From 38e4426a437ace51b7d0f01d124c2cf626615b25 Mon Sep 17 00:00:00 2001 From: ottowayi Date: Sun, 17 Oct 2021 11:43:12 -0500 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=90=9B=20fixed=20issue=20in=20parsing?= =?UTF-8?q?=20tag=20requests=20of=20nested=20UDTs=20resulting=20in=20an=20?= =?UTF-8?q?incorrect=20tag=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pycomm3/logix_driver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pycomm3/logix_driver.py b/pycomm3/logix_driver.py index e5fec86..2ff3789 100644 --- a/pycomm3/logix_driver.py +++ b/pycomm3/logix_driver.py @@ -430,7 +430,7 @@ def get_tag_list(self, program: str = None, cache: bool = True) -> List[dict]: self._cache = None - self.__log.info("Completed tag list upload.") + self.__log.info(f"Completed tag list upload. Uploaded {len(self._tags)} tags.") return tags def _get_tag_list(self, program=None): @@ -1330,7 +1330,7 @@ def _parse_tag_request(self, tag: str, rw="r") -> dict: if len(attrs) and attrs[-1].isdigit(): bit = int(attrs.pop(-1)) - tag = base if not len(attrs) else f"{base}.{''.join(attrs)}" + tag = base if not len(attrs) else f"{base}.{'.'.join(attrs)}" tag_info = self._get_tag_info(base, attrs) From 431f160806596cfa207ceafd0396b523d4b133da Mon Sep 17 00:00:00 2001 From: ottowayi Date: Tue, 2 Nov 2021 09:26:10 -0500 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=85=20added=20some=20tests=20for=20ne?= =?UTF-8?q?sted=20struct=20bit-level=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/online/__init__.py | 384 +++++++++++++++++++++------------------ 1 file changed, 211 insertions(+), 173 deletions(-) diff --git a/tests/online/__init__.py b/tests/online/__init__.py index 7704407..8c2a5b8 100644 --- a/tests/online/__init__.py +++ b/tests/online/__init__.py @@ -1,44 +1,37 @@ from tests import REAL BASE_ATOMIC_TESTS = [ - - ('_sint1', 'SINT', 0), - ('_sint2', 'SINT', 100), - ('_sint_max', 'SINT', 127), - ('_sint_min', 'SINT', -128), - - ('_int1', 'INT', 0), - ('_int2', 'INT', 100), - ('_int_max', 'INT', 32_767), - ('_int_min', 'INT', -32_768), - - ('_dint1', 'DINT', 0), - ('_dint2', 'DINT', 100), - ('_dint_max', 'DINT', 2_147_483_647), - ('_dint_min', 'DINT', -2_147_483_648), - - ('_lint1', 'LINT', 0), - ('_lint2', 'LINT', 100), - ('_lint_max', 'LINT', 9_223_372_036_854_775_807), - ('_lint_min', 'LINT', -9_223_372_036_854_775_808), - - ('_real1', 'REAL', 0.0), - ('_real2', 'REAL', 100.0), - ('_real_max1', 'REAL', REAL(3.40282306e38)), - ('_real_min1', 'REAL', REAL(-3.40282306e38)), - ('_real_max2', 'REAL', REAL(1.17549435e-38)), - ('_real_min2', 'REAL', REAL(-1.17549435e-38)), - - ('_bool1', 'BOOL', False), - ('_bool2', 'BOOL', True), - + ("_sint1", "SINT", 0), + ("_sint2", "SINT", 100), + ("_sint_max", "SINT", 127), + ("_sint_min", "SINT", -128), + ("_int1", "INT", 0), + ("_int2", "INT", 100), + ("_int_max", "INT", 32_767), + ("_int_min", "INT", -32_768), + ("_dint1", "DINT", 0), + ("_dint2", "DINT", 100), + ("_dint_max", "DINT", 2_147_483_647), + ("_dint_min", "DINT", -2_147_483_648), + ("_lint1", "LINT", 0), + ("_lint2", "LINT", 100), + ("_lint_max", "LINT", 9_223_372_036_854_775_807), + ("_lint_min", "LINT", -9_223_372_036_854_775_808), + ("_real1", "REAL", 0.0), + ("_real2", "REAL", 100.0), + ("_real_max1", "REAL", REAL(3.40282306e38)), + ("_real_min1", "REAL", REAL(-3.40282306e38)), + ("_real_max2", "REAL", REAL(1.17549435e-38)), + ("_real_min2", "REAL", REAL(-1.17549435e-38)), + ("_bool1", "BOOL", False), + ("_bool2", "BOOL", True), # include bits of integers as well - ('_dint_max.31', 'BOOL', False), - ('_dint_min.31', 'BOOL', True), - ('_dint_max.0', 'BOOL', True), - ('_dint_min.0', 'BOOL', False), - ('_dint_max.1', 'BOOL', True), - ('_dint_min.1', 'BOOL', False), + ("_dint_max.31", "BOOL", False), + ("_dint_min.31", "BOOL", True), + ("_dint_max.0", "BOOL", True), + ("_dint_min.0", "BOOL", False), + ("_dint_max.1", "BOOL", True), + ("_dint_min.1", "BOOL", False), ] _sint_array = [x for x in range(20)] @@ -46,63 +39,92 @@ _dint_array = [x * 100 for x in range(30)] _lint_array = [0, 100, 9_223_372_036_854_775_807, -9_223_372_036_854_775_808, 0, 0, 0, 0, 0, 0] _real_array = [REAL(x * 100.1234) for x in range(20)] -_bool_array = [ - True, False, False, False, False, False, True, False, False, False, - False, True, False, False, False, False, False, True, False, False, - False, False, True, False, False, True, False, False, False, False, - False, True -] + [False for _ in range(32)] + [True for _ in range(32)] +_bool_array = ( + [ + True, + False, + False, + False, + False, + False, + True, + False, + False, + False, + False, + True, + False, + False, + False, + False, + False, + True, + False, + False, + False, + False, + True, + False, + False, + True, + False, + False, + False, + False, + False, + True, + ] + + [False for _ in range(32)] + + [True for _ in range(32)] +) BASE_ATOMIC_ARRAY_TESTS = [ # make sure both with [0] and without work - ('_sint_ary1[0]{20}', 'SINT[20]', _sint_array), - ('_int_ary1[0]{25}', 'INT[25]', _int_array), - ('_dint_ary1[0]{30}', 'DINT[30]', _dint_array), - ('_lint_ary1[0]{10}', 'LINT[10]', _lint_array), - ('_real_ary1[0]{20}', 'REAL[20]', _real_array), - ('_bool_ary1[0]{96}', 'BOOL[96]', _bool_array), # bool-arrays element count is DWORDs (1 element = 32 bools) - - ('_dint_2d_ary1[0,0]{25}', 'DINT[25]', _dint_array[:25]), - ('_dint_3d_ary1[0,0,0]{27}', 'DINT[27]', _dint_array[:27]), - - ('_sint_ary1{20}', 'SINT[20]', _sint_array), - ('_int_ary1{25}', 'INT[25]', _int_array), - ('_dint_ary1{30}', 'DINT[30]', _dint_array), - ('_lint_ary1{10}', 'LINT[10]', _lint_array), - ('_real_ary1{20}', 'REAL[20]', _real_array), - ('_bool_ary1{96}', 'BOOL[96]', _bool_array), - + ("_sint_ary1[0]{20}", "SINT[20]", _sint_array), + ("_int_ary1[0]{25}", "INT[25]", _int_array), + ("_dint_ary1[0]{30}", "DINT[30]", _dint_array), + ("_lint_ary1[0]{10}", "LINT[10]", _lint_array), + ("_real_ary1[0]{20}", "REAL[20]", _real_array), + ( + "_bool_ary1[0]{96}", + "BOOL[96]", + _bool_array, + ), # bool-arrays element count is DWORDs (1 element = 32 bools) + ("_dint_2d_ary1[0,0]{25}", "DINT[25]", _dint_array[:25]), + ("_dint_3d_ary1[0,0,0]{27}", "DINT[27]", _dint_array[:27]), + ("_sint_ary1{20}", "SINT[20]", _sint_array), + ("_int_ary1{25}", "INT[25]", _int_array), + ("_dint_ary1{30}", "DINT[30]", _dint_array), + ("_lint_ary1{10}", "LINT[10]", _lint_array), + ("_real_ary1{20}", "REAL[20]", _real_array), + ("_bool_ary1{96}", "BOOL[96]", _bool_array), # TODO: add these to tests for 'bad' tags # ('_dint_2d_ary1[0]{25}', 'DINT25]', _dint_array[:25]), # ('_dint_2d_ary1{25}', 'DINT[25]', _dint_array[:25]), # ('_dint_3d_ary1[0,0]{27}', 'DINT[27]', _dint_array[:27]), # ('_dint_3d_ary1[0]{27}', 'DINT[27]', _dint_array[:27]), # ('_dint_3d_ary1{27}', 'DINT[27]', _dint_array[:27]), - # also test slicing arrays - ('_sint_ary1[5]{10}', 'SINT[10]', _sint_array[5:15]), - ('_int_ary1[1]{3}', 'INT[3]', _int_array[1:4]), - ('_dint_ary1[6]{20}', 'DINT[20]', _dint_array[6:26]), - ('_lint_ary1[3]{5}', 'LINT[5]', _lint_array[3:8]), - ('_real_ary1[18]{2}', 'REAL[2]', _real_array[18:20]), - - - ('_dint_2d_ary1[2,3]{10}', 'DINT[10]', _dint_array[13:23]), - ('_dint_3d_ary1[1,2,1]{5}', 'DINT[5]', _dint_array[16:21]), - + ("_sint_ary1[5]{10}", "SINT[10]", _sint_array[5:15]), + ("_int_ary1[1]{3}", "INT[3]", _int_array[1:4]), + ("_dint_ary1[6]{20}", "DINT[20]", _dint_array[6:26]), + ("_lint_ary1[3]{5}", "LINT[5]", _lint_array[3:8]), + ("_real_ary1[18]{2}", "REAL[2]", _real_array[18:20]), + ("_dint_2d_ary1[2,3]{10}", "DINT[10]", _dint_array[13:23]), + ("_dint_3d_ary1[1,2,1]{5}", "DINT[5]", _dint_array[16:21]), # and single elements - ('_sint_ary1[5]', 'SINT', _sint_array[5]), - ('_int_ary1[0]', 'INT', _int_array[0]), - ('_dint_ary1[6]', 'DINT', _dint_array[6]), - ('_lint_ary1[3]', 'LINT', _lint_array[3]), - ('_real_ary1[19]', 'REAL', _real_array[19]), - ('_bool_ary1[0]', 'BOOL', _bool_array[0]), - ('_bool_ary1[12]', 'BOOL', _bool_array[12]), - ('_bool_ary1[29]', 'BOOL', _bool_array[29]), + ("_sint_ary1[5]", "SINT", _sint_array[5]), + ("_int_ary1[0]", "INT", _int_array[0]), + ("_dint_ary1[6]", "DINT", _dint_array[6]), + ("_lint_ary1[3]", "LINT", _lint_array[3]), + ("_real_ary1[19]", "REAL", _real_array[19]), + ("_bool_ary1[0]", "BOOL", _bool_array[0]), + ("_bool_ary1[12]", "BOOL", _bool_array[12]), + ("_bool_ary1[29]", "BOOL", _bool_array[29]), ] -_udt1_values = {'bool': True, 'sint': -1, 'int': 1, 'dint': 10, 'lint': 100, 'real': REAL(1000.009)} -_udt1_values_empty = {'bool': False, 'sint': 0, 'int': 0, 'dint': 0, 'lint': 0, 'real': REAL(0)} +_udt1_values = {"bool": True, "sint": -1, "int": 1, "dint": 10, "lint": 100, "real": REAL(1000.009)} +_udt1_values_empty = {"bool": False, "sint": 0, "int": 0, "dint": 0, "lint": 0, "real": REAL(0)} _udt2_bool_array = [False for _ in range(64)] _udt2_bool_array[5] = True @@ -116,112 +138,128 @@ _udt2_real_array[1] = REAL(88.8888) _udt2_values = { - 'bools': _udt2_bool_array, - 'sints': _udt2_sint_array, - 'ints': _udt2_int_array, - 'dints': _udt2_dint_array, - 'lints': _udt2_lint_array, - 'reals': _udt2_real_array, + "bools": _udt2_bool_array, + "sints": _udt2_sint_array, + "ints": _udt2_int_array, + "dints": _udt2_dint_array, + "lints": _udt2_lint_array, + "reals": _udt2_real_array, } _udt2_values_empty = { - 'bools': [False for _ in range(64)], - 'sints': [0 for _ in range(8)], - 'ints': [0, 0, 0, 0], - 'dints': [0 for _ in range(10)], - 'lints': [0, 0, 0, 0], - 'reals': [REAL(0) for _ in range(10)], + "bools": [False for _ in range(64)], + "sints": [0 for _ in range(8)], + "ints": [0, 0, 0, 0], + "dints": [0 for _ in range(10)], + "lints": [0, 0, 0, 0], + "reals": [REAL(0) for _ in range(10)], } -_udt3_values = {'bool1': True, 'sint': 0, 'dint1': -1, 'bool2': False, 'dint2': -1} -_udt3_values_empty = {'bool1': False, 'sint': 0, 'dint1': 0, 'bool2': False, 'dint2': 0} +_udt3_values = {"bool1": True, "sint": 0, "dint1": -1, "bool2": False, "dint2": -1} +_udt3_values_empty = {"bool1": False, "sint": 0, "dint1": 0, "bool2": False, "dint2": 0} -_str82_part = 'A normal built-in string type' -_str82_full = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sodales vel.' -_str20_part = 'A shorter string' -_str20_full = 'Lorem ipsum vivamus.' -_str480_part = 'A longer string with up to 480 characters.' -_str480_full = ('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris rhoncus elit nec mauris convallis ' -'convallis. Nunc tristique volutpat dapibus. Suspendisse potenti. Quisque eget augue vitae ante congue malesuada. ' -'Cras sed aliquam est. Integer sagittis, mauris id bibendum ornare, metus lectus accumsan ex, non egestas sem tortor at ' -'nibh. Vestibulum consectetur ex tellus. Pellentesque nisl quam, bibendum nec lectus at, tempus varius purus. ' -'Donec tristique, ipsum a ornare eleifend.') -_str_symbols = '¡¢£¤¥¦¨§©ª«¬­®¯¯±²³´µ¶·¸¹º»¼½¾¿' +_str82_part = "A normal built-in string type" +_str82_full = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sodales vel." +_str20_part = "A shorter string" +_str20_full = "Lorem ipsum vivamus." +_str480_part = "A longer string with up to 480 characters." +_str480_full = ( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris rhoncus elit nec mauris convallis " + "convallis. Nunc tristique volutpat dapibus. Suspendisse potenti. Quisque eget augue vitae ante congue malesuada. " + "Cras sed aliquam est. Integer sagittis, mauris id bibendum ornare, metus lectus accumsan ex, non egestas sem tortor at " + "nibh. Vestibulum consectetur ex tellus. Pellentesque nisl quam, bibendum nec lectus at, tempus varius purus. " + "Donec tristique, ipsum a ornare eleifend." +) +_str_symbols = "¡¢£¤¥¦¨§©ª«¬­®¯¯±²³´µ¶·¸¹º»¼½¾¿" -_str_ary1_values = ['', _str82_full, '', '', _str82_part, '', 'A', 'B', 'C', '123'] -_str480_ary1_values = ['', _str480_full, '', _str20_full] +_str_ary1_values = ["", _str82_full, "", "", _str82_part, "", "A", "B", "C", "123"] +_str480_ary1_values = ["", _str480_full, "", _str20_full] _nested_udt1_values = { - 'udt1': _udt1_values, - 'udt_ary1': [_udt1_values_empty, _udt1_values_empty, _udt1_values, _udt1_values_empty, _udt1_values_empty], - 'udt2': _udt2_values, - 'udt_ary2': [_udt2_values_empty, _udt2_values, _udt2_values_empty, _udt2_values_empty, _udt2_values_empty], - 'str1': _str82_full, - 'str_ary1': ['', '', '', '', ''], - 'udt3': _udt3_values, - 'udt_ary3': [_udt3_values_empty, _udt3_values_empty, _udt3_values], + "udt1": _udt1_values, + "udt_ary1": [ + _udt1_values_empty, + _udt1_values_empty, + _udt1_values, + _udt1_values_empty, + _udt1_values_empty, + ], + "udt2": _udt2_values, + "udt_ary2": [ + _udt2_values_empty, + _udt2_values, + _udt2_values_empty, + _udt2_values_empty, + _udt2_values_empty, + ], + "str1": _str82_full, + "str_ary1": ["", "", "", "", ""], + "udt3": _udt3_values, + "udt_ary3": [_udt3_values_empty, _udt3_values_empty, _udt3_values], } BASE_STRUCT_TESTS = [ # struct of just atomic values - ('_udt1', 'pycomm3_AtomicUDT', _udt1_values), - ('_udt1.bool', 'BOOL', _udt1_values['bool']), - ('_udt1.sint', 'SINT', _udt1_values['sint']), - ('_udt1.int', 'INT', _udt1_values['int']), - ('_udt1.dint', 'DINT', _udt1_values['dint']), - ('_udt1.lint', 'LINT', _udt1_values['lint']), - ('_udt1.real', 'REAL', _udt1_values['real']), - + ("_udt1", "pycomm3_AtomicUDT", _udt1_values), + ("_udt1.bool", "BOOL", _udt1_values["bool"]), + ("_udt1.sint", "SINT", _udt1_values["sint"]), + ("_udt1.int", "INT", _udt1_values["int"]), + ("_udt1.dint", "DINT", _udt1_values["dint"]), + ("_udt1.lint", "LINT", _udt1_values["lint"]), + ("_udt1.real", "REAL", _udt1_values["real"]), # struct of atomic arrays - ('_udt2', 'pycomm3_AtomicArrayUDT', _udt2_values), - ('_udt2.bools{64}', 'BOOL[64]', _udt2_bool_array), - ('_udt2.bools[5]', 'BOOL', _udt2_bool_array[5]), - ('_udt2.sints{8}', 'SINT[8]', _udt2_sint_array), - ('_udt2.sints[5]', 'SINT', _udt2_sint_array[5]), # also read a single element too - ('_udt2.ints{4}', 'INT[4]', _udt2_int_array), - ('_udt2.ints[3]', 'INT', _udt2_int_array[3]), - ('_udt2.dints{10}', 'DINT[10]', _udt2_dint_array), - ('_udt2.dints[6]', 'DINT', _udt2_dint_array[6]), - ('_udt2.lints{4}', 'LINT[4]', _udt2_lint_array), - ('_udt2.lints[0]', 'LINT', _udt2_lint_array[0]), - ('_udt2.reals{10}', 'REAL[10]', _udt2_real_array), - ('_udt2.reals[2]', 'REAL', _udt2_real_array[2]), - - ('_udt3', 'pycomm3_PaddedUDT', _udt3_values), - ('_udt3.bool1', 'BOOL', _udt3_values['bool1']), - ('_udt3.sint', 'SINT', _udt3_values['sint']), - ('_udt3.dint1', 'DINT', _udt3_values['dint1']), - ('_udt3.bool2', 'BOOL', _udt3_values['bool2']), - ('_udt3.dint2', 'DINT', _udt3_values['dint2']), - - ('_nested_udt1', 'pycomm3_NestedUDT', _nested_udt1_values), - ('_nested_udt1.udt1', 'pycomm3_AtomicUDT', _nested_udt1_values['udt1']), - ('_nested_udt1.udt_ary1{5}', 'pycomm3_AtomicUDT[5]', _nested_udt1_values['udt_ary1']), - ('_nested_udt1.udt2', 'pycomm3_AtomicArrayUDT', _nested_udt1_values['udt2']), - ('_nested_udt1.udt_ary2{5}', 'pycomm3_AtomicArrayUDT[5]', _nested_udt1_values['udt_ary2']), - ('_nested_udt1.udt3', 'pycomm3_PaddedUDT', _nested_udt1_values['udt3']), - ('_nested_udt1.udt_ary3{3}', 'pycomm3_PaddedUDT[3]', _nested_udt1_values['udt_ary3']), - + ("_udt2", "pycomm3_AtomicArrayUDT", _udt2_values), + ("_udt2.bools{64}", "BOOL[64]", _udt2_bool_array), + ("_udt2.bools[5]", "BOOL", _udt2_bool_array[5]), + ("_udt2.sints{8}", "SINT[8]", _udt2_sint_array), + ("_udt2.sints[5]", "SINT", _udt2_sint_array[5]), # also read a single element too + ("_udt2.ints{4}", "INT[4]", _udt2_int_array), + ("_udt2.ints[3]", "INT", _udt2_int_array[3]), + ("_udt2.dints{10}", "DINT[10]", _udt2_dint_array), + ("_udt2.dints[6]", "DINT", _udt2_dint_array[6]), + ("_udt2.lints{4}", "LINT[4]", _udt2_lint_array), + ("_udt2.lints[0]", "LINT", _udt2_lint_array[0]), + ("_udt2.reals{10}", "REAL[10]", _udt2_real_array), + ("_udt2.reals[2]", "REAL", _udt2_real_array[2]), + ("_udt3", "pycomm3_PaddedUDT", _udt3_values), + ("_udt3.bool1", "BOOL", _udt3_values["bool1"]), + ("_udt3.sint", "SINT", _udt3_values["sint"]), + ("_udt3.dint1", "DINT", _udt3_values["dint1"]), + ("_udt3.bool2", "BOOL", _udt3_values["bool2"]), + ("_udt3.dint2", "DINT", _udt3_values["dint2"]), + # bit elements of nested udts + ("_nested_udt1.udt1.sint.0", "BOOL", True), + ("_nested_udt1.udt1.int.1", "BOOL", False), + ("_nested_udt1.udt1.dint.2", "BOOL", False), + ("_nested_udt1.udt1.lint.33", "BOOL", False), + ("_nested_udt1.udt_ary3[2].dint1.31", "BOOL", True), + # nested udts + ("_nested_udt1", "pycomm3_NestedUDT", _nested_udt1_values), + ("_nested_udt1.udt1", "pycomm3_AtomicUDT", _nested_udt1_values["udt1"]), + ("_nested_udt1.udt_ary1{5}", "pycomm3_AtomicUDT[5]", _nested_udt1_values["udt_ary1"]), + ("_nested_udt1.udt2", "pycomm3_AtomicArrayUDT", _nested_udt1_values["udt2"]), + ("_nested_udt1.udt_ary2{5}", "pycomm3_AtomicArrayUDT[5]", _nested_udt1_values["udt_ary2"]), + ("_nested_udt1.udt3", "pycomm3_PaddedUDT", _nested_udt1_values["udt3"]), + ("_nested_udt1.udt_ary3{3}", "pycomm3_PaddedUDT[3]", _nested_udt1_values["udt_ary3"]), # strings - ('_str1', 'STRING', _str82_part), - ('_str2', 'STRING', ''), - ('_str3', 'STRING', _str82_full), - ('_str20_1', 'STRING20', _str20_part), - ('_str20_2', 'STRING20', ''), - ('_str20_3', 'STRING20', _str20_full), - ('_str480_1', 'STRING480', _str480_part), - ('_str480_2', 'STRING480', ''), - ('_str480_3', 'STRING480', _str480_full), - ('_str_symbols', 'STRING', _str_symbols), - ('_str_ary1{10}', 'STRING[10]', _str_ary1_values), - ('_str_ary1[0]{10}', 'STRING[10]', _str_ary1_values), - ('_str_ary1[0]', 'STRING', _str_ary1_values[0]), - ('_str_ary1[9]', 'STRING', _str_ary1_values[9]), - ('_str_ary1[3]{3}', 'STRING[3]', _str_ary1_values[3:6]), - ('_str480_ary1{4}', 'STRING480[4]', _str480_ary1_values), - ('_str480_ary1[0]{4}', 'STRING480[4]', _str480_ary1_values), - ('_str480_ary1[3]', 'STRING480', _str480_ary1_values[3]), - ('_str480_ary1[1]{2}', 'STRING480[2]', _str480_ary1_values[1:3]), - + ("_str1", "STRING", _str82_part), + ("_str2", "STRING", ""), + ("_str3", "STRING", _str82_full), + ("_str20_1", "STRING20", _str20_part), + ("_str20_2", "STRING20", ""), + ("_str20_3", "STRING20", _str20_full), + ("_str480_1", "STRING480", _str480_part), + ("_str480_2", "STRING480", ""), + ("_str480_3", "STRING480", _str480_full), + ("_str_symbols", "STRING", _str_symbols), + ("_str_ary1{10}", "STRING[10]", _str_ary1_values), + ("_str_ary1[0]{10}", "STRING[10]", _str_ary1_values), + ("_str_ary1[0]", "STRING", _str_ary1_values[0]), + ("_str_ary1[9]", "STRING", _str_ary1_values[9]), + ("_str_ary1[3]{3}", "STRING[3]", _str_ary1_values[3:6]), + ("_str480_ary1{4}", "STRING480[4]", _str480_ary1_values), + ("_str480_ary1[0]{4}", "STRING480[4]", _str480_ary1_values), + ("_str480_ary1[3]", "STRING480", _str480_ary1_values[3]), + ("_str480_ary1[1]{2}", "STRING480[2]", _str480_ary1_values[1:3]), ] From ab8f92e6ddcd3298795e749ecb32cd1c63ca9917 Mon Sep 17 00:00:00 2001 From: ottowayi Date: Tue, 2 Nov 2021 17:23:49 -0500 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=85=20added=20tests=20for=20AOIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pycomm3/logix_driver.py | 3 + pycomm3/packets/logix.py | 34 +- tests/online/__init__.py | 32 + tests/online/test_writes.py | 37 +- tests/pycomm3.L5X | 1806 ++++++++++++++++++++++++++++++++--- 5 files changed, 1754 insertions(+), 158 deletions(-) diff --git a/pycomm3/logix_driver.py b/pycomm3/logix_driver.py index 2ff3789..c5c16e9 100644 --- a/pycomm3/logix_driver.py +++ b/pycomm3/logix_driver.py @@ -1419,6 +1419,9 @@ def _send_read_fragmented( self._sequence, request, offset ) else: + if response.error: + self.__log.error(f"Fragment failed with error: {response.error}") + offset = None if all(responses): diff --git a/pycomm3/packets/logix.py b/pycomm3/packets/logix.py index 2715dce..94c5688 100644 --- a/pycomm3/packets/logix.py +++ b/pycomm3/packets/logix.py @@ -69,9 +69,7 @@ def __init__( self.request_path = None def tag_only_message(self): - return b"".join( - (self.tag_service, self.request_path, UINT.encode(self.elements)) - ) + return b"".join((self.tag_service, self.request_path, UINT.encode(self.elements))) class ReadTagResponsePacket(TagServiceResponsePacket): @@ -107,20 +105,16 @@ class ReadTagRequestPacket(TagServiceRequestPacket): def _setup_message(self): super()._setup_message() if self.request_path is None: - self.request_path = tag_request_path( - self.tag, self.tag_info, self._use_instance_id - ) + self.request_path = tag_request_path(self.tag, self.tag_info, self._use_instance_id) if self.request_path is None: - self.error = f"Failed to build request path for tag" + self._error = "Failed to build request path for tag" self._msg.append(self.tag_only_message()) class ReadTagFragmentedResponsePacket(ReadTagResponsePacket): __log = logging.getLogger(f"{__module__}.{__qualname__}") - def __init__( - self, request: "ReadTagFragmentedRequestPacket", raw_data: bytes = None - ): + def __init__(self, request: "ReadTagFragmentedRequestPacket", raw_data: bytes = None): self.value = None self._data_type = None self.value_bytes = None @@ -201,9 +195,7 @@ def from_request( return new_request def __repr__(self): - return ( - f"{self.__class__.__name__}(tag={self.tag!r}, elements={self.elements!r})" - ) + return f"{self.__class__.__name__}(tag={self.tag!r}, elements={self.elements!r})" class WriteTagResponsePacket(TagServiceResponsePacket): @@ -251,9 +243,7 @@ def __init__( def _setup_message(self): super()._setup_message() if self.request_path is None: - self.request_path = tag_request_path( - self.tag, self.tag_info, self._use_instance_id - ) + self.request_path = tag_request_path(self.tag, self.tag_info, self._use_instance_id) if self.request_path is None: self.error = f"Failed to build request path for tag" self._msg.append(self.tag_only_message()) @@ -368,9 +358,7 @@ def __init__( self._mask_size = DataTypes.get(self.data_type).size if self._mask_size is None: - raise RequestError( - f'Invalid data type {tag_info["data_type"]} for writing bits' - ) + raise RequestError(f'Invalid data type {tag_info["data_type"]} for writing bits') if self.request_path is None: self.error = "Failed to create request path for tag" @@ -414,9 +402,7 @@ def _parse_reply(self): super()._parse_reply() num_replies = UINT.decode(self.data) offset_data = self.data[2 : 2 + 2 * num_replies] - offsets = ( - UINT.decode(offset_data[i : i + 2]) for i in range(0, len(offset_data), 2) - ) + offsets = (UINT.decode(offset_data[i : i + 2]) for i in range(0, len(offset_data), 2)) start, end = tee(offsets) # split offsets into start/end indexes next(end) # advance end by 1 so 2nd item is the end index for the first item reply_data = [self.data[i:j] for i, j in zip_longest(start, end)] @@ -429,9 +415,7 @@ def _parse_reply(self): self.responses.append(response) def __repr__(self): - return ( - f"{self.__class__.__name__}(values={_r(self.values)}, error={self.error!r})" - ) + return f"{self.__class__.__name__}(values={_r(self.values)}, error={self.error!r})" class MultiServiceRequestPacket(SendUnitDataRequestPacket): diff --git a/tests/online/__init__.py b/tests/online/__init__.py index 8c2a5b8..4160375 100644 --- a/tests/online/__init__.py +++ b/tests/online/__init__.py @@ -199,6 +199,26 @@ "udt_ary3": [_udt3_values_empty, _udt3_values_empty, _udt3_values], } +_aoi1_values = { + "EnableIn": True, + "EnableOut": True, + "b1": False, + "b2": True, + **{f"b{i}": False for i in range(3, 21)}, + "param_dint1": 1234, + "local_dint1": 0, + "local_udt1": { + "udt1": _udt1_values_empty, + "udt_ary1": [_udt1_values_empty for _ in range(5)], + "udt2": _udt2_values_empty, + "udt_ary2": [_udt2_values_empty for _ in range(5)], + "str1": "", + "str_ary1": ["", "", "", "", ""], + "udt3": _udt3_values_empty, + "udt_ary3": [_udt3_values_empty for _ in range(3)], + }, +} + BASE_STRUCT_TESTS = [ # struct of just atomic values ("_udt1", "pycomm3_AtomicUDT", _udt1_values), @@ -262,4 +282,16 @@ ("_str480_ary1[0]{4}", "STRING480[4]", _str480_ary1_values), ("_str480_ary1[3]", "STRING480", _str480_ary1_values[3]), ("_str480_ary1[1]{2}", "STRING480[2]", _str480_ary1_values[1:3]), + # aoi + ("_aoi1", "pycomm3_AOI", _aoi1_values), + ("_aoi1.b1", "BOOL", _aoi1_values["b1"]), + ("_aoi1.b2", "BOOL", _aoi1_values["b2"]), + ("_aoi1.b16", "BOOL", _aoi1_values["b16"]), + ("_aoi1.b17", "BOOL", _aoi1_values["b17"]), + ("_aoi1.b20", "BOOL", _aoi1_values["b20"]), + ("_aoi1.param_dint1", "DINT", _aoi1_values["param_dint1"]), + ("_aoi1.param_dint1.1", "BOOL", True), + ("_aoi1.param_dint1.31", "BOOL", False), + ("_aoi1.local_dint1", "DINT", _aoi1_values["local_dint1"]), + ("_aoi1.local_udt1", "pycomm3_NestedUDT", _aoi1_values["local_udt1"]), ] diff --git a/tests/online/test_writes.py b/tests/online/test_writes.py index f570cfa..be93574 100644 --- a/tests/online/test_writes.py +++ b/tests/online/test_writes.py @@ -6,16 +6,16 @@ all_write_tests = [ - *[(f'write{tag}', dt, val) for tag, dt, val in BASE_ATOMIC_TESTS], - *[(f'Program:pycomm3.write_prog{tag}', dt, val) for tag, dt, val in BASE_ATOMIC_TESTS], - *[(f'write{tag}', dt, val) for tag, dt, val in BASE_ATOMIC_ARRAY_TESTS], - *[(f'Program:pycomm3.write_prog{tag}', dt, val) for tag, dt, val in BASE_ATOMIC_ARRAY_TESTS], - *[(f'write{tag}', dt, val) for tag, dt, val in BASE_STRUCT_TESTS], - *[(f'Program:pycomm3.write_prog{tag}', dt, val) for tag, dt, val in BASE_STRUCT_TESTS], + *[(f"write{tag}", dt, val) for tag, dt, val in BASE_ATOMIC_TESTS if "aoi" not in tag], + *[(f"Program:pycomm3.write_prog{tag}", dt, val) for tag, dt, val in BASE_ATOMIC_TESTS if "aoi" not in tag], + *[(f"write{tag}", dt, val) for tag, dt, val in BASE_ATOMIC_ARRAY_TESTS if "aoi" not in tag], + *[(f"Program:pycomm3.write_prog{tag}", dt, val) for tag, dt, val in BASE_ATOMIC_ARRAY_TESTS if "aoi" not in tag], + *[(f"write{tag}", dt, val) for tag, dt, val in BASE_STRUCT_TESTS if "aoi" not in tag], + *[(f"Program:pycomm3.write_prog{tag}", dt, val) for tag, dt, val in BASE_STRUCT_TESTS if "aoi" not in tag], ] -@pytest.mark.parametrize('tag_name, data_type, value', all_write_tests) +@pytest.mark.parametrize("tag_name, data_type, value", all_write_tests) def test_writes(plc, tag_name, data_type, value): result = plc.write((tag_name, value)) assert result @@ -26,11 +26,14 @@ def test_writes(plc, tag_name, data_type, value): assert result == plc.read(tag_name) # read the same tag and make sure it matches -@pytest.mark.parametrize('tag_name, data_type, value', ( - ('write_bool_ary1[0]{32}', 'BOOL[32]', _bool_array[:32]), - ('write_bool_ary1[32]{32}', 'BOOL[32]', _bool_array[32:64]), - ('write_bool_ary1[32]{64}', 'BOOL[64]', _bool_array[32:]), -)) +@pytest.mark.parametrize( + "tag_name, data_type, value", + ( + ("write_bool_ary1[0]{32}", "BOOL[32]", _bool_array[:32]), + ("write_bool_ary1[32]{32}", "BOOL[32]", _bool_array[32:64]), + ("write_bool_ary1[32]{64}", "BOOL[64]", _bool_array[32:]), + ), +) def test_bool_array_writes(plc, tag_name, data_type, value): result = plc.write((tag_name, value)) assert result @@ -42,7 +45,7 @@ def test_bool_array_writes(plc, tag_name, data_type, value): def test_bool_array_invalid_writes(plc): - result = plc.write('write_bool_ary1[1]{2}', [True, False]) + result = plc.write("write_bool_ary1[1]{2}", [True, False]) assert not result @@ -99,9 +102,11 @@ def test_multi_write(plc): def test_duplicate_tags_in_request(plc): tags = [ - ('write_int_max.0', True), ('write_int_max.1', False), - ('write_int_max', 32_767), ('write_int_min', -32_768), - ('write_bool_ary1[1]', False) + ("write_int_max.0", True), + ("write_int_max.1", False), + ("write_int_max", 32_767), + ("write_int_min", -32_768), + ("write_bool_ary1[1]", False), ] results = plc.write(*tags, *tags) diff --git a/tests/pycomm3.L5X b/tests/pycomm3.L5X index 8276d2f..d070e75 100644 --- a/tests/pycomm3.L5X +++ b/tests/pycomm3.L5X @@ -1,5 +1,5 @@  - + @@ -67,6 +67,1096 @@ + + + + + + +00 + + + + + +01 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +00 + + + + + +D2 04 00 00 + + + + + + + +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +00 00 00 00 + + + + + + + + + + + + + 80 @@ -447,11 +1537,11 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF @@ -1260,10 +2350,10 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 - - + + - + @@ -1287,10 +2377,10 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 - - + + - + @@ -1298,11 +2388,11 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 -44 E9 0D C0 30 75 00 00 87 5E 00 00 +C2 E0 11 C0 30 75 00 00 A0 0F 00 00 - + @@ -1590,6 +2680,132 @@ F0 00 + +09 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 20 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 @@ -1717,6 +2933,18 @@ F0 00 + +01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF + + + + + + + + + + FD FF 7F 7F @@ -1900,6 +3128,132 @@ F0 00 + +0B 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 00 @@ -1947,14 +3301,14 @@ D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00 -01 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF - - + + - + @@ -2299,14 +3653,14 @@ D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00 -00 00 00 A0 14 00 00 00 13 00 00 00 +00 00 00 00 14 00 00 00 00 00 00 00 - - + + - + @@ -2436,11 +3790,11 @@ D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF @@ -3249,10 +4603,10 @@ D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00 - - + + - + @@ -3276,10 +4630,10 @@ D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00 - - + + - + @@ -3395,18 +4749,6 @@ F0 0A 00 00 54 0B 00 00 - -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - - - - - - - - - 64 @@ -4026,6 +5368,132 @@ F0 00 + +0B 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 00 @@ -4483,11 +5951,11 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF @@ -5296,10 +6764,10 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 - - + + - + @@ -5323,10 +6791,10 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 - - + + - + @@ -5953,14 +7421,140 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF - + - + - + + + + + +09 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6421,11 +8015,11 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 01 64 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF +00 00 00 00 FF FF FF FF @@ -7234,10 +8828,10 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 - - + + - + @@ -7261,10 +8855,10 @@ FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80 - - + + - + @@ -7891,14 +9485,14 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF - + - + - + @@ -7926,14 +9520,14 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 A0 19 00 00 00 18 00 00 00 +00 00 00 00 19 00 00 00 00 00 00 00 - - + + - + @@ -8017,14 +9611,6 @@ BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00 - - - @@ -8060,11 +9646,6 @@ Atomic Data Types - - - @@ -8115,12 +9696,6 @@ Arrays of Atomic Data Types - - - @@ -8155,16 +9730,16 @@ String, UDT, Predefined, etc + + + + + - - - @@ -8194,6 +9769,11 @@ write tags are used in the logic so they're included in the exports + + + + + @@ -8218,14 +9798,6 @@ write tags are used in the logic so they're included in the exports - - - @@ -8261,11 +9833,6 @@ Atomic Data Types - - - @@ -8310,16 +9877,16 @@ Arrays of Atomic Data Types + + + + + - - - @@ -8344,6 +9911,11 @@ write tags are used in the logic so they're included in the exports + + + + +