* [PATCH 1/1] BaseTools: Add FMMT Tool @ 2021-12-01 1:29 Yuwei Chen 2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming 0 siblings, 1 reply; 4+ messages in thread From: Yuwei Chen @ 2021-12-01 1:29 UTC (permalink / raw) To: devel; +Cc: Bob Feng, Liming Gao The FMMT python tool is used for firmware files operation, which has the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function: 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files) 2.Add a new FFS into a FV file (both included in a FD file or not) 3.Replace an FFS in a FV file with a new FFS file 4.Delete an FFS in a FV file (both included in a FD file or not) 5.Extract the FFS from a FV file (both included in a FD file or not) Currently the FMMT C tool is saved in edk2-staging repo, but its quality and coding style can't meet the Edk2 quality, which is hard to maintain (Hard/Duplicate Code; Regression bugs; Restrict usage). The new Python version keeps same functions with origin C version. It has higher quality and better coding style, and it is much easier to extend new functions and to maintain. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847 PR Link: https://github.com/tianocore/edk2-basetools/pull/12 RFC Link: https://edk2.groups.io/g/devel/message/82877 Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT Cc: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> --- V4 fixed the Linux file format issue and known bugs. BaseTools/BinWrappers/PosixLike/FMMT | 14 + BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 + BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++ BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 + .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++ .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++ BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++ .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++ BaseTools/Source/Python/FMMT/PI/__init__.py | 6 + BaseTools/Source/Python/FMMT/README.md | 180 ++++++ BaseTools/Source/Python/FMMT/__init__.py | 0 .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++ BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++ .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++ .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++ .../Source/Python/FMMT/core/FMMTParser.py | 86 +++ .../Source/Python/FMMT/core/FvHandler.py | 521 ++++++++++++++++++ .../Source/Python/FMMT/core/GuidTools.py | 152 +++++ .../Source/Python/FMMT/utils/FmmtLogger.py | 18 + .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++ 22 files changed, 2432 insertions(+) create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini create mode 100644 BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png create mode 100644 BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py create mode 100644 BaseTools/Source/Python/FMMT/README.md create mode 100644 BaseTools/Source/Python/FMMT/__init__.py create mode 100644 BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTreeNode.py create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTOperation.py create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py create mode 100644 BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py diff --git a/BaseTools/BinWrappers/PosixLike/FMMT b/BaseTools/BinWrappers/PosixLike/FMMT new file mode 100644 index 000000000000..5f5519e1e1b6 --- /dev/null +++ b/BaseTools/BinWrappers/PosixLike/FMMT @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +#python `dirname $0`/RunToolFromSource.py `basename $0` $* + +# If a ${PYTHON_COMMAND} command is available, use it in preference to python +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then + python_exe=${PYTHON_COMMAND} +fi + +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here +dir=$(dirname "$full_cmd") +cmd=${full_cmd##*/} + +export PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}" +exec "${python_exe:-python}" -m $cmd.$cmd "$@" diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat b/BaseTools/BinWrappers/WindowsLike/FMMT.bat new file mode 100644 index 000000000000..f0551c4ac54a --- /dev/null +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat @@ -0,0 +1,4 @@ +@setlocal +@set ToolName=%~n0% +@set PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BASE_TOOLS_PATH%\Source\Python\FMMT +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %* diff --git a/BaseTools/Source/Python/FMMT/FMMT.py b/BaseTools/Source/Python/FMMT/FMMT.py new file mode 100644 index 000000000000..5028d8446ee0 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/FMMT.py @@ -0,0 +1,117 @@ +# @file +# Firmware Module Management Tool. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# Import Modules +# +import argparse +import sys +from core.FMMTOperation import * + +parser = argparse.ArgumentParser(description=''' +View the Binary Structure of FD/FV/Ffs/Section, and Delete/Extract/Add/Replace a Ffs from/into a FV. +''') +parser.add_argument("--version", action="version", version='%(prog)s Version 1.0', + help="Print debug information.") +parser.add_argument("-v", "--View", dest="View", nargs='+', + help="View each FV and the named files within each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'") +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+', + help="Delete a Ffs from FV: '-d inputfile TargetFfsName outputfile TargetFvName(Optional,\ + If not given, wil delete all the existed target Ffs)'") +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+', + help="Extract a Ffs Info: '-e inputfile TargetFfsName outputfile'") +parser.add_argument("-a", "--Add", dest="Add", nargs='+', + help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'") +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+', + help="Replace a Ffs in a FV: '-r inputfile TargetFfsName newffsfile outputfile TargetFvName(Optional,\ + If not given, wil replace all the existed target Ffs with new Ffs file)'") +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+', + help="The format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future") + +def print_banner(): + print("") + +class FMMT(): + def __init__(self) -> None: + self.firmware_packet = {} + + def CheckFfsName(self, FfsName:str) -> str: + try: + return uuid.UUID(FfsName) + except: + return FfsName + + def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None) -> None: + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile) + filetype = os.path.splitext(inputfile)[1].lower() + if filetype == '.fd': + ROOT_TYPE = ROOT_TREE + elif filetype == '.fv': + ROOT_TYPE = ROOT_FV_TREE + elif filetype == '.ffs': + ROOT_TYPE = ROOT_FFS_TREE + elif filetype == '.sec': + ROOT_TYPE = ROOT_SECTION_TREE + else: + ROOT_TYPE = ROOT_TREE + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile) + + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None: + if Fv_name: + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile, uuid.UUID(Fv_name)) + else: + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile) + + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None: + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile) + + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None: + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, outputfile) + + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None: + if Fv_name: + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile, uuid.UUID(Fv_name)) + else: + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile) + + +def main(): + args=parser.parse_args() + status=0 + + try: + fmmt=FMMT() + if args.View: + if args.LogFileType: + fmmt.View(args.View[0], args.LogFileType[0]) + else: + fmmt.View(args.View[0]) + if args.Delete: + if len(args.Delete) == 4: + fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3]) + else: + fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2]) + if args.Extract: + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2]) + if args.Add: + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3]) + if args.Replace: + if len(args.Replace) == 5: + fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3],args.Replace[4]) + else: + fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3]) + # TODO: + '''Do the main work''' + except Exception as e: + print(e) + + return status + + +if __name__ == "__main__": + exit(main()) diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini b/BaseTools/Source/Python/FMMT/FMMTConfig.ini new file mode 100644 index 000000000000..aa2444f11b38 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini @@ -0,0 +1,11 @@ +## @file +# This file is used to define the FMMT dependent external tool guid. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32 +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc806a0133413a4aa037f1d43d80000546a5246 GIT binary patch literal 29515 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 literal 0 HcmV?d00001 diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png new file mode 100644 index 0000000000000000000000000000000000000000..6335653ece1605cd0c53bd2cc2bc21d57d213dae GIT binary patch literal 79906 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 RBat2OV|2<CTVmi8`9DHIo&o>> literal 0 HcmV?d00001 diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py b/BaseTools/Source/Python/FMMT/PI/Common.py new file mode 100644 index 000000000000..efab874ee08b --- /dev/null +++ b/BaseTools/Source/Python/FMMT/PI/Common.py @@ -0,0 +1,81 @@ +## @file +# This file is used to define the common C struct and functions. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from ctypes import * +import uuid + +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}') +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}') +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}') +# EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}') + +EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3") +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes +EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a' +EFI_SYSTEM_NVDATA_FV_GUID = uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50") +EFI_SYSTEM_NVDATA_FV_GUID_BYTE = b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP" +EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09") +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t' +ZEROVECTOR_BYTE = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff") +FVH_SIGNATURE = b'_FVH' + +class GUID(Structure): + _pack_ = 1 + _fields_ = [ + ('Guid1', c_uint32), + ('Guid2', c_uint16), + ('Guid3', c_uint16), + ('Guid4', ARRAY(c_uint8, 8)), + ] + + def from_list(self, listformat: list) -> None: + self.Guid1 = listformat[0] + self.Guid2 = listformat[1] + self.Guid3 = listformat[2] + for i in range(8): + self.Guid4[i] = listformat[i+3] + + def __cmp__(self, otherguid) -> bool: + if not isinstance(otherguid, GUID): + return 'Input is not the GUID instance!' + rt = False + if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2 and self.Guid3 == otherguid.Guid3: + rt = True + for i in range(8): + rt = rt & (self.Guid4[i] == otherguid.Guid4[i]) + return rt + +def ModifyGuidFormat(target_guid: str) -> GUID: + target_guid = target_guid.replace('-', '') + target_list = [] + start = [0,8,12,16,18,20,22,24,26,28,30] + end = [8,12,16,18,20,22,24,26,28,30,32] + num = len(start) + for pos in range(num): + new_value = int(target_guid[start[pos]:end[pos]], 16) + target_list.append(new_value) + new_format = GUID() + new_format.from_list(target_list) + return new_format + + +# Get data from ctypes to bytes. +def struct2stream(s) -> bytes: + length = sizeof(s) + p = cast(pointer(s), POINTER(c_char * length)) + return p.contents.raw + + + +def GetPadSize(Size: int, alignment: int) -> int: + if Size % alignment == 0: + return 0 + Pad_Size = alignment - Size % alignment + return Pad_Size diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py new file mode 100644 index 000000000000..33c49ffb50bc --- /dev/null +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py @@ -0,0 +1,66 @@ +## @file +# This file is used to define the Ffs Header C Struct. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from struct import * +from ctypes import * +from PI.Common import * + +EFI_FFS_FILE_HEADER_LEN = 24 +EFI_FFS_FILE_HEADER2_LEN = 32 + +class CHECK_SUM(Structure): + _pack_ = 1 + _fields_ = [ + ('Header', c_uint8), + ('File', c_uint8), + ] + +class EFI_FFS_INTEGRITY_CHECK(Union): + _pack_ = 1 + _fields_ = [ + ('Checksum', CHECK_SUM), + ('Checksum16', c_uint16), + ] + + +class EFI_FFS_FILE_HEADER(Structure): + _pack_ = 1 + _fields_ = [ + ('Name', GUID), + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), + ('Type', c_uint8), + ('Attributes', c_uint8), + ('Size', ARRAY(c_uint8, 3)), + ('State', c_uint8), + ] + + @property + def FFS_FILE_SIZE(self) -> int: + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 + + @property + def HeaderLength(self) -> int: + return 24 + +class EFI_FFS_FILE_HEADER2(Structure): + _pack_ = 1 + _fields_ = [ + ('Name', GUID), + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), + ('Type', c_uint8), + ('Attributes', c_uint8), + ('Size', ARRAY(c_uint8, 3)), + ('State', c_uint8), + ('ExtendedSize', c_uint64), + ] + + @property + def FFS_FILE_SIZE(self) -> int: + return self.ExtendedSize + + @property + def HeaderLength(self) -> int: + return 32 diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py b/BaseTools/Source/Python/FMMT/PI/FvHeader.py new file mode 100644 index 000000000000..aae2feae844a --- /dev/null +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py @@ -0,0 +1,112 @@ +## @file +# This file is used to define the FV Header C Struct. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from ast import Str +from struct import * +from ctypes import * +from PI.Common import * + +class EFI_FV_BLOCK_MAP_ENTRY(Structure): + _pack_ = 1 + _fields_ = [ + ('NumBlocks', c_uint32), + ('Length', c_uint32), + ] + + +class EFI_FIRMWARE_VOLUME_HEADER(Structure): + _fields_ = [ + ('ZeroVector', ARRAY(c_uint8, 16)), + ('FileSystemGuid', GUID), + ('FvLength', c_uint64), + ('Signature', c_uint32), + ('Attributes', c_uint32), + ('HeaderLength', c_uint16), + ('Checksum', c_uint16), + ('ExtHeaderOffset', c_uint16), + ('Reserved', c_uint8), + ('Revision', c_uint8), + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, 1)), + ] + +def Refine_FV_Header(nums): + class EFI_FIRMWARE_VOLUME_HEADER(Structure): + _fields_ = [ + ('ZeroVector', ARRAY(c_uint8, 16)), + ('FileSystemGuid', GUID), + ('FvLength', c_uint64), + ('Signature', c_uint32), + ('Attributes', c_uint32), + ('HeaderLength', c_uint16), + ('Checksum', c_uint16), + ('ExtHeaderOffset', c_uint16), + ('Reserved', c_uint8), + ('Revision', c_uint8), + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)), + ] + return EFI_FIRMWARE_VOLUME_HEADER + +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): + _fields_ = [ + ('FvName', GUID), + ('ExtHeaderSize', c_uint32) + ] + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure): + _fields_ = [ + ('ExtEntrySize', c_uint16), + ('ExtEntryType', c_uint16) + ] + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('TypeMask', c_uint32) + ] + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('TypeMask', c_uint32), + ('Types', ARRAY(GUID, 1)) + ] + +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE: + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('TypeMask', c_uint32), + ('Types', ARRAY(GUID, nums)) + ] + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure) + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('FormatType', GUID) + ] + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('FormatType', GUID), + ('Data', ARRAY(c_uint8, 1)) + ] + +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE: + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('FormatType', GUID), + ('Data', ARRAY(c_uint8, nums)) + ] + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure) + +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure): + _fields_ = [ + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY), + ('UsedSize', c_uint32) + ] diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py new file mode 100644 index 000000000000..c2cc8e0172fb --- /dev/null +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py @@ -0,0 +1,110 @@ +## @file +# This file is used to define the Section Header C Struct. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from struct import * +from ctypes import * +from PI.Common import * + +EFI_COMMON_SECTION_HEADER_LEN = 4 +EFI_COMMON_SECTION_HEADER2_LEN = 8 + +class EFI_COMMON_SECTION_HEADER(Structure): + _pack_ = 1 + _fields_ = [ + ('Size', ARRAY(c_uint8, 3)), + ('Type', c_uint8), + ] + + @property + def SECTION_SIZE(self) -> int: + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 + + def Common_Header_Size(self) -> int: + return 4 + +class EFI_COMMON_SECTION_HEADER2(Structure): + _pack_ = 1 + _fields_ = [ + ('Size', ARRAY(c_uint8, 3)), + ('Type', c_uint8), + ('ExtendedSize', c_uint32), + ] + + @property + def SECTION_SIZE(self) -> int: + return self.ExtendedSize + + def Common_Header_Size(self) -> int: + return 8 + +class EFI_COMPRESSION_SECTION(Structure): + _pack_ = 1 + _fields_ = [ + ('UncompressedLength', c_uint32), + ('CompressionType', c_uint8), + ] + + def ExtHeaderSize(self) -> int: + return 5 + +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure): + _pack_ = 1 + _fields_ = [ + ('SubTypeGuid', GUID), + ] + + def ExtHeaderSize(self) -> int: + return 16 + +class EFI_GUID_DEFINED_SECTION(Structure): + _pack_ = 1 + _fields_ = [ + ('SectionDefinitionGuid', GUID), + ('DataOffset', c_uint16), + ('Attributes', c_uint16), + ] + + def ExtHeaderSize(self) -> int: + return 20 + +def Get_USER_INTERFACE_Header(nums: int): + class EFI_SECTION_USER_INTERFACE(Structure): + _pack_ = 1 + _fields_ = [ + ('FileNameString', ARRAY(c_uint16, nums)), + ] + + def ExtHeaderSize(self) -> int: + return 2 * nums + + def GetUiString(self) -> str: + UiString = '' + for i in range(nums): + if self.FileNameString[i]: + UiString += chr(self.FileNameString[i]) + return UiString + + return EFI_SECTION_USER_INTERFACE + +def Get_VERSION_Header(nums: int): + class EFI_SECTION_VERSION(Structure): + _pack_ = 1 + _fields_ = [ + ('BuildNumber', c_uint16), + ('VersionString', ARRAY(c_uint16, nums)), + ] + + def ExtHeaderSize(self) -> int: + return 2 * (nums+1) + + def GetVersionString(self) -> str: + VersionString = '' + for i in range(nums): + if self.VersionString[i]: + VersionString += chr(self.VersionString[i]) + return VersionString + + return EFI_SECTION_VERSION diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py b/BaseTools/Source/Python/FMMT/PI/__init__.py new file mode 100644 index 000000000000..4e8296fad1ba --- /dev/null +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py @@ -0,0 +1,6 @@ +## @file +# This file is used to define the FMMT dependent external tool management class. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/README.md b/BaseTools/Source/Python/FMMT/README.md new file mode 100644 index 000000000000..e14dfa34ea66 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/README.md @@ -0,0 +1,180 @@ +# FMMT +## Overview +This FMMT tool is the python implementation of the edk2 FMMT tool which locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt. +This implementation has the same usage as the edk2 FMMT, but it's more readable and relaiable. + +# FMMT User Guide + +#### Last updated October 13, 2021 + +Important Changes and Updates: + +- Oct 13, 2021 Initial Draft of FMMT Python Tool + +#### Note: + +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is much easier to maintain and extend other functions. + + + +# 1. Introduction + +## 1.1 Overview + +The Firmware Device is a persistent physical repository that contains firmware code and/or data. The firmware code and/or data stored in Firmware Volumes. Detail layout of Firmware Volumes is described in ?Figure 1. The Firmware Volume Format?. + +![](Img/FirmwareVolumeFormat.png) + +<center>Figure 1. The Firmware Volume Format</center> + +In firmware development, binary file has its firmware layout following the Platform-Initialization Specification. Thus, operation on FV file / FFS file (Firmware File) is an efficient and convenient way for firmware function testing and developing. FMMT Python tool is used for firmware files operation. + +## 1.2 Tool Capabilities + +The FMMT tool is capable of: + +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware Files) + +- Add a new FFS into a FV file (both included in a FD file or not) + +- Replace an FFS in a FV file with a new FFS file + +- Delete an FFS in a FV file (both included in a FD file or not) + +- Extract the FFS from a FV file (both includ-v < Inputfile > < Outputfile >ed in a FD file or not) + +## 1.3 References + +| Document | +| ------------------------------------------------ | +| UEFI Platform Initialization (PI) Specification | + + + +# 2. FMMT Python Tool Usage + +## 2.1 Required Files + +### 2.1.1 Independent use + +When independent use the FMMT Python Tool, the following files and settings are required: + +- GuidTool executable files used for Decompress/Compress Firmware data. + +- Environment variables path with GuidTool path setting. + +### 2.1.2 Use with Build System + +When use the FMMT Python Tool with Build System: + +- If only use Edk2 based GuidTool, do not need other preparation. + +- If use other customized GuidTool, need prepare the config file with GuidTool info. The syntax for GuidTool definition shown as follow: + + ***ToolsGuid ShortName Command*** + + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress*** + +## 2.2 Syntax + +### 2.2.1 Syntax for Parse file + +***-v < Inputfile > < Outputfile > -l < LogFileType >*** + +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is optional, if inputs, the *Inputfile* will be encapsulated into *Outputfile* following the parsed firmware layout. *"-l LogFileType"* is optional, it decides the format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future. + +### 2.2.2 Syntax for Add a new FFS + +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >*** + +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* (Name or Guid) is the TargetFv which *NewFfsFile* will be added into. + +### 2.2.3 Syntax for Delete an FFS + +***-d < Inputfile > < TargetFfsName > < Outputfile > < TargetFvName/TargetFvGuid >*** + +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.* + +### 2.2.4 Syntax for Replace an FFS + +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < TargetFvName/TargetFvGuid >*** + +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.* + +### 2.2.5 Syntax for Extract an FFS + +***-e < Inputfile > < TargetFfsName > < Outputfile >*** + +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs which will be extracted. + + + +# 3. FMMT Python Tool Design + +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each Node have its Data field, which saves the FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the parse/add/delete/replace/extract operations are based on the NodeTree (adjusting the layout and data). + +## 3.1 NodeTree + +A whole NodeTree saves all the Firmware info. + +- Parent & Child relationship figured out the Firmware layout. + +- Each Node have several fields. ?Data? field saves an FirmwareClass instance which contains all the data info of the info. + +### 3.1.1 NodeTree Format + +The NodeTree will be created with parse function. When parse a file, a Root Node will be initialized firstly. The Data split and Tree construction process is described with an FD file shown as ?Figure 2. The NodeTree format?: + +- A Root Node is initialized. + +- Use the ?FV Signature? as FV key to split Whole FD Data. ?FV0?, ?FV1?, ?FV2?? Node created. + +- After FV level Node created, use the ?Ffs Data Size? as FFS key to split each FV Data. ?Ffs0?...Node created. + +- After FFS level Node created, use the ?Section Data Size? as Section key to split each Ffs Data. ?Section0?...Node created. + +- If some of Section includes other Sections, continue use the ?Section Data Size? as Section key to split each Section Data. + +- After all Node created, the whole NodeTree saves all the info. (Can be used in other functions or print the whole firmware layout into log file) + +![](Img/NodeTreeFormat.png) + +<center>Figure 2. The NodeTree format</center> + +### 3.1.2 Node Factory and Product + +As 3.1.1, Each Node is created by data split and recognition. To extend the NodeTree usage, Factory pattern is used in Node created process. + +Each Node have its Factory to create Product and use Product ParserData function to deal with the data. + +## 3.2 GuidTool + +There are two ways to set the GuidTool. One from Config file, another from environment variables. + +Current GuidTool first check if has Config file. + +- If have, load the config GuidTool Information. + +- Else get from environment variables. + +### 3.2.1 Get from Config file + +- Config file should in same folder with FMMT.py or the path in environment variables. + +- Content should follow the format: + + ***ToolsGuid ShortName Command*** + +### 3.2.2 Get from Environment Variables + +- The GuidTool Command used must be set in environment variables. + +### 3.2.3 Edk2 Based GuidTool + +| ***Guid*** | ***ShortName*** | ***Command*** | +| ------------------------------------------ | --------------- | --------------------- | +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | ***TianoCompress*** | +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | ***LzmaCompress*** | +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | ***GenCrc32*** | +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | ***LzmaF86Compress*** | +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | ***BrotliCompress*** | diff --git a/BaseTools/Source/Python/FMMT/__init__.py b/BaseTools/Source/Python/FMMT/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py new file mode 100644 index 000000000000..33ffe73cab27 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py @@ -0,0 +1,371 @@ +## @file +# This file is used to implement of the various bianry parser. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from re import T +import copy +import os +from PI.Common import * +from core.BiosTreeNode import * +from core.BiosTree import * +from core.GuidTools import * + +ROOT_TREE = 'ROOT' +ROOT_FV_TREE = 'ROOT_FV_TREE' +ROOT_FFS_TREE = 'ROOT_FFS_TREE' +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' + +FV_TREE = 'FV' +DATA_FV_TREE = 'DATA_FV' +FFS_TREE = 'FFS' +FFS_PAD = 'FFS_PAD' +FFS_FREE_SPACE = 'FFS_FREE_SPACE' +SECTION_TREE = 'SECTION' +SEC_FV_TREE = 'SEC_FV_IMAGE' +BINARY_DATA = 'BINARY' +Fv_count = 0 + +## Abstract factory +class BinaryFactory(): + type:list = [] + + def Create_Product(): + pass + +class BinaryProduct(): + ## Use GuidTool to decompress data. + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes: + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..") + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') + guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) + DecompressedData = guidtool.unpack(Section_Data) + return DecompressedData + + def ParserData(): + pass + +class SectionFactory(BinaryFactory): + type = [SECTION_TREE] + + def Create_Product(): + return SectionProduct() + +class FfsFactory(BinaryFactory): + type = [ROOT_SECTION_TREE, FFS_TREE] + + def Create_Product(): + return FfsProduct() + +class FvFactory(BinaryFactory): + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE] + + def Create_Product(): + return FvProduct() + +class FdFactory(BinaryFactory): + type = [ROOT_FV_TREE, ROOT_TREE] + + def Create_Product(): + return FdProduct() + +class SectionProduct(BinaryProduct): + ## Decompress the compressed section. + def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None: + if Section_Tree.Data.Type == 0x01: + Section_Tree.Data.OriData = Section_Tree.Data.Data + self.ParserFfs(Section_Tree, b'') + # Guided Define Section + elif Section_Tree.Data.Type == 0x02: + Section_Tree.Data.OriData = Section_Tree.Data.Data + DeCompressGuidTool = Section_Tree.Data.ExtHeader.SectionDefinitionGuid + Section_Tree.Data.Data = self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data) + Section_Tree.Data.Size = len(Section_Tree.Data.Data) + Section_Tree.Data.HeaderLength + self.ParserFfs(Section_Tree, b'') + elif Section_Tree.Data.Type == 0x03: + Section_Tree.Data.OriData = Section_Tree.Data.Data + self.ParserFfs(Section_Tree, b'') + # SEC_FV Section + elif Section_Tree.Data.Type == 0x17: + global Fv_count + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data) + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count)) + Sec_Fv_Tree.type = SEC_FV_TREE + Sec_Fv_Tree.Data = Sec_Fv_Info + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + Sec_Fv_Tree.Data.Header.HeaderLength + Sec_Fv_Tree.Data.Data = Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:] + Section_Tree.insertChild(Sec_Fv_Tree) + Fv_count += 1 + + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None: + Rel_Offset = 0 + Section_Offset = 0 + # Get the Data from parent tree, if do not have the tree then get it from the whole_data. + if ParTree.Data != None: + Data_Size = len(ParTree.Data.Data) + Section_Offset = ParTree.Data.DOffset + Whole_Data = ParTree.Data.Data + else: + Data_Size = len(Whole_Data) + # Parser all the data to collect all the Section recorded in its Parent Section. + while Rel_Offset < Data_Size: + # Create a SectionNode and set it as the SectionTree's Data + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) + Section_Tree = BIOSTREE(Section_Info.Name) + Section_Tree.type = SECTION_TREE + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size] + Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset + Section_Info.ROffset = Rel_Offset + if Section_Info.Header.Type == 0: + break + # The final Section in parent Section does not need to add padding, else must be 4-bytes align with parent Section start offset + Pad_Size = 0 + if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size): + Pad_Size = GetPadSize(Section_Info.Size, 4) + Section_Info.PadData = Pad_Size * b'\x00' + if Section_Info.Header.Type == 0x02: + Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size] + if Section_Info.Header.Type == 0x14: + ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString() + if Section_Info.Header.Type == 0x15: + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString() + Section_Offset += Section_Info.Size + Pad_Size + Rel_Offset += Section_Info.Size + Pad_Size + Section_Tree.Data = Section_Info + ParTree.insertChild(Section_Tree) + +class FfsProduct(BinaryProduct): + # ParserFFs / GetSection + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None: + Rel_Offset = 0 + Section_Offset = 0 + # Get the Data from parent tree, if do not have the tree then get it from the whole_data. + if ParTree.Data != None: + Data_Size = len(ParTree.Data.Data) + Section_Offset = ParTree.Data.DOffset + Whole_Data = ParTree.Data.Data + else: + Data_Size = len(Whole_Data) + # Parser all the data to collect all the Section recorded in Ffs. + while Rel_Offset < Data_Size: + # Create a SectionNode and set it as the SectionTree's Data + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) + Section_Tree = BIOSTREE(Section_Info.Name) + Section_Tree.type = SECTION_TREE + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size] + Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset + Section_Info.ROffset = Rel_Offset + if Section_Info.Header.Type == 0: + break + # The final Section in Ffs does not need to add padding, else must be 4-bytes align with Ffs start offset + Pad_Size = 0 + if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size): + Pad_Size = GetPadSize(Section_Info.Size, 4) + Section_Info.PadData = Pad_Size * b'\x00' + if Section_Info.Header.Type == 0x02: + Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size] + # If Section is Version or UI type, it saves the version and UI info of its parent Ffs. + if Section_Info.Header.Type == 0x14: + ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString() + if Section_Info.Header.Type == 0x15: + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString() + Section_Offset += Section_Info.Size + Pad_Size + Rel_Offset += Section_Info.Size + Pad_Size + Section_Tree.Data = Section_Info + ParTree.insertChild(Section_Tree) + +class FvProduct(BinaryProduct): + ## ParserFv / GetFfs + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None: + Ffs_Offset = 0 + Rel_Offset = 0 + # Get the Data from parent tree, if do not have the tree then get it from the whole_data. + if ParTree.Data != None: + Data_Size = len(ParTree.Data.Data) + Ffs_Offset = ParTree.Data.DOffset + Whole_Data = ParTree.Data.Data + else: + Data_Size = len(Whole_Data) + # Parser all the data to collect all the Ffs recorded in Fv. + while Rel_Offset < Data_Size: + # Create a FfsNode and set it as the FFsTree's Data + if Data_Size - Rel_Offset < 24: + Ffs_Tree = BIOSTREE('Free_Space') + Ffs_Tree.type = FFS_FREE_SPACE + Ffs_Tree.Data = FreeSpaceNode(Whole_Data[Rel_Offset:]) + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset + ParTree.Data.Free_Space = Data_Size - Rel_Offset + ParTree.insertChild(Ffs_Tree) + Rel_Offset = Data_Size + else: + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:]) + Ffs_Tree = BIOSTREE(Ffs_Info.Name) + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset + Ffs_Info.DOffset = Ffs_Offset + Ffs_Info.Header.HeaderLength + Rel_Whole_Offset + Ffs_Info.ROffset = Rel_Offset + if Ffs_Info.Name == PADVECTOR: + Ffs_Tree.type = FFS_PAD + Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size] + Ffs_Info.Size = len(Ffs_Info.Data) + Ffs_Info.Header.HeaderLength + # if current Ffs is the final ffs of Fv and full of b'\xff', define it with Free_Space + if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') == b'': + Ffs_Tree.type = FFS_FREE_SPACE + Ffs_Info.Data = Whole_Data[Rel_Offset:] + Ffs_Info.Size = len(Ffs_Info.Data) + ParTree.Data.Free_Space = Ffs_Info.Size + else: + Ffs_Tree.type = FFS_TREE + Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size] + # The final Ffs in Fv does not need to add padding, else must be 8-bytes align with Fv start offset + Pad_Size = 0 + if Ffs_Tree.type != FFS_FREE_SPACE and (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != Data_Size): + Pad_Size = GetPadSize(Ffs_Info.Size, 8) + Ffs_Info.PadData = Pad_Size * b'\xff' + Ffs_Offset += Ffs_Info.Size + Pad_Size + Rel_Offset += Ffs_Info.Size + Pad_Size + Ffs_Tree.Data = Ffs_Info + ParTree.insertChild(Ffs_Tree) + +class FdProduct(BinaryProduct): + type = [ROOT_FV_TREE, ROOT_TREE] + + ## Create DataTree with first level /fv Info, then parser each Fv. + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0) -> None: + # Get all Fv image in Fd with offset and length + Fd_Struct = self.GetFvFromFd(whole_data) + data_size = len(whole_data) + Binary_count = 0 + global Fv_count + # If the first Fv image is the Binary Fv, add it into the tree. + if Fd_Struct[0][1] != 0: + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) + Binary_node.type = BINARY_DATA + Binary_node.Data = BinaryNode(str(Binary_count)) + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]] + Binary_node.Data.Size = len(Binary_node.Data.Data) + Binary_node.Data.HOffset = 0 + offset + WholeFvTree.insertChild(Binary_node) + Binary_count += 1 + # Add the first collected Fv image into the tree. + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count)) + Cur_node.type = Fd_Struct[0][0] + Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]]) + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset + Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength + Cur_node.Data.Data = whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[0][1]+Cur_node.Data.Size] + WholeFvTree.insertChild(Cur_node) + Fv_count += 1 + Fv_num = len(Fd_Struct) + # Add all the collected Fv image and the Binary Fv image between them into the tree. + for i in range(Fv_num-1): + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]: + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) + Binary_node.type = BINARY_DATA + Binary_node.Data = BinaryNode(str(Binary_count)) + Binary_node.Data.Data = whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]] + Binary_node.Data.Size = len(Binary_node.Data.Data) + Binary_node.Data.HOffset = Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset + WholeFvTree.insertChild(Binary_node) + Binary_count += 1 + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count)) + Cur_node.type = Fd_Struct[i+1][0] + Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]]) + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset + Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength + Cur_node.Data.Data = whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[i+1][1]+Cur_node.Data.Size] + WholeFvTree.insertChild(Cur_node) + Fv_count += 1 + # If the final Fv image is the Binary Fv, add it into the tree + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size: + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) + Binary_node.type = BINARY_DATA + Binary_node.Data = BinaryNode(str(Binary_count)) + Binary_node.Data.Data = whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:] + Binary_node.Data.Size = len(Binary_node.Data.Data) + Binary_node.Data.HOffset = Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset + WholeFvTree.insertChild(Binary_node) + Binary_count += 1 + + ## Get the first level Fv from Fd file. + def GetFvFromFd(self, whole_data: bytes=b'') -> list: + Fd_Struct = [] + data_size = len(whole_data) + cur_index = 0 + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV image offset and length. + while cur_index < data_size: + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in whole_data[cur_index:]: + target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) + cur_index + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE: + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])]) + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] + else: + cur_index = target_index + 16 + else: + cur_index = data_size + cur_index = 0 + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV image offset and length. + while cur_index < data_size: + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in whole_data[cur_index:]: + target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) + cur_index + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE: + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])]) + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] + else: + cur_index = target_index + 16 + else: + cur_index = data_size + cur_index = 0 + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image offset and length. + while cur_index < data_size: + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in whole_data[cur_index:]: + target_index = whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + cur_index + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE: + Fd_Struct.append([DATA_FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])]) + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] + else: + cur_index = target_index + 16 + else: + cur_index = data_size + # Sort all the collect Fv image with offset. + Fd_Struct.sort(key=lambda x:x[1]) + tmp_struct = copy.deepcopy(Fd_Struct) + tmp_index = 0 + Fv_num = len(Fd_Struct) + # Remove the Fv image included in another Fv image. + for i in range(1,Fv_num): + if tmp_struct[i][1]+tmp_struct[i][2][0] < tmp_struct[i-1][1]+tmp_struct[i-1][2][0]: + Fd_Struct.remove(Fd_Struct[i-tmp_index]) + tmp_index += 1 + return Fd_Struct + +class ParserEntry(): + FactoryTable:dict = { + SECTION_TREE: SectionFactory, + ROOT_SECTION_TREE: FfsFactory, + FFS_TREE: FfsFactory, + ROOT_FFS_TREE: FvFactory, + FV_TREE: FvFactory, + SEC_FV_TREE: FvFactory, + ROOT_FV_TREE: FdFactory, + ROOT_TREE: FdFactory, + } + + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory: + if Tree_type in self.FactoryTable: + return self.FactoryTable[Tree_type] + + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: bytes, Offset: int) -> None: + New_Product = TargetFactory.Create_Product() + New_Product.ParserData(Tree, Data, Offset) + + def DataParser(self, Tree, Data: bytes, Offset: int) -> None: + TargetFactory = self.GetTargetFactory(Tree.type) + if TargetFactory: + self.Generate_Product(TargetFactory, Tree, Data, Offset) \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py new file mode 100644 index 000000000000..0b6252ecc1bb --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py @@ -0,0 +1,198 @@ +## @file +# This file is used to define the Bios layout tree structure and related operations. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import collections +from PI.Common import * + +ROOT_TREE = 'ROOT' +ROOT_FV_TREE = 'ROOT_FV_TREE' +ROOT_FFS_TREE = 'ROOT_FFS_TREE' +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' + +FV_TREE = 'FV' +DATA_FV_TREE = 'DATA_FV' +FFS_TREE = 'FFS' +FFS_PAD = 'FFS_PAD' +FFS_FREE_SPACE = 'FFS_FREE_SPACE' +SECTION_TREE = 'SECTION' +SEC_FV_TREE = 'SEC_FV_IMAGE' +BINARY_DATA = 'BINARY' + +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE] +FvType = [FV_TREE, SEC_FV_TREE] +FfsType = FFS_TREE +SecType = SECTION_TREE + +class BIOSTREE: + def __init__(self, NodeName: str) -> None: + self.key = NodeName + self.type = None + self.Data = None + self.Child = [] + self.Findlist = [] + self.Parent = None + self.NextRel = None + self.LastRel = None + + def HasChild(self) -> bool: + if self.Child == []: + return False + else: + return True + + def isFinalChild(self) -> bool: + ParTree = self.Parent + if ParTree: + if ParTree.Child[-1] == self: + return True + return False + + # FvTree.insertChild() + def insertChild(self, newNode, pos: int=None) -> None: + if len(self.Child) == 0: + self.Child.append(newNode) + else: + if not pos: + LastTree = self.Child[-1] + self.Child.append(newNode) + LastTree.NextRel = newNode + newNode.LastRel = LastTree + else: + newNode.NextRel = self.Child[pos-1].NextRel + newNode.LastRel = self.Child[pos].LastRel + self.Child[pos-1].NextRel = newNode + self.Child[pos].LastRel = newNode + self.Child.insert(pos, newNode) + newNode.Parent = self + + # lastNode.insertRel(newNode) + def insertRel(self, newNode) -> None: + if self.Parent: + parentTree = self.Parent + new_index = parentTree.Child.index(self) + 1 + parentTree.Child.insert(new_index, newNode) + self.NextRel = newNode + newNode.LastRel = self + + def deleteNode(self, deletekey: str) -> None: + FindStatus, DeleteTree = self.FindNode(deletekey) + if FindStatus: + parentTree = DeleteTree.Parent + lastTree = DeleteTree.LastRel + nextTree = DeleteTree.NextRel + if parentTree: + index = parentTree.Child.index(DeleteTree) + del parentTree.Child[index] + if lastTree and nextTree: + lastTree.NextRel = nextTree + nextTree.LastRel = lastTree + elif lastTree: + lastTree.NextRel = None + elif nextTree: + nextTree.LastRel = None + return DeleteTree + else: + print('Could not find the target tree') + return None + + def FindNode(self, key: str, Findlist: list) -> None: + if self.key == key or (self.Data and self.Data.Name == key) or (self.type == FFS_TREE and self.Data.UiName == key): + Findlist.append(self) + else: + for item in self.Child: + item.FindNode(key, Findlist) + + def GetTreePath(self): + BiosTreePath = [self] + while self.Parent: + BiosTreePath.insert(0, self.Parent) + self = self.Parent + return BiosTreePath + + def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0, ParFvId="") -> None: + Key = list(TargetDict.keys())[0] + if TargetDict[Key]["Type"] in RootType: + Info.append("Image File: {}".format(Key)) + Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum'))) + Info.append("\n") + elif TargetDict[Key]["Type"] in FvType: + space += 2 + if TargetDict[Key]["Type"] == SEC_FV_TREE: + Info.append("{}Child FV named {} of {}".format(space*" ", Key, ParFvId)) + space += 2 + else: + Info.append("FvId: {}".format(Key)) + ParFvId = Key + Info.append("{}FvNameGuid: {}".format(space*" ", TargetDict.get(Key).get('FvNameGuid'))) + Info.append("{}Attributes: {}".format(space*" ", TargetDict.get(Key).get('Attributes'))) + Info.append("{}Total Volume Size: {}".format(space*" ", TargetDict.get(Key).get('Size'))) + Info.append("{}Free Volume Size: {}".format(space*" ", TargetDict.get(Key).get('FreeSize'))) + Info.append("{}Volume Offset: {}".format(space*" ", TargetDict.get(Key).get('Offset'))) + Info.append("{}FilesNum: {}".format(space*" ", TargetDict.get(Key).get('FilesNum'))) + elif TargetDict[Key]["Type"] in FfsType: + space += 2 + if TargetDict.get(Key).get('UiName') != "b''": + Info.append("{}File: {} / {}".format(space*" ", Key, TargetDict.get(Key).get('UiName'))) + else: + Info.append("{}File: {}".format(space*" ", Key)) + if "Files" in list(TargetDict[Key].keys()): + for item in TargetDict[Key]["Files"]: + self.parserTree(item, Info, space, ParFvId) + + def ExportTree(self,TreeInfo: dict=None) -> dict: + if TreeInfo is None: + TreeInfo =collections.OrderedDict() + + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE: + key = str(self.key) + TreeInfo[self.key] = collections.OrderedDict() + TreeInfo[self.key]["Name"] = key + TreeInfo[self.key]["Type"] = self.type + TreeInfo[self.key]["FilesNum"] = len(self.Child) + elif self.type == FV_TREE or self.type == SEC_FV_TREE: + key = str(self.Data.FvId) + TreeInfo[key] = collections.OrderedDict() + TreeInfo[key]["Name"] = key + if self.Data.FvId != self.Data.Name: + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name) + TreeInfo[key]["Type"] = self.type + TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes) + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength) + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space) + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) + TreeInfo[key]["FilesNum"] = len(self.Child) + elif self.type == FFS_TREE: + key = str(self.Data.Name) + TreeInfo[key] = collections.OrderedDict() + TreeInfo[key]["Name"] = key + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName) + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version) + TreeInfo[key]["Type"] = self.type + TreeInfo[key]["Size"] = hex(self.Data.Size) + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) + TreeInfo[key]["FilesNum"] = len(self.Child) + elif self.type == SECTION_TREE and self.Data.Type == 0x02: + key = str(self.Data.Name) + TreeInfo[key] = collections.OrderedDict() + TreeInfo[key]["Name"] = key + TreeInfo[key]["Type"] = self.type + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + self.Data.HeaderLength) + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size) + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) + TreeInfo[key]["FilesNum"] = len(self.Child) + elif self is not None: + key = str(self.Data.Name) + TreeInfo[key] = collections.OrderedDict() + TreeInfo[key]["Name"] = key + TreeInfo[key]["Type"] = self.type + TreeInfo[key]["Size"] = hex(self.Data.Size) + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) + TreeInfo[key]["FilesNum"] = len(self.Child) + + for item in self.Child: + TreeInfo[key].setdefault('Files',[]).append( item.ExportTree()) + + return TreeInfo \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py new file mode 100644 index 000000000000..cfb711eea5a2 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py @@ -0,0 +1,191 @@ +## @file +# This file is used to define the BIOS Tree Node. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from PI.FvHeader import * +from PI.FfsFileHeader import * +from PI.SectionHeader import * +from PI.Common import * +import uuid + +SectionHeaderType = { + 0x01:'EFI_COMPRESSION_SECTION', + 0x02:'EFI_GUID_DEFINED_SECTION', + 0x03:'EFI_SECTION_DISPOSABLE', + 0x10:'EFI_SECTION_PE32', + 0x11:'EFI_SECTION_PIC', + 0x12:'EFI_SECTION_TE', + 0x13:'EFI_SECTION_DXE_DEPEX', + 0x14:'EFI_SECTION_VERSION', + 0x15:'EFI_SECTION_USER_INTERFACE', + 0x16:'EFI_SECTION_COMPATIBILITY16', + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION', + 0x19:'EFI_SECTION_RAW', + 0x1B:'EFI_SECTION_PEI_DEPEX', + 0x1C:'EFI_SECTION_MM_DEPEX' +} +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18] + +class BinaryNode: + def __init__(self, name: str) -> None: + self.Size = 0 + self.Name = "BINARY" + str(name) + self.HOffset = 0 + self.Data = b'' + +class FvNode: + def __init__(self, name, buffer: bytes) -> None: + self.Header = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer) + Map_num = (self.Header.HeaderLength - 56)//8 + self.Header = Refine_FV_Header(Map_num).from_buffer_copy(buffer) + self.FvId = "FV" + str(name) + self.Name = "FV" + str(name) + if self.Header.ExtHeaderOffset: + self.ExtHeader = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header.ExtHeaderOffset:]) + self.Name = uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName)) + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20 + if self.ExtHeader.ExtHeaderSize != 20: + self.ExtEntryExist = 1 + self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntryOffset:]) + self.ExtTypeExist = 1 + if self.ExtEntry.ExtEntryType == 0x01: + nums = (self.ExtEntry.ExtEntrySize - 8) // 16 + self.ExtEntry = Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:]) + elif self.ExtEntry.ExtEntryType == 0x02: + nums = self.ExtEntry.ExtEntrySize - 20 + self.ExtEntry = Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:]) + elif self.ExtEntry.ExtEntryType == 0x03: + self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(buffer[self.ExtEntryOffset:]) + else: + self.ExtTypeExist = 0 + else: + self.ExtEntryExist = 0 + self.Size = self.Header.FvLength + self.HeaderLength = self.Header.HeaderLength + self.HOffset = 0 + self.DOffset = 0 + self.ROffset = 0 + self.Data = b'' + if self.Header.Signature != 1213613663: + print('Invalid! Fv Header Signature {} is not "_FVH".'.format(self.Header.Signature)) + with open(str(self.Name)+'.fd', "wb") as f: + f.write(struct2stream(self.Header)) + assert False + self.PadData = b'' + self.Free_Space = 0 + self.ModCheckSum() + + def ModCheckSum(self) -> None: + # Fv Header Sums to 0. + Header = struct2stream(self.Header)[::-1] + Size = self.HeaderLength // 2 + Sum = 0 + for i in range(Size): + Sum += int(Header[i*2: i*2 + 2].hex(), 16) + if Sum & 0xffff: + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - self.Header.Checksum)[-4:], 16)), 16) + + def ModFvExt(self) -> None: + # If used space changes and self.ExtEntry.UsedSize exists, self.ExtEntry.UsedSize need to be changed. + if self.Header.ExtHeaderOffset and self.ExtEntryExist and self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03: + self.ExtEntry.UsedSize = self.Header.FvLength - self.Free_Space + + def ModFvSize(self) -> None: + # If Fv Size changed, self.Header.FvLength and self.Header.BlockMap[i].NumBlocks need to be changed. + BlockMapNum = len(self.Header.BlockMap) + for i in range(BlockMapNum): + if self.Header.BlockMap[i].Length: + self.Header.BlockMap[i].NumBlocks = self.Header.FvLength // self.Header.BlockMap[i].Length + + def ModExtHeaderData(self) -> None: + if self.Header.ExtHeaderOffset: + ExtHeaderData = struct2stream(self.ExtHeader) + ExtHeaderDataOffset = self.Header.ExtHeaderOffset - self.HeaderLength + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData + self.Data[ExtHeaderDataOffset+20:] + if self.Header.ExtHeaderOffset and self.ExtEntryExist: + ExtHeaderEntryData = struct2stream(self.ExtEntry) + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + 20 - self.HeaderLength + self.Data = self.Data[:ExtHeaderEntryDataOffset] + ExtHeaderEntryData + self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):] + +class FfsNode: + def __init__(self, buffer: bytes) -> None: + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer) + # self.Attributes = unpack("<B", buffer[21:22])[0] + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes != 0xff and self.Header.Attributes & 0x01 == 1: + print('Error Ffs Header! Ffs Header Size and Attributes is not matched!') + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes & 0x01 == 1: + self.Header = EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer) + self.Name = uuid.UUID(bytes_le=struct2stream(self.Header.Name)) + self.UiName = b'' + self.Version = b'' + self.Size = self.Header.FFS_FILE_SIZE + self.HeaderLength = self.Header.HeaderLength + self.HOffset = 0 + self.DOffset = 0 + self.ROffset = 0 + self.Data = b'' + self.PadData = b'' + + def ModCheckSum(self) -> None: + HeaderData = struct2stream(self.Header) + HeaderSum = 0 + for item in HeaderData: + HeaderSum += item + HeaderSum -= self.Header.State + HeaderSum -= self.Header.IntegrityCheck.Checksum.File + if HeaderSum & 0xff: + Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 - int(hex(HeaderSum)[-2:], 16) + self.Header.IntegrityCheck.Checksum.Header = int(hex(Header)[-2:], 16) + +class SectionNode: + def __init__(self, buffer: bytes) -> None: + if buffer[0:3] != b'\xff\xff\xff': + self.Header = EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer) + else: + self.Header = EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer) + if self.Header.Type in SectionHeaderType: + self.Name = SectionHeaderType[self.Header.Type] + elif self.Header.Type == 0: + self.Name = "EFI_SECTION_RAW" + else: + self.Name = "SECTION" + if self.Header.Type in HeaderType: + self.ExtHeader = self.GetExtHeader(self.Header.Type, buffer[self.Header.Common_Header_Size():], (self.Header.SECTION_SIZE-self.Header.Common_Header_Size())) + self.HeaderLength = self.Header.Common_Header_Size() + self.ExtHeader.ExtHeaderSize() + else: + self.ExtHeader = None + self.HeaderLength = self.Header.Common_Header_Size() + self.Size = self.Header.SECTION_SIZE + self.Type = self.Header.Type + self.HOffset = 0 + self.DOffset = 0 + self.ROffset = 0 + self.Data = b'' + self.OriData = b'' + self.OriHeader = b'' + self.PadData = b'' + + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None: + if Type == 0x01: + return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer) + elif Type == 0x02: + return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer) + elif Type == 0x14: + return Get_VERSION_Header((nums - 2)//2).from_buffer_copy(buffer) + elif Type == 0x15: + return Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer) + elif Type == 0x18: + return EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer) + +class FreeSpaceNode: + def __init__(self, buffer: bytes) -> None: + self.Name = 'Free_Space' + self.Data = buffer + self.Size = len(buffer) + self.HOffset = 0 + self.DOffset = 0 + self.ROffset = 0 + self.PadData = b'' \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py new file mode 100644 index 000000000000..a0432c4093cf --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py @@ -0,0 +1,140 @@ +## @file +# This file is used to define the functions to operate bios binary file. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from core.FMMTParser import * +from core.FvHandler import * +from utils.FvLayoutPrint import * + +global Fv_count +Fv_count = 0 + +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE' +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile: str=None) -> None: + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TYPE) + # 2. DataTree Create + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + # 3. Log Output + InfoDict = FmmtParser.WholeFvTree.ExportTree() + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo) + GetFormatter("").LogPrint(FmmtParser.BinaryInfo) + if logfile: + GetFormatter(logfile.lower()).dump(InfoDict, FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile),".{}".format(logfile.lower()))) + # 4. Data Encapsultion + if outputfile: + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None: + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + # 3. Data Modify + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist) + # Choose the Specfic DeleteFfs with Fv info + if Fv_name: + for item in FmmtParser.WholeFvTree.Findlist: + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(item) + if FmmtParser.WholeFvTree.Findlist != []: + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: + FfsMod = FvHandler(None, Delete_Ffs) + Status = FfsMod.DeleteFfs() + else: + print('Target Ffs not found!!!') + # 4. Data Encapsultion + if Status: + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None: + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + # Get Target Fv and Target Ffs_Pad + FmmtParser.WholeFvTree.FindNode(Fv_name, FmmtParser.WholeFvTree.Findlist) + # Create new ffs Tree + with open(newffsfile, "rb") as f: + new_ffs_data = f.read() + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE) + Status = False + # 3. Data Modify + if FmmtParser.WholeFvTree.Findlist: + for TargetFv in FmmtParser.WholeFvTree.Findlist: + TargetFfsPad = TargetFv.Child[-1] + if TargetFfsPad.type == FFS_FREE_SPACE: + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset) + else: + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size) + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], TargetFfsPad) + Status = FfsMod.AddFfs() + else: + print('Target Fv not found!!!') + # 4. Data Encapsultion + if Status: + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None: + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + with open(newffsfile, "rb") as f: + new_ffs_data = f.read() + newFmmtParser = FMMTParser(newffsfile, FV_TREE) + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, new_ffs_data) + Status = False + # 3. Data Modify + new_ffs = newFmmtParser.WholeFvTree.Child[0] + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff' + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) + if Fv_name: + for item in FmmtParser.WholeFvTree.Findlist: + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(item) + if FmmtParser.WholeFvTree.Findlist != []: + for TargetFfs in FmmtParser.WholeFvTree.Findlist: + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs) + Status = FfsMod.ReplaceFfs() + else: + print('Target Ffs not found!!!') + # 4. Data Encapsultion + if Status: + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None: + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) + if FmmtParser.WholeFvTree.Findlist != []: + TargetNode = FmmtParser.WholeFvTree.Findlist[0] + TargetFv = TargetNode.Parent + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + TargetNode.Data.Header.State = c_uint8( + ~TargetNode.Data.Header.State) + FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data + with open(outputfile, "wb") as f: + f.write(FinalData) + else: + print('Target Ffs not found!!!') \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py b/BaseTools/Source/Python/FMMT/core/FMMTParser.py new file mode 100644 index 000000000000..6e54b860a9c9 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py @@ -0,0 +1,86 @@ +## @file +# This file is used to define the interface of Bios Parser. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from PI.Common import * +from core.BinaryFactoryProduct import ParserEntry +from core.BiosTreeNode import * +from core.BiosTree import * +from core.GuidTools import * + +class FMMTParser: + def __init__(self, name: str, TYPE: str) -> None: + self.WholeFvTree = BIOSTREE(name) + self.WholeFvTree.type = TYPE + self.FinalData = b'' + self.BinaryInfo = [] + + ## Parser the nodes in WholeTree. + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', Reloffset: int=0) -> None: + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE: + ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset) + else: + ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset) + for Child in WholeFvTree.Child: + self.ParserFromRoot(Child, "") + + ## Encapuslation all the data in tree into self.FinalData + def Encapsulation(self, rootTree, CompressStatus: bool) -> None: + # If current node is Root node, skip it. + if rootTree.type == ROOT_TREE or rootTree.type == ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == ROOT_SECTION_TREE: + print('Start at Root !') + # If current node do not have Header, just add Data. + elif rootTree.type == BINARY_DATA or rootTree.type == FFS_FREE_SPACE: + self.FinalData += rootTree.Data.Data + rootTree.Child = [] + # If current node do not have Child and ExtHeader, just add its Header and Data. + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD: + self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData + if rootTree.isFinalChild(): + ParTree = rootTree.Parent + if ParTree.type != 'ROOT': + self.FinalData += ParTree.Data.PadData + rootTree.Child = [] + # If current node is not Section node and may have Child and ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data. + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or rootTree.type == SEC_FV_TREE: + if rootTree.HasChild(): + self.FinalData += struct2stream(rootTree.Data.Header) + else: + self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData + if rootTree.isFinalChild(): + ParTree = rootTree.Parent + if ParTree.type != 'ROOT': + self.FinalData += ParTree.Data.PadData + # If current node is Section, need to consider its ExtHeader, Child and Compressed Status. + elif rootTree.type == SECTION_TREE: + # Not compressed section + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != b'' and CompressStatus): + if rootTree.HasChild(): + if rootTree.Data.ExtHeader: + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + else: + self.FinalData += struct2stream(rootTree.Data.Header) + else: + Data = rootTree.Data.Data + if rootTree.Data.ExtHeader: + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData + else: + self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData + if rootTree.isFinalChild(): + ParTree = rootTree.Parent + self.FinalData += ParTree.Data.PadData + # If compressed section + else: + Data = rootTree.Data.OriData + rootTree.Child = [] + if rootTree.Data.ExtHeader: + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData + else: + self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData + if rootTree.isFinalChild(): + ParTree = rootTree.Parent + self.FinalData += ParTree.Data.PadData + for Child in rootTree.Child: + self.Encapsulation(Child, CompressStatus) diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py new file mode 100644 index 000000000000..f73f1fd65c07 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py @@ -0,0 +1,521 @@ +## @file +# This file is used to the implementation of Bios layout handler. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +from core.BiosTree import * +from core.GuidTools import GUIDTools +from core.BiosTreeNode import * +from PI.Common import * + +EFI_FVB2_ERASE_POLARITY = 0x00000800 + +def ChangeSize(TargetTree, size_delta: int=0) -> None: + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or type(TargetTree.Data.Header) == type(EFI_COMMON_SECTION_HEADER2()): + TargetTree.Data.Size -= size_delta + TargetTree.Data.Header.ExtendedSize -= size_delta + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData: + OriSize = TargetTree.Data.Header.SECTION_SIZE + OriSize -= size_delta + TargetTree.Data.Header.Size[0] = OriSize % (16**2) + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2) + TargetTree.Data.Header.Size[2] = OriSize // (16**4) + else: + TargetTree.Data.Size -= size_delta + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2) + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) //(16**2) + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4) + +def ModifyFfsType(TargetFfs) -> None: + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and TargetFfs.Data.Size > 0xFFFFFF: + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8 + New_Header = EFI_FFS_FILE_HEADER2() + New_Header.Name = TargetFfs.Data.Header.Name + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck + New_Header.Type = TargetFfs.Data.Header.Type + New_Header.Attributes = TargetFfs.Data.Header.Attributes + New_Header.Size = 0 + New_Header.State = TargetFfs.Data.Header.State + New_Header.ExtendedSize = ExtendSize + TargetFfs.Data.Header = New_Header + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength + TargetFfs.Data.ModCheckSum() + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and TargetFfs.Data.Size <= 0xFFFFFF: + New_Header = EFI_FFS_FILE_HEADER() + New_Header.Name = TargetFfs.Data.Header.Name + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck + New_Header.Type = TargetFfs.Data.Header.Type + New_Header.Attributes = TargetFfs.Data.Header.Attributes + New_Header.Size = TargetFfs.Data.HeaderLength + TargetFfs.Data.Size + New_Header.State = TargetFfs.Data.Header.State + TargetFfs.Data.Header = New_Header + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength + TargetFfs.Data.ModCheckSum() + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE: + NeedChange = True + for item in TargetFfs.Parent.Child: + if type(item.Data.Header) == type(EFI_FFS_FILE_HEADER2()): + NeedChange = False + if NeedChange: + TargetFfs.Parent.Data.Header.FileSystemGuid = ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3") + + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()): + TarParent = TargetFfs.Parent + while TarParent: + if TarParent.type == FV_TREE and struct2stream(TarParent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE: + TarParent.Data.Header.FileSystemGuid = ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") + TarParent = TarParent.Parent + +class FvHandler: + def __init__(self, NewFfs, TargetFfs) -> None: + self.NewFfs = NewFfs + self.TargetFfs = TargetFfs + self.Status = False + self.Remain_New_Free_Space = 0 + + ## Use for Compress the Section Data + def CompressData(self, TargetTree) -> None: + TreePath = TargetTree.GetTreePath() + pos = len(TreePath) + self.Status = True + while pos: + if self.Status: + if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-1].Data.Type == 0x02: + self.CompressSectionData(TreePath[pos-1], None, TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid) + else: + if pos == len(TreePath): + self.CompressSectionData(TreePath[pos-1], pos) + else: + self.CompressSectionData(TreePath[pos-1], None) + pos -= 1 + + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> None: + NewData = b'' + temp_save_child = TargetTree.Child + if TargetTree.Data: + for item in temp_save_child: + if item.type == SECTION_TREE and not item.Data.OriData and item.Data.ExtHeader: + NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData + elif item.type == SECTION_TREE and item.Data.OriData and not item.Data.ExtHeader: + NewData += struct2stream(item.Data.Header) + item.Data.OriData + item.Data.PadData + elif item.type == SECTION_TREE and item.Data.OriData and item.Data.ExtHeader: + NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData + elif item.type == FFS_FREE_SPACE: + NewData += item.Data.Data + item.Data.PadData + else: + NewData += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData + if TargetTree.type == FFS_TREE: + New_Pad_Size = GetPadSize(len(NewData), 8) + Size_delta = len(NewData) - len(TargetTree.Data.Data) + ChangeSize(TargetTree, -Size_delta) + Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size + self.Remain_New_Free_Space += Delta_Pad_Size + TargetTree.Data.PadData = b'\xff' * New_Pad_Size + TargetTree.Data.ModCheckSum() + elif TargetTree.type == FV_TREE or TargetTree.type == SEC_FV_TREE and not pos: + if self.Remain_New_Free_Space: + if TargetTree.Data.Free_Space: + TargetTree.Data.Free_Space += self.Remain_New_Free_Space + NewData += self.Remain_New_Free_Space * b'\xff' + TargetTree.Child[-1].Data.Data += self.Remain_New_Free_Space * b'\xff' + else: + TargetTree.Data.Data += self.Remain_New_Free_Space * b'\xff' + New_Free_Space = BIOSTREE('FREE_SPACE') + New_Free_Space.type = FFS_FREE_SPACE + New_Free_Space.Data = FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space) + TargetTree.insertChild(New_Free_Space) + self.Remain_New_Free_Space = 0 + if TargetTree.type == SEC_FV_TREE: + Size_delta = len(NewData) + self.Remain_New_Free_Space - len(TargetTree.Data.Data) + TargetTree.Data.Header.FvLength += Size_delta + TargetTree.Data.ModFvExt() + TargetTree.Data.ModFvSize() + TargetTree.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetTree) + TargetTree.Data.ModCheckSum() + elif TargetTree.type == SECTION_TREE and TargetTree.Data.Type != 0x02: + New_Pad_Size = GetPadSize(len(NewData), 4) + Size_delta = len(NewData) - len(TargetTree.Data.Data) + ChangeSize(TargetTree, -Size_delta) + if TargetTree.NextRel: + Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size + self.Remain_New_Free_Space += Delta_Pad_Size + TargetTree.Data.PadData = b'\x00' * New_Pad_Size + TargetTree.Data.Data = NewData + if GuidTool: + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..") + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') + guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) + CompressedData = guidtool.pack(TargetTree.Data.Data) + if len(CompressedData) < len(TargetTree.Data.OriData): + New_Pad_Size = GetPadSize(len(CompressedData), 4) + Size_delta = len(CompressedData) - len(TargetTree.Data.OriData) + ChangeSize(TargetTree, -Size_delta) + if TargetTree.NextRel: + TargetTree.Data.PadData = b'\x00' * New_Pad_Size + self.Remain_New_Free_Space = len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - len(CompressedData) - New_Pad_Size + else: + TargetTree.Data.PadData = b'' + self.Remain_New_Free_Space = len(TargetTree.Data.OriData) - len(CompressedData) + TargetTree.Data.OriData = CompressedData + elif len(CompressedData) == len(TargetTree.Data.OriData): + TargetTree.Data.OriData = CompressedData + elif len(CompressedData) > len(TargetTree.Data.OriData): + New_Pad_Size = GetPadSize(CompressedData, 4) + self.Remain_New_Free_Space = len(CompressedData) + New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData) + Size_delta = len(TargetTree.Data.OriData) - len(CompressedData) + ChangeSize(TargetTree, -Size_delta) + if TargetTree.NextRel: + TargetTree.Data.PadData = b'\x00' * New_Pad_Size + TargetTree.Data.OriData = CompressedData + self.ModifyTest(TargetTree, self.Remain_New_Free_Space) + self.Status = False + + def ModifyFvExtData(self, TreeNode) -> None: + FvExtData = b'' + if TreeNode.Data.Header.ExtHeaderOffset: + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader) + FvExtData += FvExtHeader + if TreeNode.Data.Header.ExtHeaderOffset and TreeNode.Data.ExtEntryExist: + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry) + FvExtData += FvExtEntry + if FvExtData: + InfoNode = TreeNode.Child[0] + InfoNode.Data.Data = FvExtData + InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:] + InfoNode.Data.ModCheckSum() + + def ModifyTest(self, ParTree, Needed_Space: int) -> None: + if Needed_Space > 0: + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE: + ParTree.Data.Data = b'' + Needed_Space = Needed_Space - ParTree.Data.Free_Space + if Needed_Space < 0: + ParTree.Child[-1].Data.Data = b'\xff' * (-Needed_Space) + ParTree.Data.Free_Space = (-Needed_Space) + self.Status = True + else: + if ParTree.type == FV_TREE: + self.Status = False + else: + BlockSize = ParTree.Data.Header.BlockMap[0].Length + New_Add_Len = BlockSize - Needed_Space%BlockSize + if New_Add_Len % BlockSize: + ParTree.Child[-1].Data.Data = b'\xff' * New_Add_Len + ParTree.Data.Free_Space = New_Add_Len + Needed_Space += New_Add_Len + else: + ParTree.Child.remove(ParTree.Child[-1]) + ParTree.Data.Free_Space = 0 + ParTree.Data.Size += Needed_Space + ParTree.Data.Header.Fvlength = ParTree.Data.Size + for item in ParTree.Child: + if item.type == FFS_FREE_SPACE: + ParTree.Data.Data += item.Data.Data + item.Data.PadData + else: + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + ParTree.Data.ModFvExt() + ParTree.Data.ModFvSize() + ParTree.Data.ModExtHeaderData() + self.ModifyFvExtData(ParTree) + ParTree.Data.ModCheckSum() + elif ParTree.type == FFS_TREE: + ParTree.Data.Data = b'' + for item in ParTree.Child: + if item.Data.OriData: + if item.Data.ExtHeader: + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData + else: + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData + else: + if item.Data.ExtHeader: + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData + else: + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + ChangeSize(ParTree, -Needed_Space) + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8) + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData) + Needed_Space += Delta_Pad_Size + ParTree.Data.PadData = b'\xff' * GetPadSize(ParTree.Data.Size, 8) + ParTree.Data.ModCheckSum() + elif ParTree.type == SECTION_TREE: + OriData = ParTree.Data.Data + ParTree.Data.Data = b'' + for item in ParTree.Child: + if item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type != 0x02: + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData + elif item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type == 0x02: + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData + else: + ParTree.Data.Data += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData + if ParTree.Data.Type == 0x02: + ParTree.Data.Size += Needed_Space + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) + ToolPath = os.path.join(os.path.dirname(ParPath), r'FMMTConfig.ini') + guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.SectionDefinitionGuid)) + CompressedData = guidtool.pack(ParTree.Data.Data) + Needed_Space = len(CompressedData) - len(ParTree.Data.OriData) + ParTree.Data.OriData = CompressedData + New_Size = ParTree.Data.HeaderLength + len(CompressedData) + ParTree.Data.Header.Size[0] = New_Size % (16**2) + ParTree.Data.Header.Size[1] = New_Size % (16**4) //(16**2) + ParTree.Data.Header.Size[2] = New_Size // (16**4) + if ParTree.NextRel: + New_Pad_Size = GetPadSize(New_Size, 4) + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData) + ParTree.Data.PadData = b'\x00' * New_Pad_Size + Needed_Space += Delta_Pad_Size + else: + ParTree.Data.PadData = b'' + elif Needed_Space: + ChangeSize(ParTree, -Needed_Space) + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4) + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData) + Needed_Space += Delta_Pad_Size + ParTree.Data.PadData = b'\x00' * New_Pad_Size + NewParTree = ParTree.Parent + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE, ROOT_TREE] + if NewParTree and NewParTree.type not in ROOT_TYPE: + self.ModifyTest(NewParTree, Needed_Space) + else: + self.Status = True + + def ReplaceFfs(self) -> bool: + TargetFv = self.TargetFfs.Parent + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed. + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + self.NewFfs.Data.Header.State = c_uint8( + ~self.NewFfs.Data.Header.State) + # NewFfs parsing will not calculate the PadSize, thus recalculate. + self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8) + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size: + Needed_Space = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData) + # If TargetFv have enough free space, just move part of the free space to NewFfs. + if TargetFv.Data.Free_Space >= Needed_Space: + # Modify TargetFv Child info and BiosTree. + TargetFv.Child[-1].Data.Data = b'\xff' * (TargetFv.Data.Free_Space - Needed_Space) + TargetFv.Data.Free_Space -= Needed_Space + Target_index = TargetFv.Child.index(self.TargetFfs) + TargetFv.Child.remove(self.TargetFfs) + TargetFv.insertChild(self.NewFfs, Target_index) + # Modify TargetFv Header and ExtHeader info. + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + # return the Status + self.Status = True + # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs. + else: + if TargetFv.type == FV_TREE: + self.Status = False + else: + # Recalculate TargetFv needed space to keep it match the BlockSize setting. + Needed_Space -= TargetFv.Data.Free_Space + BlockSize = TargetFv.Data.Header.BlockMap[0].Length + New_Add_Len = BlockSize - Needed_Space%BlockSize + Target_index = TargetFv.Child.index(self.TargetFfs) + if New_Add_Len % BlockSize: + TargetFv.Child[-1].Data.Data = b'\xff' * New_Add_Len + TargetFv.Data.Free_Space = New_Add_Len + Needed_Space += New_Add_Len + TargetFv.insertChild(self.NewFfs, Target_index) + TargetFv.Child.remove(self.TargetFfs) + else: + TargetFv.Child.remove(self.TargetFfs) + TargetFv.Data.Free_Space = 0 + TargetFv.insertChild(self.NewFfs) + # Encapsulate the Fv Data for update. + TargetFv.Data.Data = b'' + for item in TargetFv.Child: + if item.type == FFS_FREE_SPACE: + TargetFv.Data.Data += item.Data.Data + item.Data.PadData + else: + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + TargetFv.Data.Size += Needed_Space + # Modify TargetFv Data Header and ExtHeader info. + TargetFv.Data.Header.FvLength = TargetFv.Data.Size + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + # Start free space calculating and moving process. + self.ModifyTest(TargetFv.Parent, Needed_Space) + else: + New_Free_Space = self.TargetFfs.Data.Size - self.NewFfs.Data.Size + # If TargetFv already have free space, move the new free space into it. + if TargetFv.Data.Free_Space: + TargetFv.Child[-1].Data.Data += b'\xff' * New_Free_Space + TargetFv.Data.Free_Space += New_Free_Space + Target_index = TargetFv.Child.index(self.TargetFfs) + TargetFv.Child.remove(self.TargetFfs) + TargetFv.insertChild(self.NewFfs, Target_index) + self.Status = True + # If TargetFv do not have free space, create free space for Fv. + else: + New_Free_Space_Tree = BIOSTREE('FREE_SPACE') + New_Free_Space_Tree.type = FFS_FREE_SPACE + New_Free_Space_Tree.Data = FfsNode(b'\xff' * New_Free_Space) + TargetFv.Data.Free_Space = New_Free_Space + TargetFv.insertChild(New_Free_Space) + Target_index = TargetFv.Child.index(self.TargetFfs) + TargetFv.Child.remove(self.TargetFfs) + TargetFv.insertChild(self.NewFfs, Target_index) + self.Status = True + # Modify TargetFv Header and ExtHeader info. + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + return self.Status + + def AddFfs(self) -> bool: + # NewFfs parsing will not calculate the PadSize, thus recalculate. + self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8) + if self.TargetFfs.type == FFS_FREE_SPACE: + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData) + TargetFv = self.TargetFfs.Parent + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed. + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + self.NewFfs.Data.Header.State = c_uint8( + ~self.NewFfs.Data.Header.State) + # If TargetFv have enough free space, just move part of the free space to NewFfs, split free space to NewFfs and new free space. + if TargetLen < 0: + self.Status = True + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen) + TargetFv.Data.Free_Space = (-TargetLen) + TargetFv.Data.ModFvExt() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + TargetFv.insertChild(self.NewFfs, -1) + ModifyFfsType(self.NewFfs) + elif TargetLen == 0: + self.Status = True + TargetFv.Child.remove(self.TargetFfs) + TargetFv.insertChild(self.NewFfs) + ModifyFfsType(self.NewFfs) + # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs. + else: + if TargetFv.type == FV_TREE: + self.Status = False + elif TargetFv.type == SEC_FV_TREE: + # Recalculate TargetFv needed space to keep it match the BlockSize setting. + BlockSize = TargetFv.Data.Header.BlockMap[0].Length + New_Add_Len = BlockSize - TargetLen%BlockSize + if New_Add_Len % BlockSize: + self.TargetFfs.Data.Data = b'\xff' * New_Add_Len + self.TargetFfs.Data.Size = New_Add_Len + TargetLen += New_Add_Len + TargetFv.insertChild(self.NewFfs, -1) + TargetFv.Data.Free_Space = New_Add_Len + else: + TargetFv.Child.remove(self.TargetFfs) + TargetFv.insertChild(self.NewFfs) + TargetFv.Data.Free_Space = 0 + ModifyFfsType(self.NewFfs) + TargetFv.Data.Data = b'' + for item in TargetFv.Child: + if item.type == FFS_FREE_SPACE: + TargetFv.Data.Data += item.Data.Data + item.Data.PadData + else: + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + # Encapsulate the Fv Data for update. + TargetFv.Data.Size += TargetLen + TargetFv.Data.Header.FvLength = TargetFv.Data.Size + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + # Start free space calculating and moving process. + self.ModifyTest(TargetFv.Parent, TargetLen) + else: + # If TargetFv do not have free space, need directly move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs. + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) + TargetFv = self.TargetFfs.Parent + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + self.NewFfs.Data.Header.State = c_uint8( + ~self.NewFfs.Data.Header.State) + if TargetFv.type == FV_TREE: + self.Status = False + elif TargetFv.type == SEC_FV_TREE: + BlockSize = TargetFv.Data.Header.BlockMap[0].Length + New_Add_Len = BlockSize - TargetLen%BlockSize + if New_Add_Len % BlockSize: + New_Free_Space = BIOSTREE('FREE_SPACE') + New_Free_Space.type = FFS_FREE_SPACE + New_Free_Space.Data = FreeSpaceNode(b'\xff' * New_Add_Len) + TargetLen += New_Add_Len + TargetFv.Data.Free_Space = New_Add_Len + TargetFv.insertChild(self.NewFfs) + TargetFv.insertChild(New_Free_Space) + else: + TargetFv.insertChild(self.NewFfs) + ModifyFfsType(self.NewFfs) + TargetFv.Data.Data = b'' + for item in TargetFv.Child: + if item.type == FFS_FREE_SPACE: + TargetFv.Data.Data += item.Data.Data + item.Data.PadData + else: + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + TargetFv.Data.Size += TargetLen + TargetFv.Data.Header.FvLength = TargetFv.Data.Size + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + self.ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + self.ModifyTest(TargetFv.Parent, TargetLen) + return self.Status + + def DeleteFfs(self) -> bool: + Delete_Ffs = self.TargetFfs + Delete_Fv = Delete_Ffs.Parent + Add_Free_Space = Delete_Ffs.Data.Size + len(Delete_Ffs.Data.PadData) + if Delete_Fv.Data.Free_Space: + if Delete_Fv.type == SEC_FV_TREE: + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length + New_Free_Space = BlockSize - Used_Size % BlockSize + self.Remain_New_Free_Space += Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space + Delete_Fv.Child[-1].Data.Data = New_Free_Space * b'\xff' + Delete_Fv.Data.Free_Space = New_Free_Space + else: + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * b'\xff' + Delete_Fv.Data.Free_Space += Add_Free_Space + New_Free_Space = Delete_Fv.Data.Free_Space + Add_Free_Space + else: + if Delete_Fv.type == SEC_FV_TREE: + Used_Size = Delete_Fv.Data.Size - Add_Free_Space + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length + New_Free_Space = BlockSize - Used_Size % BlockSize + self.Remain_New_Free_Space += Add_Free_Space - New_Free_Space + Add_Free_Space = New_Free_Space + else: + Used_Size = Delete_Fv.Data.Size - Add_Free_Space + New_Free_Space = Add_Free_Space + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff') + New_Free_Space_Info.Data = Add_Free_Space * b'\xff' + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name) + New_Ffs_Tree.type = FFS_FREE_SPACE + New_Ffs_Tree.Data = New_Free_Space_Info + Delete_Fv.insertChild(New_Ffs_Tree) + Delete_Fv.Data.Free_Space = Add_Free_Space + Delete_Fv.Child.remove(Delete_Ffs) + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space + Delete_Fv.Data.ModFvExt() + Delete_Fv.Data.ModFvSize() + Delete_Fv.Data.ModExtHeaderData() + self.ModifyFvExtData(Delete_Fv) + Delete_Fv.Data.ModCheckSum() + self.CompressData(Delete_Fv) + self.Status = True + return self.Status diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py b/BaseTools/Source/Python/FMMT/core/GuidTools.py new file mode 100644 index 000000000000..e21d8e0406ae --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py @@ -0,0 +1,152 @@ +## @file +# This file is used to define the FMMT dependent external tool management class. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import glob +import logging +import os +import shutil +import sys +import tempfile +import uuid +from PI.Common import * +from utils.FmmtLogger import FmmtLogger as logger +import subprocess + +def ExecuteCommand(cmd: list) -> None: + subprocess.run(cmd,stdout=subprocess.DEVNULL) + +class GUIDTool: + def __init__(self, guid: str, short_name: str, command: str) -> None: + self.guid: str = guid + self.short_name: str = short_name + self.command: str = command + + def pack(self, buffer: bytes) -> bytes: + """ + compress file. + """ + tool = self.command + if tool: + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) + ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file") + ToolOuputFile = os.path.join(tmp, "pack_sec_file") + try: + file = open(ToolInputFile, "wb") + file.write(buffer) + file.close() + command = [tool, '-e', '-o', ToolOuputFile, + ToolInputFile] + ExecuteCommand(command) + buf = open(ToolOuputFile, "rb") + res_buffer = buf.read() + except Exception as msg: + logger.error(msg) + return "" + else: + buf.close() + if os.path.exists(tmp): + shutil.rmtree(tmp) + return res_buffer + else: + logger.error( + "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.") + logger.info("Its GUID is: %s" % self.guid) + return "" + + + def unpack(self, buffer: bytes) -> bytes: + """ + buffer: remove common header + uncompress file + """ + tool = self.command + if tool: + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) + ToolInputFile = os.path.join(tmp, "unpack_sec_file") + ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file") + try: + file = open(ToolInputFile, "wb") + file.write(buffer) + file.close() + command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile] + ExecuteCommand(command) + buf = open(ToolOuputFile, "rb") + res_buffer = buf.read() + except Exception as msg: + logger.error(msg) + return "" + else: + buf.close() + if os.path.exists(tmp): + shutil.rmtree(tmp) + return res_buffer + else: + logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.") + logger.info("Its GUID is: %s" % self.guid) + return "" + +class GUIDTools: + ''' + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools. + ''' + default_tools = { + struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", "TianoCompress"), + struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", "LzmaCompress"), + struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", "GenCrc32"), + struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", "LzmaF86Compress"), + struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", "BrotliCompress"), + } + + def __init__(self, tooldef_file: str=None) -> None: + self.dir = os.path.dirname(__file__) + self.tooldef_file = tooldef_file if tooldef_file else os.path.join( + self.dir, "FMMTConfig.ini") + self.tooldef = dict() + self.load() + + def VerifyTools(self) -> None: + """ + Verify Tools and Update Tools path. + """ + path_env = os.environ.get("PATH") + path_env_list = path_env.split(os.pathsep) + path_env_list.append(os.path.dirname(__file__)) + path_env_list = list(set(path_env_list)) + for tool in self.tooldef.values(): + cmd = tool.command + if os.path.isabs(cmd): + if not os.path.exists(cmd): + print("Tool Not found %s" % cmd) + else: + for syspath in path_env_list: + if glob.glob(os.path.join(syspath, cmd+"*")): + break + else: + print("Tool Not found %s" % cmd) + + def load(self) -> None: + if os.path.exists(self.tooldef_file): + with open(self.tooldef_file, "r") as fd: + config_data = fd.readlines() + for line in config_data: + try: + guid, short_name, command = line.split() + new_format_guid = struct2stream(ModifyGuidFormat(guid.strip())) + self.tooldef[new_format_guid] = GUIDTool( + guid.strip(), short_name.strip(), command.strip()) + except: + print("GuidTool load error!") + continue + else: + self.tooldef.update(self.default_tools) + + self.VerifyTools() + + def __getitem__(self, guid) -> None: + return self.tooldef.get(guid) + + +guidtools = GUIDTools() diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py new file mode 100644 index 000000000000..18f0cff96e4b --- /dev/null +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py @@ -0,0 +1,18 @@ +## @file +# This file is used to define the Fmmt Logger. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent + +## + +import logging +import sys + +FmmtLogger = logging.getLogger('FMMT') +FmmtLogger.setLevel(logging.INFO) + +lh=logging.StreamHandler(sys.stdout) +lf=logging.Formatter("%(levelname)-8s: %(message)s") +lh.setFormatter(lf) +FmmtLogger.addHandler(lh) \ No newline at end of file diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py new file mode 100644 index 000000000000..1a6c67056266 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py @@ -0,0 +1,54 @@ +## @file +# This file is used to define the printer for Bios layout. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +def GetFormatter(layout_format: str): + if layout_format == 'json': + return JsonFormatter() + elif layout_format == 'yaml': + return YamlFormatter() + elif layout_format == 'html': + return HtmlFormatter() + else: + return TxtFormatter() + +class Formatter(object): + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None: + raise NotImplemented + +class JsonFormatter(Formatter): + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None: + try: + import json + except: + TxtFormatter().dump(layoutdict, layoutlist, outputfile) + return + print(outputfile) + if outputfile: + with open(outputfile,"w") as fw: + json.dump(layoutdict, fw, indent=2) + else: + print(json.dumps(layoutdict,indent=2)) + +class TxtFormatter(Formatter): + def LogPrint(self,layoutlist: list) -> None: + for item in layoutlist: + print(item) + print('\n') + + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None: + print(outputfile) + with open(outputfile, "w") as f: + for item in layoutlist: + f.writelines(item + '\n') + +class YamlFormatter(Formatter): + def dump(self,layoutdict, layoutlist, outputfile = None): + TxtFormatter().dump(layoutdict, layoutlist, outputfile) + +class HtmlFormatter(Formatter): + def dump(self,layoutdict, layoutlist, outputfile = None): + TxtFormatter().dump(layoutdict, layoutlist, outputfile) \ No newline at end of file -- 2.27.0.windows.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool 2021-12-01 1:29 [PATCH 1/1] BaseTools: Add FMMT Tool Yuwei Chen @ 2021-12-03 3:18 ` gaoliming 2021-12-06 8:34 ` Yuwei Chen 0 siblings, 1 reply; 4+ messages in thread From: gaoliming @ 2021-12-03 3:18 UTC (permalink / raw) To: devel, yuwei.chen; +Cc: 'Bob Feng' Yuwei: I did some test and meet three problems. I submit BZ https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check. Thanks Liming > -----邮件原件----- > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen > 发送时间: 2021年12月1日 9:29 > 收件人: devel@edk2.groups.io > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao > <gaoliming@byosoft.com.cn> > 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > The FMMT python tool is used for firmware files operation, which has > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function: > > 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files) > 2.Add a new FFS into a FV file (both included in a FD file or not) > 3.Replace an FFS in a FV file with a new FFS file > 4.Delete an FFS in a FV file (both included in a FD file or not) > 5.Extract the FFS from a FV file (both included in a FD file or not) > > Currently the FMMT C tool is saved in edk2-staging repo, but its > quality and coding style can't meet the Edk2 quality, which is hard to > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage). > > The new Python version keeps same functions with origin C version. It > has higher quality and better coding style, and it is much easier to > extend new functions and to maintain. > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847 > PR Link: https://github.com/tianocore/edk2-basetools/pull/12 > RFC Link: https://edk2.groups.io/g/devel/message/82877 > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT > > Cc: Bob Feng <bob.c.feng@intel.com> > Cc: Liming Gao <gaoliming@byosoft.com.cn> > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> > --- > V4 fixed the Linux file format issue and known bugs. > BaseTools/BinWrappers/PosixLike/FMMT | 14 + > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 + > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++ > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 + > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++ > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++ > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++ > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++ > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 + > BaseTools/Source/Python/FMMT/README.md | 180 ++++++ > BaseTools/Source/Python/FMMT/__init__.py | 0 > .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++ > BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++ > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++ > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++ > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++ > .../Source/Python/FMMT/core/FvHandler.py | 521 > ++++++++++++++++++ > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++ > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 + > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++ > 22 files changed, 2432 insertions(+) > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini > create mode 100644 > BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > create mode 100644 > BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py > create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py > create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py > create mode 100644 BaseTools/Source/Python/FMMT/README.md > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py > create mode 100644 > BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py > create mode 100644 > BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > create mode 100644 > BaseTools/Source/Python/FMMT/core/FMMTOperation.py > create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py > create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py > create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py > create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > create mode 100644 > BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT > b/BaseTools/BinWrappers/PosixLike/FMMT > new file mode 100644 > index 000000000000..5f5519e1e1b6 > --- /dev/null > +++ b/BaseTools/BinWrappers/PosixLike/FMMT > @@ -0,0 +1,14 @@ > +#!/usr/bin/env bash > +#python `dirname $0`/RunToolFromSource.py `basename $0` $* > + > +# If a ${PYTHON_COMMAND} command is available, use it in preference to > python > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > + python_exe=${PYTHON_COMMAND} > +fi > + > +full_cmd=${BASH_SOURCE:-$0} # see > http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a > good choice here > +dir=$(dirname "$full_cmd") > +cmd=${full_cmd##*/} > + > +export > PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY > THONPATH:+:"$PYTHONPATH"}" > +exec "${python_exe:-python}" -m $cmd.$cmd "$@" > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat > b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > new file mode 100644 > index 000000000000..f0551c4ac54a > --- /dev/null > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > @@ -0,0 +1,4 @@ > +@setlocal > +@set ToolName=%~n0% > +@set > PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA > SE_TOOLS_PATH%\Source\Python\FMMT > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %* > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py > b/BaseTools/Source/Python/FMMT/FMMT.py > new file mode 100644 > index 000000000000..5028d8446ee0 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/FMMT.py > @@ -0,0 +1,117 @@ > +# @file > +# Firmware Module Management Tool. > +# > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +# Import Modules > +# > +import argparse > +import sys > +from core.FMMTOperation import * > + > +parser = argparse.ArgumentParser(description=''' > +View the Binary Structure of FD/FV/Ffs/Section, and > Delete/Extract/Add/Replace a Ffs from/into a FV. > +''') > +parser.add_argument("--version", action="version", version='%(prog)s > Version 1.0', > + help="Print debug information.") > +parser.add_argument("-v", "--View", dest="View", nargs='+', > + help="View each FV and the named files within > each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'") > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+', > + help="Delete a Ffs from FV: '-d inputfile > TargetFfsName outputfile TargetFvName(Optional,\ > + If not given, wil delete all the existed target Ffs)'") > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+', > + help="Extract a Ffs Info: '-e inputfile TargetFfsName > outputfile'") > +parser.add_argument("-a", "--Add", dest="Add", nargs='+', > + help="Add a Ffs into a FV:'-a inputfile > TargetFvName newffsfile outputfile'") > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+', > + help="Replace a Ffs in a FV: '-r inputfile > TargetFfsName newffsfile outputfile TargetFvName(Optional,\ > + If not given, wil replace all the existed target > Ffs with new Ffs file)'") > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+', > + help="The format of log file which saves Binary > layout. Currently supports: json, txt. More formats will be added in the > future") > + > +def print_banner(): > + print("") > + > +class FMMT(): > + def __init__(self) -> None: > + self.firmware_packet = {} > + > + def CheckFfsName(self, FfsName:str) -> str: > + try: > + return uuid.UUID(FfsName) > + except: > + return FfsName > + > + def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None) -> > None: > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile) > + filetype = os.path.splitext(inputfile)[1].lower() > + if filetype == '.fd': > + ROOT_TYPE = ROOT_TREE > + elif filetype == '.fv': > + ROOT_TYPE = ROOT_FV_TREE > + elif filetype == '.ffs': > + ROOT_TYPE = ROOT_FFS_TREE > + elif filetype == '.sec': > + ROOT_TYPE = ROOT_SECTION_TREE > + else: > + ROOT_TYPE = ROOT_TREE > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile) > + > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, > Fv_name: str=None) -> None: > + if Fv_name: > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > outputfile, uuid.UUID(Fv_name)) > + else: > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > outputfile) > + > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None: > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile) > + > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> > None: > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, > outputfile) > + > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: > str, Fv_name: str=None) -> None: > + if Fv_name: > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, > outputfile, uuid.UUID(Fv_name)) > + else: > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, > outputfile) > + > + > +def main(): > + args=parser.parse_args() > + status=0 > + > + try: > + fmmt=FMMT() > + if args.View: > + if args.LogFileType: > + fmmt.View(args.View[0], args.LogFileType[0]) > + else: > + fmmt.View(args.View[0]) > + if args.Delete: > + if len(args.Delete) == 4: > + > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3]) > + else: > + > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2]) > + if args.Extract: > + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2]) > + if args.Add: > + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3]) > + if args.Replace: > + if len(args.Replace) == 5: > + > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > 3],args.Replace[4]) > + else: > + > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > 3]) > + # TODO: > + '''Do the main work''' > + except Exception as e: > + print(e) > + > + return status > + > + > +if __name__ == "__main__": > + exit(main()) > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini > b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > new file mode 100644 > index 000000000000..aa2444f11b38 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > @@ -0,0 +1,11 @@ > +## @file > +# This file is used to define the FMMT dependent external tool guid. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32 > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress > diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > new file mode 100644 > index > 0000000000000000000000000000000000000000..7cc806a0133413a4aa037 > f1d43d80000546a5246 > GIT binary patch > literal 29515 > zcmcG$bySpZzxIs{h;*kQ-QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+ > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@-mueX!oILX!ky# > KL)-b > z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx > mKL > z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A-~0 > Os > zomQa`7xm?Vn1W*P-%s-jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK > u0 > zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{) > abe > z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He > 5*9B > z*-Jfk;((ApOh<DBpW00KVT-d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_ > e > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU-u*mWM > w) > zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK > !@Kal= > zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04 > 1 > z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^ > W > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy-4#Vx^C$n*R(S2#<fkNRn8K6C!26< > O > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<-BdBP<AmFX)1 > _0^ > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt-C5{L_ > zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@ > YoAv$ > zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o% > z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT > oZlL > z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk` > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@-nrRU > zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr > k > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX-Sd(_WJqP_|B0b^CxF|AoL+M;CA > Vm > zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT+ > 5 > z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu > D}JIY > zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY > y > z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk > znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h > W653 > zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz > z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8 > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B-8MDTh)0*RC#EN#u!^ > nVH$m > zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd > m$ > zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^| > 1l > zs#*3J+AHPINX8;)QiLwy6-Z2S$&-jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep > z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l > As > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$-*{a=n > ?K!V > zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb} > rWM > zKu}~4YZm`$e$42-HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k > sy > z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU > CN$ > z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG > |Lx3X6 > zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt > P > z4}!3MY9t1~*EvD4lR~M)=-uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P! > zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b > 3+@WmhX > z>ZGUkb+ts3Tk&n$W-n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C > Qkvs@ > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)-!o_k?1CJInjgyPOhp1A%MDgUMftCS$J~ > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA-1pvp;SGObla#%wB7pN+^fnJc#a?jT)B > 8 > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&-l~CT@#e0@& > vmX7 > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*-7<1UbT|>O|@l;?iY=`N4 > z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*% > zg_$H!-&YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW > z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^( > F<T-(} > zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy` > TJt!CY > zZezN}4wz=94~>e){&{8Z-!pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c > PC > z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4| > bv > zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb > HJ6Kn > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78-3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq > ;E > zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9 > uN5=1 > z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu > S > zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D > p?; > zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)% > zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw > Z%2 > z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl; > utt > z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5 > W0`! > z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59 > {es93C0D > zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@> > 3g{x5 > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^-1kaKB+d7T > Drx2 > ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB > (wX > zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u? > 3XkOqt > zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX > DU > z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y-oCVYo9xaw1S?6YWT`9V^=h<QFr > Q} > zHAIHMg-^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0 > NyW > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t-!imMfLU8CUGd)w > ^ > zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ > L > zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j} > * > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r-rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ-?%k;$V^R5XclbB > !ZjD > zt=UY&?7-X9<AFk^dEO%~_#P&-r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(= > tOwMb > z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0 > lL_ > z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+ > YC > zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc > OCnX > za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss > @v > zSgaMn{Kb=7It4nMlG8iA*-tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH > Y<UT > zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M > y7^ > zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS-w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR > A2ii > z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V-{XCZzitML(}hGq&W > zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q > zeC@D`Bk`qD-*FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS > bRs > zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw > z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0 > zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9< > 3 > zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO > 7{FtVq > zO<`-jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT > -Ie5 > z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg > u > zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV > aGRj! > z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D > h > z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o > M(_fvkH > zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY > $ > z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H > @@5TTQn > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|-*^dW > 5 > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG-=t3xx > w9x1s> > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)-^X=?*fdvD > OD > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ-h^Vc`*v)kGJbP?dUI5 > #x > z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o > S > zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5 > sA > zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A > -H_ > zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq > Cg}S > zLrkk-#H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB > $or- > z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{ > }W > zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo > wW$ > znAFU~_wY4f2q?dP-TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D > &U93 > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>-&vpdCAooZEI# > wk{a > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T) > z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c# > ~d > zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt > z0zq > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5-iu6O > P@(+ > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p-UTYHHHGHJ > a^R > z4e9LSAJ3h-L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR > zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO< > C > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B-aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad > u > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<-CE_@x)deTU#?kEtpbb>pf > JQ > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#-<B(*%Baj > w8bG > z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4 > pUp > z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j > kUEqfGQeE > zsxs)ys+*k-a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j > zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G* > Aw_D > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb-9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1 > D > z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7 > X^ > zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe > pj>) > z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID< > < > z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(` > 3v > zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@ > Y8EQ > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>-&_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar > }<t > zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+ > -Xd > zF@iS2N;c?&GGNFv1f-nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF > lqL! > z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$ > zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M > TTEJ1 > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+-iRa;O_hx8v1 > pM > zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ > i-E > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{-<qQVg#k>78 > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#-fvwHu8795}6 > W > z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-` > X2@$m4( > zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r > A*% > zYs#3InBRHdV-hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L > zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09 > 9|n > zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@ > u > zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6% > Ib > zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU > *R)a;LqQ > zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w > vUtt > zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE-{)&!(C4TBm|f@H > Qxf > zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx > & > zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%= > WmbM0 > z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl-q3 > 6 > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6-LubB > c > z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha > zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh > g > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$ > z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB > k2bs > zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#( > t_TQ<~ > zPpkWLsyFv=kpB8wMCMJ461d6-pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB > WqSJV > zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u > w9Z > zIQm^k)g4d<<I-`XDjPImuOoV3k-fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@ > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ-q&>D;Lu4Y*65q > 0=*^{N > zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT > bF > ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv< > z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv > L > zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5 > g^7sU > zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*> > 4 > zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t` > ! > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$-5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In > Z;K > z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u= > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H-JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V > J)p > zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3# > MZ@o > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G-;I<V5t?h0H4ZJmY{X!kNZmp3 > lj > zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo# > 0G7mqVU > zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx| > C^ > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os-Y*<Arj > @T > zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U > zv&u^91`JfQ*$6*pQVC-u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z > T > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB-Dh>thr$2oA7josXpNOr1+ > 57 > z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~ > zUK--r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd > V-z > zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY > VB& > zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w* > oz > z@o`0!-;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe` > m > zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B-{ > Y > z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T > nb329 > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY-w@fzc7$VQ4tNhm5V8N(S > dPS > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8-C&&+<Zy65#V5 > z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw > hf!j > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j-W2=miHT > no > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1-qeL<q;^=2F} > T| > zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC > pwM(WO > z`0>B1JR`+)ZDiuFC!F7Fv-o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF > =- > zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP > (nm$ > zgn7NXKD%P4(&M*qR-(Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c > <p > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av-4<bCdT@wTC>GBy~|DLthW;7TX > boX > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C-ixZ#a}(P > %71 > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg-Xm`x2Xg > z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA > qe > z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4 > z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8 > z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH > T- > zH|7YArh@+FLkg-WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3 > UO`cs > zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB) > 0 > zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25 > zwYj@;E^4?Qbs%M^x|g>zUX-moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A! > IRJo > zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL > wpm5C > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd-6Ob;XHAbX$!ujWY~NcR > 9fz? > zA{m&^E5y==&`JNCtrsVh*i&iF-?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj > mI > zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi-6N<6qBRAbW>R|5Yvc<6M7$K > w`6V > zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2 > q4` > z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^ > |E7=& > zinFr&rqO5i{Cmn-mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U > ab > zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO > zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw > n>R7 > zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc# > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)-%FkT > XOBB > zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`& > uLj > zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({| > *p > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X-Z#BGRQr2o > aKQ > zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt( > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q-=mGP;tP2mL@wi(xnoq6<%Cb76W9}f > Ny@K > zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O > pL)Fq>4 > zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf > Mt > z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@ > @Yi > zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v > E` > zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u > Q@)u > zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4 > PQQA > z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4 > ~<o<8e > zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D > <J > z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F` > F4& > zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb > E5 > z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z > #~g=O > zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k > e1 > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi-O@I~^x{;?=(JqlKKAP)z9 > zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF% > *F9!4P^ > zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N) > x` > zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82# > hx6wR > z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp% > FUzQ > zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb > 4G2Su$ > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&-TpdZ4Sm%Z^!(mu%Q > -d6 > z8CSq{iA^TAM+Sba`K-HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd > qw > z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci > zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;> > m > zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW > DlU4VKO$Q7# > zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF > m!6A > z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s > 2 > zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq > uX > zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b > URoM > z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T; > dh > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b-+I~rxJ^NTX^hUZQ_xQHPN@RYRbv= > OAaP0< > z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv > Yry > zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls> > &a* > z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8-K > z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m > zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j > > > zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW > d@XHe > zvn*f~#Zp|_nC%d-|J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`< > x-t > zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc > ny< > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d-chHgloB > Wr|bA > zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v > z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH > y > z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ > u7Dn > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_-YI>c&n(Yp>Lyir > ~@ > zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-< > h!%= > z*&>EVOnq&ad$05T2-6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7 > Tcf_kK > zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve > HMi > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?-}0}e(EkUQx{gt5Qv2GI}9K > s > z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~ > | > zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y > *YvY > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW-`VxgtihK5w!+4bR%e5W4fcRUBu > t}=3 > z-)H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*& > MCZ > zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&- > zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}# > (sm; > zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzcE > -_;{w > zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0 > R!C > z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h > o5lF > z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+ > &#` > zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD- > m$*V > zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt > a > zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+& > `~cD > zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@> > U5( > zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#> > i8( > zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ > zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw > JY7J-w > zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^ > NQcQ > zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~ > z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o > m > zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y > C > z<!BcWm*#gI)Q;$>P(-^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$ > VQ0FW > zGH;^fyr(a?>xrm&;uh2hKqp>D-AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7 > aZ > ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z? > !Ajpt > z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha > 7z > z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ > @Ox > zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0 > l > zVjM=Qw37|BK0|)-NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj > z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II > Uz > zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt} > MtL > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr-NH4*=bhL7Tc<AKzmQSP`%KB$^O6d > paf~! > zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE-1A > zv1;CZ!z3UqKTUkaP--mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw* > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO-t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs > Eg > z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$ > ^*M} > zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v > z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr > Z?;v@B > zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_ > zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb) > OG > z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK > n{X > z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1 > pZ%wkIe6 > zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY- > pR > zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75! > sSCv > zOI0V)+9b%8^ak8NWz6d-k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW& > !*&3( > zh6=X0QmwWX9XHj5l1@tYGXVhG)-Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+ > HQzlwT > z8x|ZZV|V(-wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH > Psf > z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs > s8V7 > z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj > z5_5g=+O$i$k;%-1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO > 5%a > z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z- > qZ)Dr > z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E > NpfA > zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0 > zd*)2v-xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k > XtIl50 > zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F > Um > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}-_g|Ab91$j2ad2jnt > +=M > znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg > zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY > QmA > zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf > HM# > zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5 > VI= > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL-`KrNzBi@nX > eF > z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r > ;!F > z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t > xQ > z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y| > p > zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp-=DEZ9aDLwe&emQpH(ng8O8f| > N|b > zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO > -%SX > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm-Et@op > ^sZ > z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW > 5K > zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes > )B > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o-9JRkFbj^Cvi9 > l63 > z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v > +d4T > z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^ > `QF}Y > zTI!eAjaQV1M2^`)i<P>gsTGz-UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew< > 3 > z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V > mt<0 > zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^ > + > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=-Jy}m > Zu > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^-&~y > sjCF > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC-gE$~l!e > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^-Xvwp0G$Ypd!Rc|ZQdfy > )>q > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d-LF2U( > N;ve > z`|0v08lJhE-43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK| > T > z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`( > m > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<-L*AxFh1pz<SsamItVw$U* > KSpI > z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ > G; > zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G > iy|~ > z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw> > 1jO > zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR > ~#6 > z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W > ;)# > zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb > z$n8i2c(^-EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN > 9%7z > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J-iap7Ma > 7+~R > zr)wN#;gC`Q+R-b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7 > sn > zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw > HK > zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz > zM > zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c* > wq)= > z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF > S* > z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk- > _@X* > za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~ > I4 > zMe~hi*!yt-e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW > B@ > ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z > aMs11 > zN|%vFr}N@XKRz-JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW& > XA7Ak > z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY > M > z{((;&-ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB > z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S > KDX > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`-jSejso!@e^uJ > < > zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG > HTu > znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH > d+ > zMY-=jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+ > k&+m > z%ZWm1z4nMfO?(4A8G8!-oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+- > ^I > z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4 > e|4? > ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj# > ^0e > zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E; > aO > zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI) > d > z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA-+T`x7hrGd7 > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G-tP(~dNEPPRy<$X2&|cAe5A > }bI > z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C > zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM# > g8_@a_! > z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0 > 06 > zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q# > N > zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@ > M4b@Z > zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A > W > zDssgPVVyB-*vr3ad5~B-)<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f > wo) > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H-BNMSM32B_HnUIx=z%Fof0ntPF#j9W > WX+ > zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u > ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L > D0 > z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$ > T2! > zdK(Bjx%p|zQnoY<UWi-I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb > Nki > zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP> > u{Cu > z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA > z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a > @W= > zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p > zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b > aP~U > z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS? > dZ > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T-wQgkxi3VLQjxyVy > zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod > Up5h > zqp!T4LK?<KJ()xH%)kcP!N1qc-swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n > rr| > z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g > $M > zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG > nyO9 > z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<= > QC > z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO > 2Oi > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl > zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI > +uw!; > zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL > z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2 > )p > zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B > c;i! > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV-Hkg6e~c%ayO > }6e > z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf > zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx > yhi > zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE > FSC > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz-*>o*46xhGpS8Y;XQ > *+ > z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_; > $3Q > zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9 > d > zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq > b-| > zOx|zYa;20oYTSb^$f*puP6`{=@+R-cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs > C^ > zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv > $0gQ > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#-a+SMQ@Tv59b7zfSbF`J@FL3|c(?~ > Mw6 > zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva > Y > z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK > J}o! > zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y > GYg > zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE > z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ > QYoK > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ-~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{-p3I!HZ(Q(cX| > H6u > zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@ > wl > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_-`ds;ZHWg<At > o > z_!d&4;KL)krKVbM_-%V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3 > zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW? > s&KLw+ > zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB( > ~6l > z==pSlrsfT~2W{Zj-#*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU > Xk > zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1( > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$-Ow%eFF$z!@ > J+- > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R > zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR > +Kh}Lr > zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2 > zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{aQ > z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n > C)ZrQ > zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7 > 6h > zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW > z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C > Wu8yz > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{) > zw7h-b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{ > $z*$ > z=zlg}>gO`p-0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i > B > z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul > @} > z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6 > nc` > z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU > z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7 > 2C@ > zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM > e > zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2 > z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg > 7 > z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP > Su5 > z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{ > 2 > z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^ > h{bn+ > zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4 > uNZt+ > z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH > @17p > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@-1E > 7@! > z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv > UZA3 > ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13 > z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq > z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2 > zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH > zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY > Ep}s > z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox > zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n > z{aj > zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT > zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC& > Q* > z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@ > 1dFnWtdD > zNVk1t_y;mT-k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr > q=F > zDjf9;-DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu > WqN > zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM > o0 > zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p > h-@ > z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK > HW > z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y > nKla > zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D! > B > z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp > Zw$e > zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c; > za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g% > mO > zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_-Hx > _2| > zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6 > R4Rr > zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N > zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd > zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6& > u@Wv > z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6 > 9Jd_v > zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56-8|HN!VHDt?X!7%VRV8^)x > U0D > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e-h|F2yMD^>eWe)o2zdCq!a(n?9 > >#f > z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO} > F > z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ# > qTm(t > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;-}$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG( > 6c > zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr > a > zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU > zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h > <pq > zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC > Mb > zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn? > G > z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm! > &o > zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e-RM%C;1ods}_Dy6=&aE!DH&yZe}Po > l_s&^ > ztt&=Z6-Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D} > 1 > zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6 > Vm*0jD > zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS > z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|> > `XAJs > z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL& > z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A- > Mf > z<-7K<$G6OrXCLF&g-X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN > z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il > {Aw9 > zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87 > CC@?? > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo-^_Ot?JdLg|1aj$ifpl{V^ > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C-R#Vcu^1XBSkb > = > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o--&31)1TQ|Q%EAhuIXZd?<`#d > Hj > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1-k2y^JQ>&e<>!r+45@!bqRS > D > zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#= > z8@e(3tmNqVWq`wXV!qG<JTY-Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3 > e-e`uBA > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq-a`x7HIXwJ=fQf_ro@BbDbjW+5A=13 > ?M > zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71-xIa;QyQ+A+=ch*hu > DSEC > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0& > > literal 0 > HcmV?d00001 > > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > new file mode 100644 > index > 0000000000000000000000000000000000000000..6335653ece1605cd0c53b > d2cc2bc21d57d213dae > GIT binary patch > literal 79906 > zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$ > C9i > zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c > } > zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I > { > z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7 > MH&Y > zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM| > NThc > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M-DQkUsiWm_>>F`39z{F@w > QiMSjA > zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^ > -oj > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB-Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY > zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1> > z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o > OF-( > ze(GY+PNz-|cTO$duNND)-{Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR& > %J > zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{ > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb-jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD > z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW > %3^ > zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k > vG > zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3d > R&s7P > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq-u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm-&}GK > x(< > zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n > -t? > z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9 > * > z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V > 4Ni > zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu > ^% > z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4 > C= > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+-DI^9d~!WoYX0A1$ > X% > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=-;cGp& > 30 > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X-)f2nzV!Q^qU_$m?x3Qsm > ex3w > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j-#eg0l|9C)@T=sxzA > k > zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E > NK9U!c > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4-eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb > nmP > zDdg?>-mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a > R`2d( > zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|< > D<#} > zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o > 8 > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e-W7 > zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_ > P > zLL$x|O2|$4_>pUK%4O!a-6#4-alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT > z`*O5L^inXLpWTzaUm%TSE<U`-Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs > p! > z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{ > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR-#Ov6((s > C#V > zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T > @9C > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&-x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4 > n= > z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ > e > zuk|Q9*5!@y$-x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF > 8^ > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G-<BptWKsIz=W_P31e > zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2 > &++Q{ > zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv > Y!Bo} > z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8 > P< > zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z > RAE+ > z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K > z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e > g > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA-UumgF$+yN > ^{w > zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR > {j > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0-9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N > XFE > zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj > zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z > v^+ > zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)# > Yhjbc; > z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_ > Rx-k$ > zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r > !n > z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#}; > @Voub > ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX > #p{~VSr > zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2 > 6z*3T > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^-D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d > NUT > zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s > zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ > znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp > utI > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg-y}h%yHH_0H > a8<A > zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps > >6Mc?h > z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e > TQ%X > zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M-G > 2{M > znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u& > Jp > zum8=!r+B_~0&G%_%VRj-TC~2mL-ot07njmvdGDQXScyh?WMt%s_phdFXEx;v > A6W{j > z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam > `+(0 > z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29 > @ > z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On > @-tU=bw%s > zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{ > YugQ} > zM8N()%W_L~2Da%^cIAH-<-an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v* > wES > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H-AhOC|1BQKucrND=U^;)jo > OarT+ > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s-8ymFk^)c%duzJ;nL)3Nu > } > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx-&f`Khm=*XOz > ?S<B} > z%8w-r#pfF@&BNC-fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2 > 2QC!aZ > ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP > W > z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!% > U)1gME > zXaJ!`N#R-_I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk > z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@ > ZQJwxv > zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM > |FT > z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M > Re<Cff; > z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{ > P5 > zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L > zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg > uoJJp > zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^ > AC > z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f > z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7-rV > rF > zg3F-R(c*YRq-@%swU!k`8-wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R( > 9R2;h > z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs > 08Z > zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r > wY > zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a > %KM75 > zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2 > z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW > G > zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K > 9+X > zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S > z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ > pa > zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds > zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^ > rj9 > z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI > 7hE2 > z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U > Qp > zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P > u^kAGC > zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p > &qx > zu6PAe_-|zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce > Wy}o- > zDVg;W`B&bT@-K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~ > zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV > >9 > zsE<cJl8QUANXMMXD!_@-n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P > q > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC-=%ubEfAZ > @ > zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^ > zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA > R5My > zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v > adA > z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L > ~M > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW-e{py@ > Z9m > zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d > zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G > % > zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y > 1 > zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI> > pGi > z+_V-c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+ > X > zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj > !|* > z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU > M9o^q > zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k > z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y > zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G > tq > z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp% > wS# > zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2 > iu$ > zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^ > Q > zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{ > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x > z-axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b > zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d > zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi > GxV > zW+Xgk^iMPoaLhyqRlH?kt-@DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~ > z > z?VV;!_jL_mlUw;2nHl-WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4- > % > zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+ > UJ > z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2 > >D > z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{( > <dC > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i-6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2 > % > z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7 > D~m% > zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU > wS<o > z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT > h8Q > zoJ6nV;1DH2O4gK#e-q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO > zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y-?g > mho5+ > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane-R8v5Z3OKYwF7I{995>T{A1a4Im! > )_ > zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q > wBco > zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8= > %Fv%A > zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl > ZU< > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0-}=OWCI_3x@ > 9 > zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz > hw > z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*) > z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_ > z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC > DNWo > zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T > ! > z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T > z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s > B > zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7 > zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ> > TQCm > znzg-`v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a > 0J > zIkAk(wATQFU}lxojL8BaMgpS*sZF-`Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y > z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e > zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n > >SOcM > zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ > %4x)R > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}-7DJqPTCn{7Nz>p0rZlI4~7mz > zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|! > g`?g > zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO > cr > zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb > Z!t > zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3 > l8e% > z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O > (n > zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O > pc> > zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>| > 3uW > zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{ > UyAaR~g > zku^pl=~dP2`Zfc98X!v015wP-Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd > r > zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j > 9 > zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so > Gf%c@ > zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62 > 5bew > z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG > zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN > ^ > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=-Y=I$JBF{x__)9E*zZEmcCFhV9%@A > |;C; > z0dw89i-PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%- > & > z>Q=`%q>K==&;cust-ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV > z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9 > XLis > zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P > 1}jc > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k-w~FY#E${v > @rK > zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp > -fr0oM > zeqF9y$w4I3?w-jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU > Fr1!2 > z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~; > mLh? > z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1-(p9OWCabzpEq45mFF > oK|H > z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+-O > Y}tK > zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a > zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa > +|BJf > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo-{zTWc%6}gM|{b`5lyb8()nn?Zf > zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9 > +T > z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%-(}mcvBi24si~mkArbb_~r3o|KZf^n7Uy > E > z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{ > $e > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H-8)+593lMa!6m;Ey~fbc > ;@zbu > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g-`zSeHh*X@cob > g_J > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H-$azMlS<h3_eAd0+EVB > ViPF*q=w > zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS > Tw > zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K` > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;-q=U!pbpr~8VdgFOFb > 5t^9 > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9-6O1aqUt > zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9 > QDz?mSX5 > z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l > QHSl > z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F > C# > znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1 > zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~ > H > zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_ > oz > z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K > DGp > zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o > zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C# > v9 > zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s` > S > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E-y8jBnk?{Kg<Q(rP > ?aP > zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M > #<y@7X > zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P > e > z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf} > Dot > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)-tXUE^B;?g$~2}e > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr-h5P};PfpB7o>k|p > # > zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5 > tV > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz-o1WNRw7&EKpp!}70%&c^b > 4h<X* > z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ< > GAqMM > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q-5QmskD?C29B1Pr&(c@s&e+uwi>ijiC > zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz > 6I > zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2 > p^z > z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3 > z<50dfE9+W7#lo(K-r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+ > CCm > zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7 > 2*<<s > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}-rVwE?y%~_n0~M > } > zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m > &MC4 > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw-XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL > -MC > zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY > h39ZZ}0 > zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb! > L > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v-s0rJQC*k<wIAScDz1q_$t > 67V9 > z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M > @O5t > zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X > NW > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3-Je!ymF9!@&)jg5>?2{8NsyKmZu > 0v4vt > z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6 > m~9% > zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$ > 4 > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls-oKS&kVw270i?>6=6@nEFRC5Es` > ~ > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*-LqT > F>U > z^KiUZAYXWSxqM(C(C=Zy<<Qa-QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r > G > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=-4|~9MCtID_85v > Yp > zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W} > hq > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<-JnxxY)Hg > z?YX0XeW;3-48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n > >i > z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU< > pvY2 > zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb% > W=j > zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re > %CCQ<r > z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1# > &l`5 > z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2? > |b4 > zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx > E)m# > zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV > >xj > zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o > b|> > zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB > wX}s$ > z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw > m=%XJu > zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf > XFK > z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87 > omSx > z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#-8~w<KRe>5t8O19tX > VdlKcX > zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X| > zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza-27uAu?{)Oh > zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1 > u > zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll > Tnbb(?( > z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L > W5JPe > zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT > G > zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x|| > &@ > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B-qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y > Sa > zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw > ( > zY^$M(f1CD!4Fn3S@`Lx%c?j-wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7-Yq$ > gRd > z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA > z8K_Ar&HHJwu<-S7^&Tz-z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D > Q{Qdr > z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz > zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l > h|` > zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H > d> > zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+ > p8T > zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi > Z`#p > z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK > G > zO!{{Gr-ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N > z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E > QFcnaYc^ > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe-{}E&CO6a@=<Y;tXT*n > V6 > zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC# > 52^ > zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j( > V7D7 > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u-U{ > b > z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t > ^wM9? > zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs > K25^ > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff-KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|-EFP&Y*s>3Yf2)ZCTs)~ > gJ+ > zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{ > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G-PPJ0 > ?Kf3 > z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o > Qo< > zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o > UA= > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD-X_KaBxie|nwb|o$l{eH#^hvv27< > Qn > zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn > D@ > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb-jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U( > z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ > zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$ > %Qo3*6 > zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m > 9{p > z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ > +Y > zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl > z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE > 9& > z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$ > &>8io > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb-OZgaoXUvS83(PBK8FLxH<rd+PcVL > z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr > @>iU79 > zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl< > @ > zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth* > NP > z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_ > <h1r2 > z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U > U^ > zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S > a#=2pN > z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T > KI > za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh-`^5g98TqP_j#KdfRYD|0YNGFhOt4 > #( > z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy% > MXI4g > zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc > v > zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA6 > 3 > z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L > P` > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&-acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z > G > zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF > Xihx > zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg > ~d{ri!Y > zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{ > z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_ > z) > ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi > x|! > z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G; > *KA > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a-2i*w9Y1kWggcE > Az > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz-Yc~Qsu2kWQ?O0sIz*2Ug$6lF > 7j$V > zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN > bAk > ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc > @ > zi|8mSqO-MoaYaqA_#}w?c->nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G > 65>` > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog-(Rz@ruT7zBf!)UI > W~ > z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T > `E > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^-^WD > % > zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf > zTyu*%V(L_|%5}>KD68-34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy > 2 > zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr > ^+)zfc4 > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#-Uk>=DjJl057_mpgxax|_Z7^eE > *fBXa > z5_DRyRueL^-#{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;( > z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg > & > zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB > z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&} > h > z32!E$+=MZ91HfdyI-J-l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$ > zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m > @ > z7tPMl@iqfxzh@Lj$xc-Z{m@G-GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P > nn4< > zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX) > q( > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb-qV@_uT2r9>Pn}r5o@L|E > Y*YV > z0`B%7x?w2<&7x>az-wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1 > m0yoPLQ > zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y > z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W > mG > zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j > sD@ZJ > z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28 > 9!| > zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR* > r7a77 > zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG- > z-09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e > WrXO > zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC > TI > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk-v)o<J5KbA=o=@`(r5hoYx > Mi^ > z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6 > 6N > z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#-IZ<w4%qoDyYF%VJC8 > ue > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n-wj*c)&TK > 0t? > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm-qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~ > z! > z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56 > MWm- > z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92 > W=k > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?-nog7X%sk_s<Y+v > *t > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo-`!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F > zbCM2u?}yBTP-|YUP+qtE+N-$^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8 > 3OR > zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc| > ej > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{-f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~ > Y > z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5 > mBp > z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K-6r > 9Of1 > z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB > H* > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX-uT&S > z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B > Z5=er > zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c > sNof` > z=Hs3R{$%c!jWY-L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP > ` > z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0 > bt > zlnR+ZB=thb?WfT~!j<x<0-aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u| > vh > zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7; > J|z > z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0& > z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N > YbY!ry > zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2-<QnUzm@<!39peL;+M > Bzl|M > z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_ > EO7gN > zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6 > $i > zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX > n{Of > z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R > @dv8E > zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@ > YK > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We-#w4(vmfn?Vr > u > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6-4f(+RJub`mui! > Dw > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl-}yeK=rbpE2k2X > KXQx > zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&! > 6 > zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj > N > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf-y^iZn3c@baZ{@GX$an^4lQ&IToF+y > zyt > z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd > z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a? > S > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di-#FqXjnSNMO_Y*e|TkzT6w > L > z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N > L > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!-s9+9*KOCp;tUhBW(x32 > DqHX > z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+ > ( > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y-Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w > X > z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq% > K > zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel > z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j# > +q& > zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t) > MFP > z2e~I-K~cSXx8EG)lzE+7@73IePhx-;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL > #F > zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5 > ~|o > z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f > zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf > zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af > A<3 > zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw > FM4a > zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD > >YZ7` > zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd > W<i* > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q-dnOip*0`sN2T > a~yG > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk-(q@M > TF-Nx > zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{ > ` > zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra > OZX > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW-kGO+`xCf>(h{Mcc > %|2 > zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE > zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV > -5^$B > zPbdR=b%2-pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L > ? > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2-pNELfG(uNbq{doFM5MP7xlb)Rgq > < > zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N > DpUF > zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q > %wi~ga > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW-3aN5iiL| > ` > zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$ > z > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+-lbp!I4w9ZnT_6aMT~=LLkg!$R > l# > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c-lmKVwD > 3GSE9z( > z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE > zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw > bk > z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo > a9>Y > zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(# > R > z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@ > K > zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9 > N? > z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw > K > zdildOB}k13;#BI@N5b9u5s-{=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp > z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w > 64j > znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>| > sB > zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r > zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL-$T > m> > zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1 > 3i$ > z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k > G5`&V > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng--HdhvEg > EU > z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4 > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$-Q%t!bC > $cv! > z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO) > Br- > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C-8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ > 9x`@ > z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB > Hp} > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r-2YOPxyr* > b}> > z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A > DU;X > zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@ > bS > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|-W+1H2CZtdm > OT(s > zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J > zwr > ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$? > Zisq > z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo > zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp > < > z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~ > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x-|BgIJfi=ju7@WZg- > yi > z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW > N<+%Xc6 > z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v > Gh > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep-0s*6L=4RuZ>k3UeD`pkpd= > K6 > zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8 > a1HxFs > zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY > yJ6 > z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR* > & > z-=>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk > f > z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJG > f > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C-m=TI!deWV<@u@B+g9zOd!H<h7 > 6 > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H-!7w?@Nm!4fF|H&)>RG9@xH# > VA%Kj > zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M > 3@ > zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x > zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL > m2 > z`KG6~&Y4#$->{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO > KIXO > z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L > NUGvT > z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr| > %C > z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S > $~q > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o-IzYg)#61qGsUJ > @X>V > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY-L2ha3l(|O > P > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=-neefemATL|%SeTj > 7KM > zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc > e > zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u > L7 > z!mV(@!YY)C1EI1tx4-6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x > $AP > zwpSBL-W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu > yMC6_ > zOF$m<BQ-2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI< > T&4! > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~-^iTXueIx8byvHT>hu$|i_OeooSft > n > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV? > zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1 > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%-W88*^zKTEx>j2)~V > 9UTQ`* > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V--kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL > 57 > ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V > z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL) > $Zo2 > za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I > e~kMH > zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?! > %!FY6 > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K-s2WN^ui3C{($wPhZa^$pzWR^Hl > 3F > zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw > 4<G > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt-M7|}+UXRU7h?~TB=)5(t0^!( > %P > z-F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc > )h3ea > z6-G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W > Nvtc > z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O > B-A > zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV > vU`(H > zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW > E37a# > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o-gou2?WYbb69sCMC}^w$$jzUo!Y& > ! > zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm > z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z > # > zq-Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV > L > zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;| > z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO( > 9zDJE > z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p-ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6-fqr2rZ=VYP@rHCOq9pf8B0xw@Y0 > Q|UG > zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY > zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#- > G > zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X! > we > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)-H!*m0eZZ!QVFvyXV^=j}!Z?!plq > zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h > 3 > zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43 > 0oJ > zI(_U{Z0qELvqlo1zMy(-joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq > I+ > z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+ > VXJD) > z-q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV > YY0B > zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC! > P| > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r-*H*VR4`LaS<<C1W7hg& > ~pO+K- > zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM* > ANN > zUz%6;oPCB&&k^}WT*2fbT-rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)( > t{ > zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z > 4P > z{MfuNHeOI7d~NQbki>Wa*r?}Ta-}c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw > nR7 > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&-v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0` > %z > zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y > O|w1& > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih-2{<n)!I+;AHbRo*RPPJ<gUm%2 > u > za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP > d~+Gh > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj- > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?-BXUNalABrN}l?3DDjuoNkTNq%YT7 > 3F~h > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV-S%|a7B=tS!rdlDQnw_~vR > NG+ > z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI > TI9~ > z80}SbU~>FO|9I4K$=-QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@ > JW;6 > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=-TSOTON|2ebg0xls`JM}%@O`g > K > zmH+=v*cCg)>)6&*G74T9ntba~IB-18Gfz;WMB^neWL%=F6kixs3>vAmMHr<# > a{F%5 > zSV4%6rVjJ{9oXWh7>e;x_5=7-ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@ > Cxn#6 > zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4 > z!jPQ@A+Wb%GhI-D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av > QoVl > zpg?U5sxJ^-s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU > u2u > zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH > Y16t > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l-Fr_U^mpQywF > 7_%T > z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a > mi% > z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j# > @z5( > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi-XyKLb > hKa > zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p > zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt > i- > zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K > 9fOo`p > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs-ui){uM_Y;pwOERO_ > ?nhh > zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp > !5R#S > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q-UO22MYfNY > *&sB > zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1 > zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN > 1K > zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt > zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr > |TU+ > zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@} > qgr0T7w > z<XUd9YdH`MV%gjTsUwYem-CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2# > 7kIj!) > zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D > z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx< > D`^2 > z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0 > O > zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w > )9* > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz-xEr*zAK9 > <N?Y > z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F > &Xs > z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx > qkyHve > z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp > E(bW+ > zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II > z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a > z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K > 127i > zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe > WR1yd= > zOy+GS3N+k-;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X > 8KHw > zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM > wuHG > z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T > NTye@ > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+-8Mp5YQRWhyS@`gIr&htF@U > =BD#r6X7 > zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp > i=M9v > zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9 > f4 > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f-C*U > }T > z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2 > T=@i > zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_ > &ip > z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED > M > zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F > Ya5e > zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A? > N> > zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n- > -MxQ > zG1h%OC9O9yC%If5t*4BIdz)$gh>-Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q > MQ > zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV > SbVYbX > zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`% > WvX > zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d-XA~5}VSN6cplAA%P=_p4Y > qn~a > zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q% > 9};T > zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w# > X`^h > zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_} > Ln= > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw-J{yCA}t$O?2Gbro_S0%@6bE|NUO7 > 3JAX4o > zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM-0 > <2 > zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT > D9y$ > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4-pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW-8FRu~9(wk+ock12GT_ > Ja > zM^?ezBrqptKLHwLt1X-1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0 > #5 > zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82 > +` > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF-GVJ3Or!j$S_H;Jw > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!-_c(_oR > c| > zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu > ma= > zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW > Kn#~- > zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO > XKo0` > zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f& > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v-Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3; > ( > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y-BrsYiU;W<x<Ea;>dpU > @ > zmR>$-PfosIWz(r5(5<wxPbjmo;#-XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N-z3e*X4)s#1kO^g=a > {~c > zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl > z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84} > qZ > zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1 > vI2 > zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP > |K > zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@ > +3pvf > zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc > 7 > zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l > WtAe > z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$ > w2^;3 > z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7( > zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844 > z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP > oM > zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+ > zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j> > aq > zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`; > L2G > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu-hUH$wa > RbE > z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6 > mTGS > z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz > w= > z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID; > @ > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb-Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F-?Au{0G5tdd)TPX1hakJ3TvR90rM<^ > Y > z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa > @~k)f > zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m > L4-Kc > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!-_hOdW0;F- > OTOp > zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!= > X+}$ > zFuvZ~++1ipISzO)2)RT}D;-aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7 > = > z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7 > GW > zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU > ePA~ > z_hxdvS8-a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E > z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e > zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(- > C#Ha|I > z=C2Ea@CE*LYY3?FwL2-o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn > be > z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A > W=XSe- > zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns > zM-{9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs > 456yTg > z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U > XC > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_-=gt@_z#8g{&FBl60M > 8q > z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl > < > z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+ > <`F > zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v| > da* > zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv? > e > zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM > P?$BB > zOd-J<xYW8H1RRa|E>kVw-`TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da > kHuGSr > zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z) > P > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r# > z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl > bN}< > zqLB8`-^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX > u{1 > zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq > zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX > )z(Tp > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD-jHBwcr%2 > 0bUM~ > zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm > n > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f-bCjEDTbbkioa3 > AvU > zTgs{woXY3O-Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw > FPeX > zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh; > z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G > 86v > zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu > JvQk4 > zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An > t>wSc > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af-Xuf0lKfuTpKFA04 > 1 > zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I; > hr > z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+ > wHXl > zz&1Drp|7~EN?!zH5pKw!JvbXK-ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B > C!KO > z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug > B$R > zx6k>}-^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg > zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD > ;>-$c > zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM} > zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO > P{<K > zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB > G7 > zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7-kO_`Up!D&o+Zeo37N~wiT > 81j > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e-+C(B!Y<Aj46`65i%71cYGD{ > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;-TI~; > EW > zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n} > xK > z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I > z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd > nlbj > zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05 > z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j- > Y > zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^ > 7 > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0-O=A5+6B7bE > #7 > zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ > !$pK^xF > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn> > z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf > ma;W > zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i > xTr > zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X} > ms > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D-^e94<`cGBaYaA!4zd=KEsJn > eJ > zd%}Zl026m#*+6#l9yFz!8d8<-XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i > } > zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+ > zD#6R=4Z52d(S5iva$jQAz=xFyN-q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~ > ( > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG-UmfNcjAaL > Epl$S > z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7 > m#Z > z1f>)aDLDPf#(_xvLI-F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g > XhRr > zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f > zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_ > <Ne~e > zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S > znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p > 2%fV|*A > zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F > +?= > zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D > 0 > zIugZZoN&hDJvgzTn^^1-d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X > uR > zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y > wh4&L > zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9 > v > z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y? > @d>R > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO-x&lC0KfJO|C8kgnlMCC`W~^izTp? > z > zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$ > )4 > z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj > NU_ > zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L > wJy > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o-D+M > C? > zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R > @B3p > zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p; > pe# > z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg > Gu > z<x;1&YdE7!dLGg3LR#-vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H > xN> > z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45% > zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh} > R > zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!; > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`-<Skpc > zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI( > zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck> > zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1= > O7 > zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ > Q > z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$ > &S(O@ > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{-gM3Y^a > D&p > zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C > 9 > zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw > R > z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA > Ms? > zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l; > EF=S > zx7~>-e--gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi > fo > zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d > P > z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx > RVQs > z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e-eJ > (bu7W > z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY > jt9 > zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW > zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M > M>h@k1 > zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^ > zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7 > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2-Z~r3V > 4w4#M}^k > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7-#MPr;?r3h8 > kN > zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF > ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p > 4&oPZ > zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V > W1 > zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?* > 5gM > z-dO<=pUw9Hu!6VH-$5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^ > P$ > zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D? > W@}5 > zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8 > _Vr > zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G > Uu > zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M% > 7_V&j > zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ` > z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG > z--mu$ZE#I*Q8<#GJ~-LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts > 5J#$S > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`-h@bk9 > O3s > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S-y+h< > ?#Y > zk-Qk=flDo-RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu > z+C9W1IPvuo^Z|-GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw > VT0 > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy-t?t~fVXzqFG>P(y1EoKn > x2hb > z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b| > +mG > zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D > !#34 > z-*FDsO~mox-k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93- > 5v$t > zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO > CE > zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z(Y > z)aDR~xD1dzXmhus5Q??fihY8I-?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1 > QMq > zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@ > H~~ > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT-h%26Z > X# > z7~{-@v;G{8Lxo0@cHdz4T{-P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur > +Z > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6-Xr9n > R6 > zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf > w^ > zZ3$IK{RGVZe9g9-KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul > qu_{W > zTj#6IYv<7-Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7 > AD > z{ZzN7#^JAPYu-X7Y-03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{ > uPf9 > zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f > 4A>iW > zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d > &( > zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l > # > zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_ > _~%; > zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki > M#a > zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D > vAn@ > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0 > zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l > zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~ > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_-EP9=wZkWSqwPf`a`R&_k > |@1@ > zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj(( > |{) > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$-(zx$a > ^1S > zX!<JR+joeIbZEYtIBvgBnl#LV4-NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g > | > z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp > zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b > z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg% > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz-khs!4b#@5QjP>U9%zLiUFG > ~av? > zeUJ9-Dv~3N$B!appHtL@3-IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q > 46kGa > zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y > E > zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm > ppAB< > zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+) > 7 > z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v > bV > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT-57V;K;+syy?R+C30w{q70#TZ1 > (Ev > zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V > @y@+N~R > zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I > zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k< > >s > z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ > G+U > zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U > S > zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q > HH0-&U > zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn > znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt > zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9 > _?krc > zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF% > zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(| > z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW > p_`g? > zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^ > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof} > z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^-- > zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x > `m > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA-cq+Wq%`jv > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i-+%|*Ny& > A > z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA > &6k{Fd > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5-JAQI7W$ > CZ<;` > zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S > OsN > zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj > mz-w > z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR > 7~ > z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3 > D{ > zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S > UN > zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs > mu > zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m; > Nu2W > z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk > V!}} > zz+g-u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC-xL=Y( > GRx > zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q > zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii > zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM > XGy > zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc > zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q > VM > z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU > zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E; > iUxRR > zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v > zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<-rUD)H9&S > f@E > zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn > >#iM > zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5 > wX% > zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@ > zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP > z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298} > 0gs > zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM- > rJhB% > z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k > zPBTLqcmk>G0PwmJ^W#xC-O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6 > 7AvC > zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=; > ?! > zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*% > J?t7L > zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D > K(~ > zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL > zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD > z*w1fD++$^@e$D7^UGJgf-rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3 > <D > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p-@)*^ > N(5Ei! > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$-P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu > ~ > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP-wj@j!4#6iMbDW)MruAkHCb1Nqxw > NM{ > z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb; > P_l#tb4g > z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57-^*tCzH+>d*z@3AV|%h%!1NOg+zH > >^N55 > zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h > E5}(1< > zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t > @BwZ > zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t > ag > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA-S)#DE > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe-+OTZJW>x%V > y > z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz! > Q? > zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW > VJ > zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT > @L_3c > zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq > w?L > zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw-G< > ~n& > zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC > {22 > zX-I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4 > dD% > z<YEj;4*V+0;|M-rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes > #~ > zqZrF<mFWvzkmFGC{3-LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d > G1& > z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v; > ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA > z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+ > z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd > ppY;|*f > zdVc@~A9~wr5$E1you*)8n4i?F--}{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l& > wBh > zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o > wnE > zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54 > +~m > ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R > Z> > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z-WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B& > MMf > z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)|2 > aiA > zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8 > ~=75zos > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g-QOrn > %{ > zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$ > Wvx > zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P > Q5^ > zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q > AJ(0a~# > zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D > O* > z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN > #0-* > z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD > NuPv > z8A&gM+yWoI3+p-Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm > Rd > z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki > No!Ys > zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S( > B7X}h > zVR;Et%eD@V5-g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3 > #N > zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}-8k0{FELICbyZM7w > lN > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{-JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb > iKo8 > z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV > hw$ > z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz > = > zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe > Mux8; > z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*; > =YK > zjl$=}dcQ-TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr > zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj > c > z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY > 3VqP > ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^ > b4_ > zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k > ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC > 6Q_? > zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{ > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;-zV}=Ffb;y0 > z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV > 9?w% > zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$ > `2Z9 > z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK > MQo > zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$ > #|)V;RX > zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@ > Ox5H > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD-VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{ > # > ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv > <E={9 > zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua > {h > z1c&pk*C&s-u!f*^mD<d?d91-{0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{ > 71|@f > zqyCdPYA>=Yf_ZfXdKIQ7K-BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS= > *8 > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz--=+yEpn0V;dyO#f3 > quY* > z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN > n#x > zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7) > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp->DBbJFmh > ~ > zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc > 359 > z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP > z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42 > R > z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR- > }t > zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E-c!f2kMR<>)RwV=hmWjbJxmB > OGSp> > z=zoS%q90`C_3r-1I|(vxy$L|<-~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53# > E3 > zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm-eR5re6n!d6@_6hyx( > I78k > zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY > Wssf9! > zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ > zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P- > %+f< > zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G` > zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd > j+el > zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G% > >t > zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@% > Il^r= > zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg > 6d?0S > zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c> > }u > zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh > +5 > ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V > bfpO > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W-!~C&zci > |? > z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT > h?j > zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4 > 8K^U > z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+ > 9a > zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM- > Wn > z9YL6MHz1*R`Ebg>i(85{!WP-zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M > $< > z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<? > zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk > zjcnO0FC<-zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP > c8Q1 > z>8<aHYtJ``M!kq=@76^J=2^>e*+-?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS > z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb- > KY > zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@) > {}ye > zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H > X$b5|#j > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee-d!ko~1?$I;0XQ0Lcy}V_T > M9HH > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M-xe{E>sl9(>CA<_JNmMi > xd > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP-t~(*7E<kqy26Hww<ma171sv > !t#Q > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X-XGl*%Q0ElH2aXP)|ASi9~aI8 > )Vn > zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;-*c4|rL<x*=v#r8 > zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$ > AaI > zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M > -hX > z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x > B > zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x > kdv8 > zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH > Z > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm > z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g-dTo#iWkSVwCW1XNNk>DTg > aD;g > zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF > WS_L$5 > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk-&zLAxDgQMl#h~ > l)AM; > z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm-$hEIpj?<LiYD}ov|o=<+m77@%`dhAH~ > ua > zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5 > zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf > }$y^xf > z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk-N;TT > N~tt > zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o > zQ-15yS^!}n-@U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M > Y69Y > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A-Rih9xWf6KdR0%$1u!qOps1C2Q# > ANP > z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u! > Dqgb3Ca > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86-gbBvpzX > R > z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5 > T > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj-hIrr3a)n*V>r6m=eJo=M3#L3_ > &Y > zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7 > z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^ > =n > zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ > IJm > z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9 > z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz > g5f7(M > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG-kU > G* > zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no > Oj > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)-2TC_XY^XyU+7`Q)it$=yI_HeO$| > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}-n<&rw6V{rKB|$Og > GoBpL > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf-;e_A#;c07yl@emICdlfx6?S > zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9-W > Pr4Do > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x-OHJh=>^ > %$z > zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf > R=j_i) > zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb-> > N#* > zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_ > zLs>gSMg&%IxgXVsk+G<1aLQyI;+-(x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p > 4d > z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a > O?%3UXP > zmxkemLOe-bD%O81OOdPv56yFNIJswr)-r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR > n > zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W > 5H`Q > zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=) > @EPJJ > z!!F00iIqj9<FImx<-TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu > Z > zA@6GBn_*`<fZu;fKyYcdsVz-LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb > JP > zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD > z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o > &q > zxj*LqEY-ZnACrceN-~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573 > zN&n5k9DfdGDn-n*utQW4V{X-IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP > Mq2Z > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4-Y(zEt0m3<zZQzZOBUz > lhe > z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i > ! > zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v= > 5E > zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2 > U3cy > zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL% > @Pb > zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W > T~0Y > zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f > 3EE > z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt< > {8Z-8 > zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE > m16 > z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4 > LVb1o > z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@ > x0z > z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn > ~4&d > zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu > G$}Tz > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ-Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@ > =?WW > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I-)fwRt3qD8qt( > { > z<P<KF=}PJ1#r#`jS-C-BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a > (X > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB-$@AJqDd(YoB@ZYfK6vP54O > =^o2 > z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN > g > zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(; > P > zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD > mu > z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF > {3 > zwPHdUsL_Emi-|sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx > tn > zbrc)1<0dX~X#twYtTp`&I-K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ > n > zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5 > +#Xc > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%-xVei > qO1Hf > z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU > <cW > zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c- > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?-up`F97 > _ > zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e > PVQj > z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT > z4)s@IGNTe?4-@J{iz-J0sXQl-t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P > U} > zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}& > jB > zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9 > XPvK > z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck > N > zH}9#C6|qJ(-~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb > 5c > zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx > C > z(-KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr > | > zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS > n)edp > zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh > 94r > z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk > Q; > zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS > z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B! > zLKgK@^uHSZLNEF1>n3-)R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP > T*O > z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL? > zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB> > 4f|! > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF-f1_RXCi@Ib*0 > z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4 > 8XtM > z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi > Vn > zP5ZAFYbCS1g7-`&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G > uEt > zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N > Vpdll > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a-3`@t)z}?8R=?u@$Rw&yc>*^x > zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{ > %xn > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0 > zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5 > B > zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm > 5jhv7qJ6 > zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs > G&n > zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc > X7Yw > zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*-s7 > b^ > zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR-qjhh > O > zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)| > CS > z^GD&-H%jsm7i~c(IDGo_-?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y > w > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h-%XTOuIK%jeRlC4YOaKdYsipAm+ > WrxJ > z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_ > emtz| > zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alVq > N6 > zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ > 9VH > zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td > R > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm-z5jm=aFjj$na3>$mvN|33HD3iFuOn0 > va3 > z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k > zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic > ; > zO)ScHYd^W4>p1IZF-rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I > nuw > zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq > ~p!H > zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR > z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH > @xAy1o > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;-FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb-d5Kj>373=4;|gla3^9<xGWqY!YN > zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF > ^ > z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe > z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)% > 6TeU > zDai3Q)sDP}fd8!F4@GgYGt3O#w-T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=& > !# > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ > zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A> > JLS > zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B > ^2@xF > zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo-1( > TU>k > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q-I>Wsn^_=%oN0?9m<2++S;$}<NQ > !2w > z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y > @4wr+ > z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW > igCND > zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G > f > zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM > +HRe > zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7> > za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!-N| > - > z;QcJ-_4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2 > Vq6r2 > zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y( > z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X > ^ > zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL > z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o > @ew > zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij% > 2fn_q4 > zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`> > =! > z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw% > <b > zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d > {;+cG) > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z-9KqzX4ywpKgSlL&Lplu > #f5K > zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN > Be > zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb > `1J > zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6 > h9# > z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW > Ts > z@juu7-1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS > pa} > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;-DANP > e- > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O-5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5 > 6 > z4%Obc4bQ}m#H`ZWui1dCf-8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q > a > zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K> > Mz > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4-gIH0R$|yhL0%iyEWP) > -dMFq > zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4; > zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(-# > w5 > zSQe21-iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH > zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=- > h3 > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#-u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6 > zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V > B > z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C-NcZPpT3FT+YGkGFM > 6L6 > zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3> > 49;t > z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@ > ZoU > z1o^bK^-i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e > <06 > zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23 > |; > zI-8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0 > p%hX > z-z&;-5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{ > O2 > zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(* > znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf > zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL > mu > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt-)j9cW`J=^32#Q > _0v= > zYuS>-!$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4 > T3 > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d-y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%( > U > z6;SpLK}$lNH+Qlh-cKR-YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>& > oV-UQQh > zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U( > c{ > zfIZlR!@-s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld* > zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e< > WpJJ > z-`$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ > N;@<uUxT > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@-auQ<`tj > RFOs > z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A > m > zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A > G > zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB > e+D$Sx > zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-| > z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7< > K > zTOHkDcgdOyfsEiOu%WtEi(>#Z-~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY > u| > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG-KacrZ > _ > zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG> > N9F > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U-w88FH|Vp0NA28vf|sjS > i! > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt-fK$0VNHs&Mk>^C1D > zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce > z$GM4 > zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV? > ?+@e > zg`wK!-l8aDa_m35OpOA{bq~|+%F-ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ > { > zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY > zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE > f!T< > z2ci!iV-wM?Bu7s^Huqb-4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C > Ct6d4 > z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p; > %j) > z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%-(2Z`Wl > @e > zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1 > Smv > z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE > TIA > zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH-#T > #5p > z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS-W4+WUsh43&>4RG*{QQ#GI!w > phN<ut > z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O! > 8 > z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC > li > zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF > no2|(R > zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS > 4D; > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R-Jpx~r9!pm?4kz;k|ao%zB@5Hbe > < > z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV > $~Mw0 > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM-j_UaA > x<g; > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu-o$d)MnXpluW?a_({zl > g > zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^ > Nsh > zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^ > H> > z@#^-Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5# > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd-Ge_d>@ > =& > zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK< > zN_8RoATaW}d{5!m3i1gyT+$O()xZN-q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n > z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8` > AC$53 > zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d > 7^x3lQL > zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t > ^ > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n-;m<n!p%lxe5r| > zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD) > S* > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8-9ip&dZ > 5@B > z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja > zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D > @Lj > zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_` > ?(Q=eq > zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su > ! > zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n` > lly-i > z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77-?_ > D > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=-#ZF|U1if%4r0!Fqa4AKSYGr=Bp4 > wS;j > zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f > B > zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w > SvXa > zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg > @KJ > zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL` > =` > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q-|Gt8<U$^Rmw`&o%H;FN+S+(N > H@-}E > z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx > qT > z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ& > z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7 > v#qf > z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp* > M& > z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf > zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!% > R0i > z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C > m*DkC > zHs9kcukmSQnY-`;FsIMBQNgVP-Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd > 6 > zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU > 7F@} > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI-W354EXdcSk^K;5aK > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)-a48PghrZ+3AO}YN > &bdTo > ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk > ce > zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c; > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO-KB7MVoi > X`~8> > z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E > h > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe-jybQSioRnO > 6 > zpm;JeMEQciVCPbow+)K59-z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs > X$9 > zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps > 19 > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM-V3W7dJ0WrB4 > !!+0k > z;zYZk1x)Y5=+Q4I`1dZe_-J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~ > h > zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY > ^|^o > zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY > w > z8&-yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_ > Pl}l > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn-cjsU7u?E8Rr%=Go&yh&47sj4 > @fk~gw > zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz; > Vn > z-7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH- > #bB > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W-7Me#XrQ^Tzt>kfFu8R(s > Yw > zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi > G > z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=| > B > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU-`l%kXo|H)KHVD6KW > h*Rz > zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx= > &< > zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT > zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr > 1> > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx-gL}d<c_Mn^@%_FE+g > ?M > zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB > m<8{ > zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB > rHu > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB-gw(`|azE*a<_S1weMZAOo%w(L > )Kl > z-dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_ > 3&$$E$ > z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3-B{ > GV > zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s > z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d > N > zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f > E# > ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l > 27AMD > z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql > amYM > zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE? > zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7 > W<MJ > z%-SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH > R8=T > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo-@a)b+Ml`1F<g{$T*e1di)$*fQ5m > |)PQDO > ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8> > ;g4 > zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA-k%PLdC*dz > w1? > z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c< > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G-H!u*oMbA8 > 4$ > zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q| > z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd > WSp > z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK > !+9 > zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq% > zw_MRqd{G)1`B`l*-mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~ > zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6-9?bOShFo2W$of{J{ > gHl > zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y > $TzS4WWp > z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_} > zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7# > T9bz > zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r; > 7VlOw; > z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g; > zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@ > ~Q`G > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s-2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v > z8QwfoitD*@-5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j > ~x > zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o > }${B{GLO@ > z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO > > > zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@( > W > z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r# > JmFX > zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0 > TYK > z-`2+H1Yr#7j9>-Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M > $i > zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@} > 8Q- > zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB > {d;Z$ > z>%q~GMLth%$)7kc<>-;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX > =3xm > zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2 > eba=c > zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn > vLvp4* > zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mMJ > XCoBHnW > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1 > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f > zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO-2 > |a}K?r > zFo(mo@$6w!RCO;!k{m2{z-_`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C > _9 > ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u > G8 > z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o| > p > z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK > pU > zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`-GBdrly&WQ1*?kDL@ > pG<V! > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3-JyC<keh(WCoDi(@n0xqm`@&*0R>; > SVa > zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?-i$S > ) > z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#-5>lJ2jXZ|?d~C= > n*V > zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR > 6na4 > zw-T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L > i > zajQH#9E-re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L > 675^ > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T-5)vkqIFntDZMA1VMOHjx#|# > gp > z<=jzFhYH`U9&O8-fDan`-Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ > s9 > z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+ > B< > zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(-AS > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W-JCA@y|<k2?s=otq > kXs > zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf% > 6 > ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg > V> > z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}- > zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP > e+{ > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b-LbUdRv*H4Cj>iO=b6AU_W > kt_g > zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><} > &(L > ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~ > zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCAI > uWDE > z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy > WSRlcK > zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL > =h8r > z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L > M^W > z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7? > _YY > zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf( > zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W > u$Jn > zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j > Uyi# > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1-7wk8y&7D+XUbG > qc > zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{ > B? > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR-`ynB}GDY7)z8WdiaOz1? > $ > z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2 > w_fKH^bO > zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C> > r > z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Yb > }g > zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi > zXl`9?-$MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29 > @(BH > zQPs%IT;9S({?mP*=Qnc|D5J-|w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf= > c > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4-F^%90(P&<beWqvDXsg0?i > WV^Yr > zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz > m*iO > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv-0T#hDV!d > ^^pp > zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{ > zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I; > zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu > G > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da-R)wUYvP#%R8D{%W4M3=p@E&YpC5Y > <^3Ym > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%-wXl_NyC`0qB > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr-wIc*7P > U)!KE > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek-a?2dg6PVM6GVX~3`oj > %%M; > z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je > zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i > z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`> > g > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T-2DeQ#fI > 0ra > zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90% > U2ISK > z7k~rD4m&7xFAX&{$U-)37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA > m&$g3 > z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;-d#*zW#Tye9hV)P&G*REZ2he+xK461i > S > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+-@izT8*fdO5W<a > <>h= > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O-U`a;Yy~M(7 > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0-*)&Q!XszxM?Zk > c > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>-Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s > z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB > ^ > z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y > mQ9 > z7-54~(UFH?f-J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V > zmVbN(^|1#(h+-lD+oK-PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W > b > zObewKL-P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E > ~AL > zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ > mE} > zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS > Ar > zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{ > eM#TotF > zf2^1WUw|=jGZ{M_KC6YOEM6I@-R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ> > -!8~ > zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G > w > z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ > vh0 > z2yd+qIez;p={X=o?0-^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F > 9F > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi-7AsygbO%g|<oo| > F > zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7 > mcGpsI > zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z > eLf}n > z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_ > V58p > z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE; > _G > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?-MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC > uL| > zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y > 7 > z*L9AUT{ijtMS0dcKOCKHpr-+xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR > p+ > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi-eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS > Q!<O& > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r-sKrwU > sCLRyE > z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1 > shL > zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U > e@ > zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r > za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp` > zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4 > +q > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D-B$kndG=Y6ir}mBr@$2Y+D1hg2` > HSFo?UV4 > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs-U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73 > t+H6 > z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W > 0@Pm_Y > zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j) > zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK > zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3 > z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P > z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH > z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t > $g7Mc > z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw > g4XT > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2-&x>7Mi3KPo##3Vi5A!D > ~zVd > zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ > )g}U > zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo > aKg > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y-AD^;!g > x| > z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3 > R > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V-O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v > OZ > z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz- > DH > z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52 > m? > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET-fIoOZ<f~u > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol-KEmeMx`wo+msu_i=!gCUc5 > aAFo > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o-UlMiBIpwFoxSL(w@3J7A9556*;P>na > q(Up` > z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7 > zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr > zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5 > k7 > zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i > ?0^U > zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C > zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq > $ > zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm` > `jz` > zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr > T%2I > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69-HYb > z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9 > zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh* > !tsx > zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C > z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD > & > zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X > @*1fT > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr-G6WS1r9|13yh@ > Y{v > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6-{$zk^x|sZJl > O+j > zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x > LE}S > zE-yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9` > UBK8 > zQ#_-WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s > HLzP7 > zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om* > TH > zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&= > w*FLg > zsI<EKP=R6SqF-IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D > k*l > z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt > gvZ`h > zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW? > MMr > zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j% > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u-_fVYHP%QJS6G+)Vr9%12 > >J > z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw > Mk8(V > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)-?sMK$L?>Ng)`3v > `R > z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl > NJlM > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi-f1#Bw(VP<qeg{%cT1IJ97@nLSx > z_X-ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4 > 5 > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4-kyiVyjuy47$ > @| > z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk > q6<X@ > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu-b=1;<A1a(HF7 > `i > z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y-< > @ > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb-%NnQFS!>!e+)H<J7 > % > z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq > )L > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh-@%MC4@d > 0h&s<FN > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V-_M01I| > m8wTMI > zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld > (#T` > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK-OFjWJG?jVvSoZ_a6 > jbw > zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa > qQ > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX-B8hJF!+PDU)2Ng~^@q8b > e+U > zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk > zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo > zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L > cp > zKSVWp#RY$Lhkns{H6-Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x > d} > zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f > zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*-i8 > r$$4 > zZOqr7#;sW-rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_; > 4Fzt > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob-K5PWDTzJUeq*If}X<4`_2c(`X*0 > z6;L!+h$=hX6x?t-Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY > <t#vw; > z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG > zsy > z&r3>eq@*BKMfN&W*>mt#-zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d > 4t+{ > zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf > is > ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U; > ?2 > zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv > *TAdi > zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS > zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I > zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l > hv > z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK > z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K > B(|Tz > z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+ > XbfG > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^-;pwarlq8+@E8O5*D1MF > F1&w > zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud > zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA > ^H > z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv > jX2 > RBat2OV|2<CTVmi8`9DHIo&o>> > > literal 0 > HcmV?d00001 > > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py > b/BaseTools/Source/Python/FMMT/PI/Common.py > new file mode 100644 > index 000000000000..efab874ee08b > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py > @@ -0,0 +1,81 @@ > +## @file > +# This file is used to define the common C struct and functions. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from ctypes import * > +import uuid > + > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}') > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = > uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}') > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = > uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}') > +# EFI_FFS_VOLUME_TOP_FILE_GUID = > uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}') > + > +EFI_FIRMWARE_FILE_SYSTEM2_GUID = > uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes > +EFI_FIRMWARE_FILE_SYSTEM3_GUID = > uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a' > +EFI_SYSTEM_NVDATA_FV_GUID = > uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50") > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE = > b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP" > +EFI_FFS_VOLUME_TOP_FILE_GUID = > uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09") > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = > b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t' > +ZEROVECTOR_BYTE = > b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff") > +FVH_SIGNATURE = b'_FVH' > + > +class GUID(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Guid1', c_uint32), > + ('Guid2', c_uint16), > + ('Guid3', c_uint16), > + ('Guid4', ARRAY(c_uint8, 8)), > + ] > + > + def from_list(self, listformat: list) -> None: > + self.Guid1 = listformat[0] > + self.Guid2 = listformat[1] > + self.Guid3 = listformat[2] > + for i in range(8): > + self.Guid4[i] = listformat[i+3] > + > + def __cmp__(self, otherguid) -> bool: > + if not isinstance(otherguid, GUID): > + return 'Input is not the GUID instance!' > + rt = False > + if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2 > and self.Guid3 == otherguid.Guid3: > + rt = True > + for i in range(8): > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i]) > + return rt > + > +def ModifyGuidFormat(target_guid: str) -> GUID: > + target_guid = target_guid.replace('-', '') > + target_list = [] > + start = [0,8,12,16,18,20,22,24,26,28,30] > + end = [8,12,16,18,20,22,24,26,28,30,32] > + num = len(start) > + for pos in range(num): > + new_value = int(target_guid[start[pos]:end[pos]], 16) > + target_list.append(new_value) > + new_format = GUID() > + new_format.from_list(target_list) > + return new_format > + > + > +# Get data from ctypes to bytes. > +def struct2stream(s) -> bytes: > + length = sizeof(s) > + p = cast(pointer(s), POINTER(c_char * length)) > + return p.contents.raw > + > + > + > +def GetPadSize(Size: int, alignment: int) -> int: > + if Size % alignment == 0: > + return 0 > + Pad_Size = alignment - Size % alignment > + return Pad_Size > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > new file mode 100644 > index 000000000000..33c49ffb50bc > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > @@ -0,0 +1,66 @@ > +## @file > +# This file is used to define the Ffs Header C Struct. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from struct import * > +from ctypes import * > +from PI.Common import * > + > +EFI_FFS_FILE_HEADER_LEN = 24 > +EFI_FFS_FILE_HEADER2_LEN = 32 > + > +class CHECK_SUM(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Header', c_uint8), > + ('File', c_uint8), > + ] > + > +class EFI_FFS_INTEGRITY_CHECK(Union): > + _pack_ = 1 > + _fields_ = [ > + ('Checksum', CHECK_SUM), > + ('Checksum16', c_uint16), > + ] > + > + > +class EFI_FFS_FILE_HEADER(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Name', GUID), > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > + ('Type', c_uint8), > + ('Attributes', c_uint8), > + ('Size', ARRAY(c_uint8, 3)), > + ('State', c_uint8), > + ] > + > + @property > + def FFS_FILE_SIZE(self) -> int: > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > + > + @property > + def HeaderLength(self) -> int: > + return 24 > + > +class EFI_FFS_FILE_HEADER2(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Name', GUID), > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > + ('Type', c_uint8), > + ('Attributes', c_uint8), > + ('Size', ARRAY(c_uint8, 3)), > + ('State', c_uint8), > + ('ExtendedSize', c_uint64), > + ] > + > + @property > + def FFS_FILE_SIZE(self) -> int: > + return self.ExtendedSize > + > + @property > + def HeaderLength(self) -> int: > + return 32 > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py > b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > new file mode 100644 > index 000000000000..aae2feae844a > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > @@ -0,0 +1,112 @@ > +## @file > +# This file is used to define the FV Header C Struct. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from ast import Str > +from struct import * > +from ctypes import * > +from PI.Common import * > + > +class EFI_FV_BLOCK_MAP_ENTRY(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('NumBlocks', c_uint32), > + ('Length', c_uint32), > + ] > + > + > +class EFI_FIRMWARE_VOLUME_HEADER(Structure): > + _fields_ = [ > + ('ZeroVector', ARRAY(c_uint8, 16)), > + ('FileSystemGuid', GUID), > + ('FvLength', c_uint64), > + ('Signature', c_uint32), > + ('Attributes', c_uint32), > + ('HeaderLength', c_uint16), > + ('Checksum', c_uint16), > + ('ExtHeaderOffset', c_uint16), > + ('Reserved', c_uint8), > + ('Revision', c_uint8), > + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, > 1)), > + ] > + > +def Refine_FV_Header(nums): > + class EFI_FIRMWARE_VOLUME_HEADER(Structure): > + _fields_ = [ > + ('ZeroVector', ARRAY(c_uint8, 16)), > + ('FileSystemGuid', GUID), > + ('FvLength', c_uint64), > + ('Signature', c_uint32), > + ('Attributes', c_uint32), > + ('HeaderLength', c_uint16), > + ('Checksum', c_uint16), > + ('ExtHeaderOffset', c_uint16), > + ('Reserved', c_uint8), > + ('Revision', c_uint8), > + ('BlockMap', > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)), > + ] > + return EFI_FIRMWARE_VOLUME_HEADER > + > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): > + _fields_ = [ > + ('FvName', GUID), > + ('ExtHeaderSize', c_uint32) > + ] > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure): > + _fields_ = [ > + ('ExtEntrySize', c_uint16), > + ('ExtEntryType', c_uint16) > + ] > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('TypeMask', c_uint32) > + ] > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('TypeMask', c_uint32), > + ('Types', ARRAY(GUID, 1)) > + ] > + > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE: > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('TypeMask', c_uint32), > + ('Types', ARRAY(GUID, nums)) > + ] > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure) > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('FormatType', GUID) > + ] > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('FormatType', GUID), > + ('Data', ARRAY(c_uint8, 1)) > + ] > + > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE: > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('FormatType', GUID), > + ('Data', ARRAY(c_uint8, nums)) > + ] > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure) > + > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure): > + _fields_ = [ > + ('Hdr', > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > + ('UsedSize', c_uint32) > + ] > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > new file mode 100644 > index 000000000000..c2cc8e0172fb > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > @@ -0,0 +1,110 @@ > +## @file > +# This file is used to define the Section Header C Struct. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from struct import * > +from ctypes import * > +from PI.Common import * > + > +EFI_COMMON_SECTION_HEADER_LEN = 4 > +EFI_COMMON_SECTION_HEADER2_LEN = 8 > + > +class EFI_COMMON_SECTION_HEADER(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Size', ARRAY(c_uint8, 3)), > + ('Type', c_uint8), > + ] > + > + @property > + def SECTION_SIZE(self) -> int: > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > + > + def Common_Header_Size(self) -> int: > + return 4 > + > +class EFI_COMMON_SECTION_HEADER2(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('Size', ARRAY(c_uint8, 3)), > + ('Type', c_uint8), > + ('ExtendedSize', c_uint32), > + ] > + > + @property > + def SECTION_SIZE(self) -> int: > + return self.ExtendedSize > + > + def Common_Header_Size(self) -> int: > + return 8 > + > +class EFI_COMPRESSION_SECTION(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('UncompressedLength', c_uint32), > + ('CompressionType', c_uint8), > + ] > + > + def ExtHeaderSize(self) -> int: > + return 5 > + > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('SubTypeGuid', GUID), > + ] > + > + def ExtHeaderSize(self) -> int: > + return 16 > + > +class EFI_GUID_DEFINED_SECTION(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('SectionDefinitionGuid', GUID), > + ('DataOffset', c_uint16), > + ('Attributes', c_uint16), > + ] > + > + def ExtHeaderSize(self) -> int: > + return 20 > + > +def Get_USER_INTERFACE_Header(nums: int): > + class EFI_SECTION_USER_INTERFACE(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('FileNameString', ARRAY(c_uint16, nums)), > + ] > + > + def ExtHeaderSize(self) -> int: > + return 2 * nums > + > + def GetUiString(self) -> str: > + UiString = '' > + for i in range(nums): > + if self.FileNameString[i]: > + UiString += chr(self.FileNameString[i]) > + return UiString > + > + return EFI_SECTION_USER_INTERFACE > + > +def Get_VERSION_Header(nums: int): > + class EFI_SECTION_VERSION(Structure): > + _pack_ = 1 > + _fields_ = [ > + ('BuildNumber', c_uint16), > + ('VersionString', ARRAY(c_uint16, nums)), > + ] > + > + def ExtHeaderSize(self) -> int: > + return 2 * (nums+1) > + > + def GetVersionString(self) -> str: > + VersionString = '' > + for i in range(nums): > + if self.VersionString[i]: > + VersionString += chr(self.VersionString[i]) > + return VersionString > + > + return EFI_SECTION_VERSION > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py > b/BaseTools/Source/Python/FMMT/PI/__init__.py > new file mode 100644 > index 000000000000..4e8296fad1ba > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py > @@ -0,0 +1,6 @@ > +## @file > +# This file is used to define the FMMT dependent external tool management > class. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/README.md > b/BaseTools/Source/Python/FMMT/README.md > new file mode 100644 > index 000000000000..e14dfa34ea66 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/README.md > @@ -0,0 +1,180 @@ > +# FMMT > +## Overview > +This FMMT tool is the python implementation of the edk2 FMMT tool which > locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt. > +This implementation has the same usage as the edk2 FMMT, but it's more > readable and relaiable. > + > +# FMMT User Guide > + > +#### Last updated October 13, 2021 > + > +Important Changes and Updates: > + > +- Oct 13, 2021 Initial Draft of FMMT Python Tool > + > +#### Note: > + > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is > much easier to maintain and extend other functions. > + > + > + > +# 1. Introduction > + > +## 1.1 Overview > + > +The Firmware Device is a persistent physical repository that contains > firmware code and/or data. The firmware code and/or data stored in > Firmware Volumes. Detail layout of Firmware Volumes is described in ?Figure > 1. The Firmware Volume Format?. > + > +![](Img/FirmwareVolumeFormat.png) > + > +<center>Figure 1. The Firmware Volume Format</center> > + > +In firmware development, binary file has its firmware layout following the > Platform-Initialization Specification. Thus, operation on FV file / FFS file > (Firmware File) is an efficient and convenient way for firmware function > testing and developing. FMMT Python tool is used for firmware files > operation. > + > +## 1.2 Tool Capabilities > + > +The FMMT tool is capable of: > + > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware > Files) > + > +- Add a new FFS into a FV file (both included in a FD file or not) > + > +- Replace an FFS in a FV file with a new FFS file > + > +- Delete an FFS in a FV file (both included in a FD file or not) > + > +- Extract the FFS from a FV file (both includ-v < Inputfile > < Outputfile >ed > in a FD file or not) > + > +## 1.3 References > + > +| Document | > +| ------------------------------------------------ | > +| UEFI Platform Initialization (PI) Specification | > + > + > + > +# 2. FMMT Python Tool Usage > + > +## 2.1 Required Files > + > +### 2.1.1 Independent use > + > +When independent use the FMMT Python Tool, the following files and > settings are required: > + > +- GuidTool executable files used for Decompress/Compress Firmware data. > + > +- Environment variables path with GuidTool path setting. > + > +### 2.1.2 Use with Build System > + > +When use the FMMT Python Tool with Build System: > + > +- If only use Edk2 based GuidTool, do not need other preparation. > + > +- If use other customized GuidTool, need prepare the config file with GuidTool > info. The syntax for GuidTool definition shown as follow: > + > + ***ToolsGuid ShortName Command*** > + > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI > BrotliCompress*** > + > +## 2.2 Syntax > + > +### 2.2.1 Syntax for Parse file > + > +***-v < Inputfile > < Outputfile > -l < LogFileType >*** > + > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is > optional, if inputs, the *Inputfile* will be encapsulated into *Outputfile* > following the parsed firmware layout. *"-l LogFileType"* is optional, it decides > the format of log file which saves Binary layout. Currently supports: json, txt. > More formats will be added in the future. > + > +### 2.2.2 Syntax for Add a new FFS > + > +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < > Outputfile >*** > + > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* > (Name or Guid) is the TargetFv which *NewFfsFile* will be added into. > + > +### 2.2.3 Syntax for Delete an FFS > + > +***-d < Inputfile > < TargetFfsName > < Outputfile > < > TargetFvName/TargetFvGuid >*** > + > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs > which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is the > parent of TargetFfs*.* > + > +### 2.2.4 Syntax for Replace an FFS > + > +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < > TargetFvName/TargetFvGuid >*** > + > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs > which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is > the parent of TargetFfs*.* > + > +### 2.2.5 Syntax for Extract an FFS > + > +***-e < Inputfile > < TargetFfsName > < Outputfile >*** > + > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs > which will be extracted. > + > + > + > +# 3. FMMT Python Tool Design > + > +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each > Node have its Data field, which saves the > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the > parse/add/delete/replace/extract operations are based on the NodeTree > (adjusting the layout and data). > + > +## 3.1 NodeTree > + > +A whole NodeTree saves all the Firmware info. > + > +- Parent & Child relationship figured out the Firmware layout. > + > +- Each Node have several fields. ?Data? field saves an FirmwareClass > instance which contains all the data info of the info. > + > +### 3.1.1 NodeTree Format > + > +The NodeTree will be created with parse function. When parse a file, a Root > Node will be initialized firstly. The Data split and Tree construction process is > described with an FD file shown as ?Figure 2. The NodeTree format?: > + > +- A Root Node is initialized. > + > +- Use the ?FV Signature? as FV key to split Whole FD > Data. ?FV0?, ?FV1?, ?FV2?? Node created. > + > +- After FV level Node created, use the ?Ffs Data Size? as FFS key to split each > FV Data. ?Ffs0?...Node created. > + > +- After FFS level Node created, use the ?Section Data Size? as Section key to > split each Ffs Data. ?Section0?...Node created. > + > +- If some of Section includes other Sections, continue use the ?Section Data > Size? as Section key to split each Section Data. > + > +- After all Node created, the whole NodeTree saves all the info. (Can be used > in other functions or print the whole firmware layout into log file) > + > +![](Img/NodeTreeFormat.png) > + > +<center>Figure 2. The NodeTree format</center> > + > +### 3.1.2 Node Factory and Product > + > +As 3.1.1, Each Node is created by data split and recognition. To extend the > NodeTree usage, Factory pattern is used in Node created process. > + > +Each Node have its Factory to create Product and use Product ParserData > function to deal with the data. > + > +## 3.2 GuidTool > + > +There are two ways to set the GuidTool. One from Config file, another from > environment variables. > + > +Current GuidTool first check if has Config file. > + > +- If have, load the config GuidTool Information. > + > +- Else get from environment variables. > + > +### 3.2.1 Get from Config file > + > +- Config file should in same folder with FMMT.py or the path in environment > variables. > + > +- Content should follow the format: > + > + ***ToolsGuid ShortName Command*** > + > +### 3.2.2 Get from Environment Variables > + > +- The GuidTool Command used must be set in environment variables. > + > +### 3.2.3 Edk2 Based GuidTool > + > +| ***Guid*** | ***ShortName*** > | ***Command*** | > +| ------------------------------------------ | --------------- | --------------------- | > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | > ***TianoCompress*** | > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | > ***LzmaCompress*** | > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | > ***GenCrc32*** | > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | > ***LzmaF86Compress*** | > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | > ***BrotliCompress*** | > diff --git a/BaseTools/Source/Python/FMMT/__init__.py > b/BaseTools/Source/Python/FMMT/__init__.py > new file mode 100644 > index 000000000000..e69de29bb2d1 > diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > new file mode 100644 > index 000000000000..33ffe73cab27 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > @@ -0,0 +1,371 @@ > +## @file > +# This file is used to implement of the various bianry parser. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from re import T > +import copy > +import os > +from PI.Common import * > +from core.BiosTreeNode import * > +from core.BiosTree import * > +from core.GuidTools import * > + > +ROOT_TREE = 'ROOT' > +ROOT_FV_TREE = 'ROOT_FV_TREE' > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > + > +FV_TREE = 'FV' > +DATA_FV_TREE = 'DATA_FV' > +FFS_TREE = 'FFS' > +FFS_PAD = 'FFS_PAD' > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > +SECTION_TREE = 'SECTION' > +SEC_FV_TREE = 'SEC_FV_IMAGE' > +BINARY_DATA = 'BINARY' > +Fv_count = 0 > + > +## Abstract factory > +class BinaryFactory(): > + type:list = [] > + > + def Create_Product(): > + pass > + > +class BinaryProduct(): > + ## Use GuidTool to decompress data. > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes: > + ParPath = > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. ") > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > + guidtool = > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > + DecompressedData = guidtool.unpack(Section_Data) > + return DecompressedData > + > + def ParserData(): > + pass > + > +class SectionFactory(BinaryFactory): > + type = [SECTION_TREE] > + > + def Create_Product(): > + return SectionProduct() > + > +class FfsFactory(BinaryFactory): > + type = [ROOT_SECTION_TREE, FFS_TREE] > + > + def Create_Product(): > + return FfsProduct() > + > +class FvFactory(BinaryFactory): > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE] > + > + def Create_Product(): > + return FvProduct() > + > +class FdFactory(BinaryFactory): > + type = [ROOT_FV_TREE, ROOT_TREE] > + > + def Create_Product(): > + return FdProduct() > + > +class SectionProduct(BinaryProduct): > + ## Decompress the compressed section. > + def ParserData(self, Section_Tree, whole_Data: bytes, > Rel_Whole_Offset: int=0) -> None: > + if Section_Tree.Data.Type == 0x01: > + Section_Tree.Data.OriData = Section_Tree.Data.Data > + self.ParserFfs(Section_Tree, b'') > + # Guided Define Section > + elif Section_Tree.Data.Type == 0x02: > + Section_Tree.Data.OriData = Section_Tree.Data.Data > + DeCompressGuidTool = > Section_Tree.Data.ExtHeader.SectionDefinitionGuid > + Section_Tree.Data.Data = > self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data) > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) + > Section_Tree.Data.HeaderLength > + self.ParserFfs(Section_Tree, b'') > + elif Section_Tree.Data.Type == 0x03: > + Section_Tree.Data.OriData = Section_Tree.Data.Data > + self.ParserFfs(Section_Tree, b'') > + # SEC_FV Section > + elif Section_Tree.Data.Type == 0x17: > + global Fv_count > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data) > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count)) > + Sec_Fv_Tree.type = SEC_FV_TREE > + Sec_Fv_Tree.Data = Sec_Fv_Info > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + > Sec_Fv_Tree.Data.Header.HeaderLength > + Sec_Fv_Tree.Data.Data = > Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:] > + Section_Tree.insertChild(Sec_Fv_Tree) > + Fv_count += 1 > + > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > int=0) -> None: > + Rel_Offset = 0 > + Section_Offset = 0 > + # Get the Data from parent tree, if do not have the tree then get it > from the whole_data. > + if ParTree.Data != None: > + Data_Size = len(ParTree.Data.Data) > + Section_Offset = ParTree.Data.DOffset > + Whole_Data = ParTree.Data.Data > + else: > + Data_Size = len(Whole_Data) > + # Parser all the data to collect all the Section recorded in its Parent > Section. > + while Rel_Offset < Data_Size: > + # Create a SectionNode and set it as the SectionTree's Data > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > + Section_Tree = BIOSTREE(Section_Info.Name) > + Section_Tree.type = SECTION_TREE > + Section_Info.Data = > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > Rel_Offset+Section_Info.Size] > + Section_Info.DOffset = Section_Offset + > Section_Info.HeaderLength + Rel_Whole_Offset > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset > + Section_Info.ROffset = Rel_Offset > + if Section_Info.Header.Type == 0: > + break > + # The final Section in parent Section does not need to add > padding, else must be 4-bytes align with parent Section start offset > + Pad_Size = 0 > + if > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size): > + Pad_Size = GetPadSize(Section_Info.Size, 4) > + Section_Info.PadData = Pad_Size * b'\x00' > + if Section_Info.Header.Type == 0x02: > + Section_Info.DOffset = Section_Offset + > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > + Section_Info.Data = > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > Rel_Offset+Section_Info.Size] > + if Section_Info.Header.Type == 0x14: > + ParTree.Data.Version = > Section_Info.ExtHeader.GetVersionString() > + if Section_Info.Header.Type == 0x15: > + ParTree.Data.UiName = > Section_Info.ExtHeader.GetUiString() > + Section_Offset += Section_Info.Size + Pad_Size > + Rel_Offset += Section_Info.Size + Pad_Size > + Section_Tree.Data = Section_Info > + ParTree.insertChild(Section_Tree) > + > +class FfsProduct(BinaryProduct): > + # ParserFFs / GetSection > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > int=0) -> None: > + Rel_Offset = 0 > + Section_Offset = 0 > + # Get the Data from parent tree, if do not have the tree then get it > from the whole_data. > + if ParTree.Data != None: > + Data_Size = len(ParTree.Data.Data) > + Section_Offset = ParTree.Data.DOffset > + Whole_Data = ParTree.Data.Data > + else: > + Data_Size = len(Whole_Data) > + # Parser all the data to collect all the Section recorded in Ffs. > + while Rel_Offset < Data_Size: > + # Create a SectionNode and set it as the SectionTree's Data > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > + Section_Tree = BIOSTREE(Section_Info.Name) > + Section_Tree.type = SECTION_TREE > + Section_Info.Data = > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > Rel_Offset+Section_Info.Size] > + Section_Info.DOffset = Section_Offset + > Section_Info.HeaderLength + Rel_Whole_Offset > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset > + Section_Info.ROffset = Rel_Offset > + if Section_Info.Header.Type == 0: > + break > + # The final Section in Ffs does not need to add padding, else > must be 4-bytes align with Ffs start offset > + Pad_Size = 0 > + if > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size): > + Pad_Size = GetPadSize(Section_Info.Size, 4) > + Section_Info.PadData = Pad_Size * b'\x00' > + if Section_Info.Header.Type == 0x02: > + Section_Info.DOffset = Section_Offset + > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > + Section_Info.Data = > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > Rel_Offset+Section_Info.Size] > + # If Section is Version or UI type, it saves the version and UI > info of its parent Ffs. > + if Section_Info.Header.Type == 0x14: > + ParTree.Data.Version = > Section_Info.ExtHeader.GetVersionString() > + if Section_Info.Header.Type == 0x15: > + ParTree.Data.UiName = > Section_Info.ExtHeader.GetUiString() > + Section_Offset += Section_Info.Size + Pad_Size > + Rel_Offset += Section_Info.Size + Pad_Size > + Section_Tree.Data = Section_Info > + ParTree.insertChild(Section_Tree) > + > +class FvProduct(BinaryProduct): > + ## ParserFv / GetFfs > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > int=0) -> None: > + Ffs_Offset = 0 > + Rel_Offset = 0 > + # Get the Data from parent tree, if do not have the tree then get it > from the whole_data. > + if ParTree.Data != None: > + Data_Size = len(ParTree.Data.Data) > + Ffs_Offset = ParTree.Data.DOffset > + Whole_Data = ParTree.Data.Data > + else: > + Data_Size = len(Whole_Data) > + # Parser all the data to collect all the Ffs recorded in Fv. > + while Rel_Offset < Data_Size: > + # Create a FfsNode and set it as the FFsTree's Data > + if Data_Size - Rel_Offset < 24: > + Ffs_Tree = BIOSTREE('Free_Space') > + Ffs_Tree.type = FFS_FREE_SPACE > + Ffs_Tree.Data = > FreeSpaceNode(Whole_Data[Rel_Offset:]) > + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset > + ParTree.Data.Free_Space = Data_Size - Rel_Offset > + ParTree.insertChild(Ffs_Tree) > + Rel_Offset = Data_Size > + else: > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:]) > + Ffs_Tree = BIOSTREE(Ffs_Info.Name) > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset > + Ffs_Info.DOffset = Ffs_Offset + > Ffs_Info.Header.HeaderLength + Rel_Whole_Offset > + Ffs_Info.ROffset = Rel_Offset > + if Ffs_Info.Name == PADVECTOR: > + Ffs_Tree.type = FFS_PAD > + Ffs_Info.Data = > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > Rel_Offset+Ffs_Info.Size] > + Ffs_Info.Size = len(Ffs_Info.Data) + > Ffs_Info.Header.HeaderLength > + # if current Ffs is the final ffs of Fv and full of b'\xff', > define it with Free_Space > + if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') > == b'': > + Ffs_Tree.type = FFS_FREE_SPACE > + Ffs_Info.Data = Whole_Data[Rel_Offset:] > + Ffs_Info.Size = len(Ffs_Info.Data) > + ParTree.Data.Free_Space = Ffs_Info.Size > + else: > + Ffs_Tree.type = FFS_TREE > + Ffs_Info.Data = > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > Rel_Offset+Ffs_Info.Size] > + # The final Ffs in Fv does not need to add padding, else > must be 8-bytes align with Fv start offset > + Pad_Size = 0 > + if Ffs_Tree.type != FFS_FREE_SPACE and > (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != Data_Size): > + Pad_Size = GetPadSize(Ffs_Info.Size, 8) > + Ffs_Info.PadData = Pad_Size * b'\xff' > + Ffs_Offset += Ffs_Info.Size + Pad_Size > + Rel_Offset += Ffs_Info.Size + Pad_Size > + Ffs_Tree.Data = Ffs_Info > + ParTree.insertChild(Ffs_Tree) > + > +class FdProduct(BinaryProduct): > + type = [ROOT_FV_TREE, ROOT_TREE] > + > + ## Create DataTree with first level /fv Info, then parser each Fv. > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0) -> > None: > + # Get all Fv image in Fd with offset and length > + Fd_Struct = self.GetFvFromFd(whole_data) > + data_size = len(whole_data) > + Binary_count = 0 > + global Fv_count > + # If the first Fv image is the Binary Fv, add it into the tree. > + if Fd_Struct[0][1] != 0: > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > + Binary_node.type = BINARY_DATA > + Binary_node.Data = BinaryNode(str(Binary_count)) > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]] > + Binary_node.Data.Size = len(Binary_node.Data.Data) > + Binary_node.Data.HOffset = 0 + offset > + WholeFvTree.insertChild(Binary_node) > + Binary_count += 1 > + # Add the first collected Fv image into the tree. > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count)) > + Cur_node.type = Fd_Struct[0][0] > + Cur_node.Data = FvNode(Fv_count, > whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]]) > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset > + Cur_node.Data.DOffset = > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > + Cur_node.Data.Data = > whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct > [0][1]+Cur_node.Data.Size] > + WholeFvTree.insertChild(Cur_node) > + Fv_count += 1 > + Fv_num = len(Fd_Struct) > + # Add all the collected Fv image and the Binary Fv image between > them into the tree. > + for i in range(Fv_num-1): > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]: > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > + Binary_node.type = BINARY_DATA > + Binary_node.Data = BinaryNode(str(Binary_count)) > + Binary_node.Data.Data = > whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]] > + Binary_node.Data.Size = len(Binary_node.Data.Data) > + Binary_node.Data.HOffset = > Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset > + WholeFvTree.insertChild(Binary_node) > + Binary_count += 1 > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count)) > + Cur_node.type = Fd_Struct[i+1][0] > + Cur_node.Data = FvNode(Fv_count, > whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]]) > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset > + Cur_node.Data.DOffset = > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > + Cur_node.Data.Data = > whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru > ct[i+1][1]+Cur_node.Data.Size] > + WholeFvTree.insertChild(Cur_node) > + Fv_count += 1 > + # If the final Fv image is the Binary Fv, add it into the tree > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size: > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > + Binary_node.type = BINARY_DATA > + Binary_node.Data = BinaryNode(str(Binary_count)) > + Binary_node.Data.Data = > whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:] > + Binary_node.Data.Size = len(Binary_node.Data.Data) > + Binary_node.Data.HOffset = > Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset > + WholeFvTree.insertChild(Binary_node) > + Binary_count += 1 > + > + ## Get the first level Fv from Fd file. > + def GetFvFromFd(self, whole_data: bytes=b'') -> list: > + Fd_Struct = [] > + data_size = len(whole_data) > + cur_index = 0 > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV > image offset and length. > + while cur_index < data_size: > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in > whole_data[cur_index:]: > + target_index = > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) + > cur_index > + if whole_data[target_index+24:target_index+28] == > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > ZEROVECTOR_BYTE: > + Fd_Struct.append([FV_TREE, target_index - 16, > unpack("Q", whole_data[target_index+16:target_index+24])]) > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > + else: > + cur_index = target_index + 16 > + else: > + cur_index = data_size > + cur_index = 0 > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV > image offset and length. > + while cur_index < data_size: > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in > whole_data[cur_index:]: > + target_index = > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) + > cur_index > + if whole_data[target_index+24:target_index+28] == > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > ZEROVECTOR_BYTE: > + Fd_Struct.append([FV_TREE, target_index - 16, > unpack("Q", whole_data[target_index+16:target_index+24])]) > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > + else: > + cur_index = target_index + 16 > + else: > + cur_index = data_size > + cur_index = 0 > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image > offset and length. > + while cur_index < data_size: > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in > whole_data[cur_index:]: > + target_index = > whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + > cur_index > + if whole_data[target_index+24:target_index+28] == > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > ZEROVECTOR_BYTE: > + Fd_Struct.append([DATA_FV_TREE, target_index - > 16, unpack("Q", whole_data[target_index+16:target_index+24])]) > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > + else: > + cur_index = target_index + 16 > + else: > + cur_index = data_size > + # Sort all the collect Fv image with offset. > + Fd_Struct.sort(key=lambda x:x[1]) > + tmp_struct = copy.deepcopy(Fd_Struct) > + tmp_index = 0 > + Fv_num = len(Fd_Struct) > + # Remove the Fv image included in another Fv image. > + for i in range(1,Fv_num): > + if tmp_struct[i][1]+tmp_struct[i][2][0] < > tmp_struct[i-1][1]+tmp_struct[i-1][2][0]: > + Fd_Struct.remove(Fd_Struct[i-tmp_index]) > + tmp_index += 1 > + return Fd_Struct > + > +class ParserEntry(): > + FactoryTable:dict = { > + SECTION_TREE: SectionFactory, > + ROOT_SECTION_TREE: FfsFactory, > + FFS_TREE: FfsFactory, > + ROOT_FFS_TREE: FvFactory, > + FV_TREE: FvFactory, > + SEC_FV_TREE: FvFactory, > + ROOT_FV_TREE: FdFactory, > + ROOT_TREE: FdFactory, > + } > + > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory: > + if Tree_type in self.FactoryTable: > + return self.FactoryTable[Tree_type] > + > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: > bytes, Offset: int) -> None: > + New_Product = TargetFactory.Create_Product() > + New_Product.ParserData(Tree, Data, Offset) > + > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None: > + TargetFactory = self.GetTargetFactory(Tree.type) > + if TargetFactory: > + self.Generate_Product(TargetFactory, Tree, Data, Offset) > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py > b/BaseTools/Source/Python/FMMT/core/BiosTree.py > new file mode 100644 > index 000000000000..0b6252ecc1bb > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py > @@ -0,0 +1,198 @@ > +## @file > +# This file is used to define the Bios layout tree structure and related > operations. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +import collections > +from PI.Common import * > + > +ROOT_TREE = 'ROOT' > +ROOT_FV_TREE = 'ROOT_FV_TREE' > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > + > +FV_TREE = 'FV' > +DATA_FV_TREE = 'DATA_FV' > +FFS_TREE = 'FFS' > +FFS_PAD = 'FFS_PAD' > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > +SECTION_TREE = 'SECTION' > +SEC_FV_TREE = 'SEC_FV_IMAGE' > +BINARY_DATA = 'BINARY' > + > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, > ROOT_SECTION_TREE] > +FvType = [FV_TREE, SEC_FV_TREE] > +FfsType = FFS_TREE > +SecType = SECTION_TREE > + > +class BIOSTREE: > + def __init__(self, NodeName: str) -> None: > + self.key = NodeName > + self.type = None > + self.Data = None > + self.Child = [] > + self.Findlist = [] > + self.Parent = None > + self.NextRel = None > + self.LastRel = None > + > + def HasChild(self) -> bool: > + if self.Child == []: > + return False > + else: > + return True > + > + def isFinalChild(self) -> bool: > + ParTree = self.Parent > + if ParTree: > + if ParTree.Child[-1] == self: > + return True > + return False > + > + # FvTree.insertChild() > + def insertChild(self, newNode, pos: int=None) -> None: > + if len(self.Child) == 0: > + self.Child.append(newNode) > + else: > + if not pos: > + LastTree = self.Child[-1] > + self.Child.append(newNode) > + LastTree.NextRel = newNode > + newNode.LastRel = LastTree > + else: > + newNode.NextRel = self.Child[pos-1].NextRel > + newNode.LastRel = self.Child[pos].LastRel > + self.Child[pos-1].NextRel = newNode > + self.Child[pos].LastRel = newNode > + self.Child.insert(pos, newNode) > + newNode.Parent = self > + > + # lastNode.insertRel(newNode) > + def insertRel(self, newNode) -> None: > + if self.Parent: > + parentTree = self.Parent > + new_index = parentTree.Child.index(self) + 1 > + parentTree.Child.insert(new_index, newNode) > + self.NextRel = newNode > + newNode.LastRel = self > + > + def deleteNode(self, deletekey: str) -> None: > + FindStatus, DeleteTree = self.FindNode(deletekey) > + if FindStatus: > + parentTree = DeleteTree.Parent > + lastTree = DeleteTree.LastRel > + nextTree = DeleteTree.NextRel > + if parentTree: > + index = parentTree.Child.index(DeleteTree) > + del parentTree.Child[index] > + if lastTree and nextTree: > + lastTree.NextRel = nextTree > + nextTree.LastRel = lastTree > + elif lastTree: > + lastTree.NextRel = None > + elif nextTree: > + nextTree.LastRel = None > + return DeleteTree > + else: > + print('Could not find the target tree') > + return None > + > + def FindNode(self, key: str, Findlist: list) -> None: > + if self.key == key or (self.Data and self.Data.Name == key) or > (self.type == FFS_TREE and self.Data.UiName == key): > + Findlist.append(self) > + else: > + for item in self.Child: > + item.FindNode(key, Findlist) > + > + def GetTreePath(self): > + BiosTreePath = [self] > + while self.Parent: > + BiosTreePath.insert(0, self.Parent) > + self = self.Parent > + return BiosTreePath > + > + def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0, > ParFvId="") -> None: > + Key = list(TargetDict.keys())[0] > + if TargetDict[Key]["Type"] in RootType: > + Info.append("Image File: {}".format(Key)) > + Info.append("FilesNum: > {}".format(TargetDict.get(Key).get('FilesNum'))) > + Info.append("\n") > + elif TargetDict[Key]["Type"] in FvType: > + space += 2 > + if TargetDict[Key]["Type"] == SEC_FV_TREE: > + Info.append("{}Child FV named {} of {}".format(space*" ", > Key, ParFvId)) > + space += 2 > + else: > + Info.append("FvId: {}".format(Key)) > + ParFvId = Key > + Info.append("{}FvNameGuid: {}".format(space*" ", > TargetDict.get(Key).get('FvNameGuid'))) > + Info.append("{}Attributes: {}".format(space*" ", > TargetDict.get(Key).get('Attributes'))) > + Info.append("{}Total Volume Size: {}".format(space*" ", > TargetDict.get(Key).get('Size'))) > + Info.append("{}Free Volume Size: {}".format(space*" ", > TargetDict.get(Key).get('FreeSize'))) > + Info.append("{}Volume Offset: {}".format(space*" ", > TargetDict.get(Key).get('Offset'))) > + Info.append("{}FilesNum: {}".format(space*" ", > TargetDict.get(Key).get('FilesNum'))) > + elif TargetDict[Key]["Type"] in FfsType: > + space += 2 > + if TargetDict.get(Key).get('UiName') != "b''": > + Info.append("{}File: {} / {}".format(space*" ", Key, > TargetDict.get(Key).get('UiName'))) > + else: > + Info.append("{}File: {}".format(space*" ", Key)) > + if "Files" in list(TargetDict[Key].keys()): > + for item in TargetDict[Key]["Files"]: > + self.parserTree(item, Info, space, ParFvId) > + > + def ExportTree(self,TreeInfo: dict=None) -> dict: > + if TreeInfo is None: > + TreeInfo =collections.OrderedDict() > + > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or > self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE: > + key = str(self.key) > + TreeInfo[self.key] = collections.OrderedDict() > + TreeInfo[self.key]["Name"] = key > + TreeInfo[self.key]["Type"] = self.type > + TreeInfo[self.key]["FilesNum"] = len(self.Child) > + elif self.type == FV_TREE or self.type == SEC_FV_TREE: > + key = str(self.Data.FvId) > + TreeInfo[key] = collections.OrderedDict() > + TreeInfo[key]["Name"] = key > + if self.Data.FvId != self.Data.Name: > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name) > + TreeInfo[key]["Type"] = self.type > + TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes) > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength) > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space) > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > + TreeInfo[key]["FilesNum"] = len(self.Child) > + elif self.type == FFS_TREE: > + key = str(self.Data.Name) > + TreeInfo[key] = collections.OrderedDict() > + TreeInfo[key]["Name"] = key > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName) > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version) > + TreeInfo[key]["Type"] = self.type > + TreeInfo[key]["Size"] = hex(self.Data.Size) > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > + TreeInfo[key]["FilesNum"] = len(self.Child) > + elif self.type == SECTION_TREE and self.Data.Type == 0x02: > + key = str(self.Data.Name) > + TreeInfo[key] = collections.OrderedDict() > + TreeInfo[key]["Name"] = key > + TreeInfo[key]["Type"] = self.type > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + > self.Data.HeaderLength) > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size) > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > + TreeInfo[key]["FilesNum"] = len(self.Child) > + elif self is not None: > + key = str(self.Data.Name) > + TreeInfo[key] = collections.OrderedDict() > + TreeInfo[key]["Name"] = key > + TreeInfo[key]["Type"] = self.type > + TreeInfo[key]["Size"] = hex(self.Data.Size) > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > + TreeInfo[key]["FilesNum"] = len(self.Child) > + > + for item in self.Child: > + TreeInfo[key].setdefault('Files',[]).append( item.ExportTree()) > + > + return TreeInfo > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > new file mode 100644 > index 000000000000..cfb711eea5a2 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > @@ -0,0 +1,191 @@ > +## @file > +# This file is used to define the BIOS Tree Node. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from PI.FvHeader import * > +from PI.FfsFileHeader import * > +from PI.SectionHeader import * > +from PI.Common import * > +import uuid > + > +SectionHeaderType = { > + 0x01:'EFI_COMPRESSION_SECTION', > + 0x02:'EFI_GUID_DEFINED_SECTION', > + 0x03:'EFI_SECTION_DISPOSABLE', > + 0x10:'EFI_SECTION_PE32', > + 0x11:'EFI_SECTION_PIC', > + 0x12:'EFI_SECTION_TE', > + 0x13:'EFI_SECTION_DXE_DEPEX', > + 0x14:'EFI_SECTION_VERSION', > + 0x15:'EFI_SECTION_USER_INTERFACE', > + 0x16:'EFI_SECTION_COMPATIBILITY16', > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION', > + 0x19:'EFI_SECTION_RAW', > + 0x1B:'EFI_SECTION_PEI_DEPEX', > + 0x1C:'EFI_SECTION_MM_DEPEX' > +} > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18] > + > +class BinaryNode: > + def __init__(self, name: str) -> None: > + self.Size = 0 > + self.Name = "BINARY" + str(name) > + self.HOffset = 0 > + self.Data = b'' > + > +class FvNode: > + def __init__(self, name, buffer: bytes) -> None: > + self.Header = > EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer) > + Map_num = (self.Header.HeaderLength - 56)//8 > + self.Header = > Refine_FV_Header(Map_num).from_buffer_copy(buffer) > + self.FvId = "FV" + str(name) > + self.Name = "FV" + str(name) > + if self.Header.ExtHeaderOffset: > + self.ExtHeader = > EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header > .ExtHeaderOffset:]) > + self.Name = > uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName)) > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20 > + if self.ExtHeader.ExtHeaderSize != 20: > + self.ExtEntryExist = 1 > + self.ExtEntry = > EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry > Offset:]) > + self.ExtTypeExist = 1 > + if self.ExtEntry.ExtEntryType == 0x01: > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16 > + self.ExtEntry = > Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[s > elf.ExtEntryOffset:]) > + elif self.ExtEntry.ExtEntryType == 0x02: > + nums = self.ExtEntry.ExtEntrySize - 20 > + self.ExtEntry = > Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[ > self.ExtEntryOffset:]) > + elif self.ExtEntry.ExtEntryType == 0x03: > + self.ExtEntry = > EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b > uffer[self.ExtEntryOffset:]) > + else: > + self.ExtTypeExist = 0 > + else: > + self.ExtEntryExist = 0 > + self.Size = self.Header.FvLength > + self.HeaderLength = self.Header.HeaderLength > + self.HOffset = 0 > + self.DOffset = 0 > + self.ROffset = 0 > + self.Data = b'' > + if self.Header.Signature != 1213613663: > + print('Invalid! Fv Header Signature {} is not > "_FVH".'.format(self.Header.Signature)) > + with open(str(self.Name)+'.fd', "wb") as f: > + f.write(struct2stream(self.Header)) > + assert False > + self.PadData = b'' > + self.Free_Space = 0 > + self.ModCheckSum() > + > + def ModCheckSum(self) -> None: > + # Fv Header Sums to 0. > + Header = struct2stream(self.Header)[::-1] > + Size = self.HeaderLength // 2 > + Sum = 0 > + for i in range(Size): > + Sum += int(Header[i*2: i*2 + 2].hex(), 16) > + if Sum & 0xffff: > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - > self.Header.Checksum)[-4:], 16)), 16) > + > + def ModFvExt(self) -> None: > + # If used space changes and self.ExtEntry.UsedSize exists, > self.ExtEntry.UsedSize need to be changed. > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and > self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03: > + self.ExtEntry.UsedSize = self.Header.FvLength - > self.Free_Space > + > + def ModFvSize(self) -> None: > + # If Fv Size changed, self.Header.FvLength and > self.Header.BlockMap[i].NumBlocks need to be changed. > + BlockMapNum = len(self.Header.BlockMap) > + for i in range(BlockMapNum): > + if self.Header.BlockMap[i].Length: > + self.Header.BlockMap[i].NumBlocks = > self.Header.FvLength // self.Header.BlockMap[i].Length > + > + def ModExtHeaderData(self) -> None: > + if self.Header.ExtHeaderOffset: > + ExtHeaderData = struct2stream(self.ExtHeader) > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset - > self.HeaderLength > + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData > + self.Data[ExtHeaderDataOffset+20:] > + if self.Header.ExtHeaderOffset and self.ExtEntryExist: > + ExtHeaderEntryData = struct2stream(self.ExtEntry) > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + > 20 - self.HeaderLength > + self.Data = self.Data[:ExtHeaderEntryDataOffset] + > ExtHeaderEntryData + > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):] > + > +class FfsNode: > + def __init__(self, buffer: bytes) -> None: > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer) > + # self.Attributes = unpack("<B", buffer[21:22])[0] > + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes != 0xff > and self.Header.Attributes & 0x01 == 1: > + print('Error Ffs Header! Ffs Header Size and Attributes is not > matched!') > + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes & > 0x01 == 1: > + self.Header = > EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer) > + self.Name = > uuid.UUID(bytes_le=struct2stream(self.Header.Name)) > + self.UiName = b'' > + self.Version = b'' > + self.Size = self.Header.FFS_FILE_SIZE > + self.HeaderLength = self.Header.HeaderLength > + self.HOffset = 0 > + self.DOffset = 0 > + self.ROffset = 0 > + self.Data = b'' > + self.PadData = b'' > + > + def ModCheckSum(self) -> None: > + HeaderData = struct2stream(self.Header) > + HeaderSum = 0 > + for item in HeaderData: > + HeaderSum += item > + HeaderSum -= self.Header.State > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File > + if HeaderSum & 0xff: > + Header = self.Header.IntegrityCheck.Checksum.Header + > 0x100 - int(hex(HeaderSum)[-2:], 16) > + self.Header.IntegrityCheck.Checksum.Header = > int(hex(Header)[-2:], 16) > + > +class SectionNode: > + def __init__(self, buffer: bytes) -> None: > + if buffer[0:3] != b'\xff\xff\xff': > + self.Header = > EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer) > + else: > + self.Header = > EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer) > + if self.Header.Type in SectionHeaderType: > + self.Name = SectionHeaderType[self.Header.Type] > + elif self.Header.Type == 0: > + self.Name = "EFI_SECTION_RAW" > + else: > + self.Name = "SECTION" > + if self.Header.Type in HeaderType: > + self.ExtHeader = self.GetExtHeader(self.Header.Type, > buffer[self.Header.Common_Header_Size():], > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size())) > + self.HeaderLength = self.Header.Common_Header_Size() + > self.ExtHeader.ExtHeaderSize() > + else: > + self.ExtHeader = None > + self.HeaderLength = self.Header.Common_Header_Size() > + self.Size = self.Header.SECTION_SIZE > + self.Type = self.Header.Type > + self.HOffset = 0 > + self.DOffset = 0 > + self.ROffset = 0 > + self.Data = b'' > + self.OriData = b'' > + self.OriHeader = b'' > + self.PadData = b'' > + > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None: > + if Type == 0x01: > + return > EFI_COMPRESSION_SECTION.from_buffer_copy(buffer) > + elif Type == 0x02: > + return > EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer) > + elif Type == 0x14: > + return Get_VERSION_Header((nums - > 2)//2).from_buffer_copy(buffer) > + elif Type == 0x15: > + return > Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer) > + elif Type == 0x18: > + return > EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer) > + > +class FreeSpaceNode: > + def __init__(self, buffer: bytes) -> None: > + self.Name = 'Free_Space' > + self.Data = buffer > + self.Size = len(buffer) > + self.HOffset = 0 > + self.DOffset = 0 > + self.ROffset = 0 > + self.PadData = b'' > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > new file mode 100644 > index 000000000000..a0432c4093cf > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > @@ -0,0 +1,140 @@ > +## @file > +# This file is used to define the functions to operate bios binary file. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from core.FMMTParser import * > +from core.FvHandler import * > +from utils.FvLayoutPrint import * > + > +global Fv_count > +Fv_count = 0 > + > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', > 'ROOT_SECTION_TREE' > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile: > str=None) -> None: > + # 1. Data Prepare > + with open(inputfile, "rb") as f: > + whole_data = f.read() > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE) > + # 2. DataTree Create > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > + # 3. Log Output > + InfoDict = FmmtParser.WholeFvTree.ExportTree() > + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo) > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo) > + if logfile: > + GetFormatter(logfile.lower()).dump(InfoDict, > FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile), > ".{}".format(logfile.lower()))) > + # 4. Data Encapsultion > + if outputfile: > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > + with open(outputfile, "wb") as f: > + f.write(FmmtParser.FinalData) > + > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: > str=None) -> None: > + # 1. Data Prepare > + with open(inputfile, "rb") as f: > + whole_data = f.read() > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > + # 2. DataTree Create > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > + # 3. Data Modify > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, > FmmtParser.WholeFvTree.Findlist) > + # Choose the Specfic DeleteFfs with Fv info > + if Fv_name: > + for item in FmmtParser.WholeFvTree.Findlist: > + if item.Parent.key != Fv_name and > item.Parent.Data.Name != Fv_name: > + FmmtParser.WholeFvTree.Findlist.remove(item) > + if FmmtParser.WholeFvTree.Findlist != []: > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: > + FfsMod = FvHandler(None, Delete_Ffs) > + Status = FfsMod.DeleteFfs() > + else: > + print('Target Ffs not found!!!') > + # 4. Data Encapsultion > + if Status: > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > + with open(outputfile, "wb") as f: > + f.write(FmmtParser.FinalData) > + > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> > None: > + # 1. Data Prepare > + with open(inputfile, "rb") as f: > + whole_data = f.read() > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > + # 2. DataTree Create > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > + # Get Target Fv and Target Ffs_Pad > + FmmtParser.WholeFvTree.FindNode(Fv_name, > FmmtParser.WholeFvTree.Findlist) > + # Create new ffs Tree > + with open(newffsfile, "rb") as f: > + new_ffs_data = f.read() > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE) > + Status = False > + # 3. Data Modify > + if FmmtParser.WholeFvTree.Findlist: > + for TargetFv in FmmtParser.WholeFvTree.Findlist: > + TargetFfsPad = TargetFv.Child[-1] > + if TargetFfsPad.type == FFS_FREE_SPACE: > + > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > new_ffs_data, TargetFfsPad.Data.HOffset) > + else: > + > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size) > + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], > TargetFfsPad) > + Status = FfsMod.AddFfs() > + else: > + print('Target Fv not found!!!') > + # 4. Data Encapsultion > + if Status: > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > + with open(outputfile, "wb") as f: > + f.write(FmmtParser.FinalData) > + > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, > Fv_name: str=None) -> None: > + # 1. Data Prepare > + with open(inputfile, "rb") as f: > + whole_data = f.read() > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > + # 2. DataTree Create > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > + with open(newffsfile, "rb") as f: > + new_ffs_data = f.read() > + newFmmtParser = FMMTParser(newffsfile, FV_TREE) > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, > new_ffs_data) > + Status = False > + # 3. Data Modify > + new_ffs = newFmmtParser.WholeFvTree.Child[0] > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff' > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > FmmtParser.WholeFvTree.Findlist) > + if Fv_name: > + for item in FmmtParser.WholeFvTree.Findlist: > + if item.Parent.key != Fv_name and > item.Parent.Data.Name != Fv_name: > + FmmtParser.WholeFvTree.Findlist.remove(item) > + if FmmtParser.WholeFvTree.Findlist != []: > + for TargetFfs in FmmtParser.WholeFvTree.Findlist: > + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], > TargetFfs) > + Status = FfsMod.ReplaceFfs() > + else: > + print('Target Ffs not found!!!') > + # 4. Data Encapsultion > + if Status: > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > + with open(outputfile, "wb") as f: > + f.write(FmmtParser.FinalData) > + > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None: > + with open(inputfile, "rb") as f: > + whole_data = f.read() > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > FmmtParser.WholeFvTree.Findlist) > + if FmmtParser.WholeFvTree.Findlist != []: > + TargetNode = FmmtParser.WholeFvTree.Findlist[0] > + TargetFv = TargetNode.Parent > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: > + TargetNode.Data.Header.State = c_uint8( > + ~TargetNode.Data.Header.State) > + FinalData = struct2stream(TargetNode.Data.Header) + > TargetNode.Data.Data > + with open(outputfile, "wb") as f: > + f.write(FinalData) > + else: > + print('Target Ffs not found!!!') > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py > b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > new file mode 100644 > index 000000000000..6e54b860a9c9 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > @@ -0,0 +1,86 @@ > +## @file > +# This file is used to define the interface of Bios Parser. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +from PI.Common import * > +from core.BinaryFactoryProduct import ParserEntry > +from core.BiosTreeNode import * > +from core.BiosTree import * > +from core.GuidTools import * > + > +class FMMTParser: > + def __init__(self, name: str, TYPE: str) -> None: > + self.WholeFvTree = BIOSTREE(name) > + self.WholeFvTree.type = TYPE > + self.FinalData = b'' > + self.BinaryInfo = [] > + > + ## Parser the nodes in WholeTree. > + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', > Reloffset: int=0) -> None: > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == > ROOT_FV_TREE: > + ParserEntry().DataParser(self.WholeFvTree, whole_data, > Reloffset) > + else: > + ParserEntry().DataParser(WholeFvTree, whole_data, > Reloffset) > + for Child in WholeFvTree.Child: > + self.ParserFromRoot(Child, "") > + > + ## Encapuslation all the data in tree into self.FinalData > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None: > + # If current node is Root node, skip it. > + if rootTree.type == ROOT_TREE or rootTree.type == > ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == > ROOT_SECTION_TREE: > + print('Start at Root !') > + # If current node do not have Header, just add Data. > + elif rootTree.type == BINARY_DATA or rootTree.type == > FFS_FREE_SPACE: > + self.FinalData += rootTree.Data.Data > + rootTree.Child = [] > + # If current node do not have Child and ExtHeader, just add its > Header and Data. > + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD: > + self.FinalData += struct2stream(rootTree.Data.Header) + > rootTree.Data.Data + rootTree.Data.PadData > + if rootTree.isFinalChild(): > + ParTree = rootTree.Parent > + if ParTree.type != 'ROOT': > + self.FinalData += ParTree.Data.PadData > + rootTree.Child = [] > + # If current node is not Section node and may have Child and > ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data. > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or > rootTree.type == SEC_FV_TREE: > + if rootTree.HasChild(): > + self.FinalData += struct2stream(rootTree.Data.Header) > + else: > + self.FinalData += struct2stream(rootTree.Data.Header) + > rootTree.Data.Data + rootTree.Data.PadData > + if rootTree.isFinalChild(): > + ParTree = rootTree.Parent > + if ParTree.type != 'ROOT': > + self.FinalData += ParTree.Data.PadData > + # If current node is Section, need to consider its ExtHeader, Child > and Compressed Status. > + elif rootTree.type == SECTION_TREE: > + # Not compressed section > + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != > b'' and CompressStatus): > + if rootTree.HasChild(): > + if rootTree.Data.ExtHeader: > + self.FinalData += > struct2stream(rootTree.Data.Header) + > struct2stream(rootTree.Data.ExtHeader) > + else: > + self.FinalData += > struct2stream(rootTree.Data.Header) > + else: > + Data = rootTree.Data.Data > + if rootTree.Data.ExtHeader: > + self.FinalData += > struct2stream(rootTree.Data.Header) + > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > + else: > + self.FinalData += > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > + if rootTree.isFinalChild(): > + ParTree = rootTree.Parent > + self.FinalData += ParTree.Data.PadData > + # If compressed section > + else: > + Data = rootTree.Data.OriData > + rootTree.Child = [] > + if rootTree.Data.ExtHeader: > + self.FinalData += > struct2stream(rootTree.Data.Header) + > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > + else: > + self.FinalData += > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > + if rootTree.isFinalChild(): > + ParTree = rootTree.Parent > + self.FinalData += ParTree.Data.PadData > + for Child in rootTree.Child: > + self.Encapsulation(Child, CompressStatus) > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py > b/BaseTools/Source/Python/FMMT/core/FvHandler.py > new file mode 100644 > index 000000000000..f73f1fd65c07 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py > @@ -0,0 +1,521 @@ > +## @file > +# This file is used to the implementation of Bios layout handler. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +import os > +from core.BiosTree import * > +from core.GuidTools import GUIDTools > +from core.BiosTreeNode import * > +from PI.Common import * > + > +EFI_FVB2_ERASE_POLARITY = 0x00000800 > + > +def ChangeSize(TargetTree, size_delta: int=0) -> None: > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or > type(TargetTree.Data.Header) == type(EFI_COMMON_SECTION_HEADER2()): > + TargetTree.Data.Size -= size_delta > + TargetTree.Data.Header.ExtendedSize -= size_delta > + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData: > + OriSize = TargetTree.Data.Header.SECTION_SIZE > + OriSize -= size_delta > + TargetTree.Data.Header.Size[0] = OriSize % (16**2) > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2) > + TargetTree.Data.Header.Size[2] = OriSize // (16**4) > + else: > + TargetTree.Data.Size -= size_delta > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2) > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) > //(16**2) > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4) > + > +def ModifyFfsType(TargetFfs) -> None: > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and > TargetFfs.Data.Size > 0xFFFFFF: > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8 > + New_Header = EFI_FFS_FILE_HEADER2() > + New_Header.Name = TargetFfs.Data.Header.Name > + New_Header.IntegrityCheck = > TargetFfs.Data.Header.IntegrityCheck > + New_Header.Type = TargetFfs.Data.Header.Type > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > + New_Header.Size = 0 > + New_Header.State = TargetFfs.Data.Header.State > + New_Header.ExtendedSize = ExtendSize > + TargetFfs.Data.Header = New_Header > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > + TargetFfs.Data.HeaderLength = > TargetFfs.Data.Header.HeaderLength > + TargetFfs.Data.ModCheckSum() > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and > TargetFfs.Data.Size <= 0xFFFFFF: > + New_Header = EFI_FFS_FILE_HEADER() > + New_Header.Name = TargetFfs.Data.Header.Name > + New_Header.IntegrityCheck = > TargetFfs.Data.Header.IntegrityCheck > + New_Header.Type = TargetFfs.Data.Header.Type > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > + New_Header.Size = TargetFfs.Data.HeaderLength + > TargetFfs.Data.Size > + New_Header.State = TargetFfs.Data.Header.State > + TargetFfs.Data.Header = New_Header > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > + TargetFfs.Data.HeaderLength = > TargetFfs.Data.Header.HeaderLength > + TargetFfs.Data.ModCheckSum() > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == > EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE: > + NeedChange = True > + for item in TargetFfs.Parent.Child: > + if type(item.Data.Header) == > type(EFI_FFS_FILE_HEADER2()): > + NeedChange = False > + if NeedChange: > + TargetFfs.Parent.Data.Header.FileSystemGuid = > ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > + > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()): > + TarParent = TargetFfs.Parent > + while TarParent: > + if TarParent.type == FV_TREE and > struct2stream(TarParent.Data.Header.FileSystemGuid) == > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE: > + TarParent.Data.Header.FileSystemGuid = > ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > + TarParent = TarParent.Parent > + > +class FvHandler: > + def __init__(self, NewFfs, TargetFfs) -> None: > + self.NewFfs = NewFfs > + self.TargetFfs = TargetFfs > + self.Status = False > + self.Remain_New_Free_Space = 0 > + > + ## Use for Compress the Section Data > + def CompressData(self, TargetTree) -> None: > + TreePath = TargetTree.GetTreePath() > + pos = len(TreePath) > + self.Status = True > + while pos: > + if self.Status: > + if TreePath[pos-1].type == SECTION_TREE and > TreePath[pos-1].Data.Type == 0x02: > + self.CompressSectionData(TreePath[pos-1], None, > TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid) > + else: > + if pos == len(TreePath): > + self.CompressSectionData(TreePath[pos-1], > pos) > + else: > + self.CompressSectionData(TreePath[pos-1], > None) > + pos -= 1 > + > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> > None: > + NewData = b'' > + temp_save_child = TargetTree.Child > + if TargetTree.Data: > + for item in temp_save_child: > + if item.type == SECTION_TREE and not > item.Data.OriData and item.Data.ExtHeader: > + NewData += struct2stream(item.Data.Header) + > struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData > + elif item.type == SECTION_TREE and item.Data.OriData > and not item.Data.ExtHeader: > + NewData += struct2stream(item.Data.Header) + > item.Data.OriData + item.Data.PadData > + elif item.type == SECTION_TREE and item.Data.OriData > and item.Data.ExtHeader: > + NewData += struct2stream(item.Data.Header) + > struct2stream(item.Data.ExtHeader) + item.Data.OriData + > item.Data.PadData > + elif item.type == FFS_FREE_SPACE: > + NewData += item.Data.Data + item.Data.PadData > + else: > + NewData += struct2stream(item.Data.Header) + > item.Data.Data + item.Data.PadData > + if TargetTree.type == FFS_TREE: > + New_Pad_Size = GetPadSize(len(NewData), 8) > + Size_delta = len(NewData) - len(TargetTree.Data.Data) > + ChangeSize(TargetTree, -Size_delta) > + Delta_Pad_Size = len(TargetTree.Data.PadData) - > New_Pad_Size > + self.Remain_New_Free_Space += Delta_Pad_Size > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size > + TargetTree.Data.ModCheckSum() > + elif TargetTree.type == FV_TREE or TargetTree.type == > SEC_FV_TREE and not pos: > + if self.Remain_New_Free_Space: > + if TargetTree.Data.Free_Space: > + TargetTree.Data.Free_Space += > self.Remain_New_Free_Space > + NewData += self.Remain_New_Free_Space * > b'\xff' > + TargetTree.Child[-1].Data.Data += > self.Remain_New_Free_Space * b'\xff' > + else: > + TargetTree.Data.Data += > self.Remain_New_Free_Space * b'\xff' > + New_Free_Space = BIOSTREE('FREE_SPACE') > + New_Free_Space.type = FFS_FREE_SPACE > + New_Free_Space.Data = > FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space) > + TargetTree.insertChild(New_Free_Space) > + self.Remain_New_Free_Space = 0 > + if TargetTree.type == SEC_FV_TREE: > + Size_delta = len(NewData) + > self.Remain_New_Free_Space - len(TargetTree.Data.Data) > + TargetTree.Data.Header.FvLength += Size_delta > + TargetTree.Data.ModFvExt() > + TargetTree.Data.ModFvSize() > + TargetTree.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetTree) > + TargetTree.Data.ModCheckSum() > + elif TargetTree.type == SECTION_TREE and > TargetTree.Data.Type != 0x02: > + New_Pad_Size = GetPadSize(len(NewData), 4) > + Size_delta = len(NewData) - len(TargetTree.Data.Data) > + ChangeSize(TargetTree, -Size_delta) > + if TargetTree.NextRel: > + Delta_Pad_Size = len(TargetTree.Data.PadData) - > New_Pad_Size > + self.Remain_New_Free_Space += Delta_Pad_Size > + TargetTree.Data.PadData = b'\x00' * > New_Pad_Size > + TargetTree.Data.Data = NewData > + if GuidTool: > + ParPath = > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. ") > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > + guidtool = > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > + CompressedData = guidtool.pack(TargetTree.Data.Data) > + if len(CompressedData) < len(TargetTree.Data.OriData): > + New_Pad_Size = GetPadSize(len(CompressedData), 4) > + Size_delta = len(CompressedData) - > len(TargetTree.Data.OriData) > + ChangeSize(TargetTree, -Size_delta) > + if TargetTree.NextRel: > + TargetTree.Data.PadData = b'\x00' * > New_Pad_Size > + self.Remain_New_Free_Space = > len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - > len(CompressedData) - New_Pad_Size > + else: > + TargetTree.Data.PadData = b'' > + self.Remain_New_Free_Space = > len(TargetTree.Data.OriData) - len(CompressedData) > + TargetTree.Data.OriData = CompressedData > + elif len(CompressedData) == len(TargetTree.Data.OriData): > + TargetTree.Data.OriData = CompressedData > + elif len(CompressedData) > len(TargetTree.Data.OriData): > + New_Pad_Size = GetPadSize(CompressedData, 4) > + self.Remain_New_Free_Space = len(CompressedData) + > New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData) > + Size_delta = len(TargetTree.Data.OriData) - > len(CompressedData) > + ChangeSize(TargetTree, -Size_delta) > + if TargetTree.NextRel: > + TargetTree.Data.PadData = b'\x00' * > New_Pad_Size > + TargetTree.Data.OriData = CompressedData > + self.ModifyTest(TargetTree, > self.Remain_New_Free_Space) > + self.Status = False > + > + def ModifyFvExtData(self, TreeNode) -> None: > + FvExtData = b'' > + if TreeNode.Data.Header.ExtHeaderOffset: > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader) > + FvExtData += FvExtHeader > + if TreeNode.Data.Header.ExtHeaderOffset and > TreeNode.Data.ExtEntryExist: > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry) > + FvExtData += FvExtEntry > + if FvExtData: > + InfoNode = TreeNode.Child[0] > + InfoNode.Data.Data = FvExtData + > InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:] > + InfoNode.Data.ModCheckSum() > + > + def ModifyTest(self, ParTree, Needed_Space: int) -> None: > + if Needed_Space > 0: > + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE: > + ParTree.Data.Data = b'' > + Needed_Space = Needed_Space - > ParTree.Data.Free_Space > + if Needed_Space < 0: > + ParTree.Child[-1].Data.Data = b'\xff' * > (-Needed_Space) > + ParTree.Data.Free_Space = (-Needed_Space) > + self.Status = True > + else: > + if ParTree.type == FV_TREE: > + self.Status = False > + else: > + BlockSize = > ParTree.Data.Header.BlockMap[0].Length > + New_Add_Len = BlockSize - > Needed_Space%BlockSize > + if New_Add_Len % BlockSize: > + ParTree.Child[-1].Data.Data = b'\xff' * > New_Add_Len > + ParTree.Data.Free_Space = > New_Add_Len > + Needed_Space += New_Add_Len > + else: > + ParTree.Child.remove(ParTree.Child[-1]) > + ParTree.Data.Free_Space = 0 > + ParTree.Data.Size += Needed_Space > + ParTree.Data.Header.Fvlength = > ParTree.Data.Size > + for item in ParTree.Child: > + if item.type == FFS_FREE_SPACE: > + ParTree.Data.Data += item.Data.Data + > item.Data.PadData > + else: > + ParTree.Data.Data += > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > + ParTree.Data.ModFvExt() > + ParTree.Data.ModFvSize() > + ParTree.Data.ModExtHeaderData() > + self.ModifyFvExtData(ParTree) > + ParTree.Data.ModCheckSum() > + elif ParTree.type == FFS_TREE: > + ParTree.Data.Data = b'' > + for item in ParTree.Child: > + if item.Data.OriData: > + if item.Data.ExtHeader: > + ParTree.Data.Data += > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > item.Data.OriData + item.Data.PadData > + else: > + ParTree.Data.Data += > struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData > + else: > + if item.Data.ExtHeader: > + ParTree.Data.Data += > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > item.Data.Data + item.Data.PadData > + else: > + ParTree.Data.Data += > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > + ChangeSize(ParTree, -Needed_Space) > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8) > + Delta_Pad_Size = New_Pad_Size - > len(ParTree.Data.PadData) > + Needed_Space += Delta_Pad_Size > + ParTree.Data.PadData = b'\xff' * > GetPadSize(ParTree.Data.Size, 8) > + ParTree.Data.ModCheckSum() > + elif ParTree.type == SECTION_TREE: > + OriData = ParTree.Data.Data > + ParTree.Data.Data = b'' > + for item in ParTree.Child: > + if item.type == SECTION_TREE and > item.Data.ExtHeader and item.Data.Type != 0x02: > + ParTree.Data.Data += > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > item.Data.Data + item.Data.PadData > + elif item.type == SECTION_TREE and > item.Data.ExtHeader and item.Data.Type == 0x02: > + ParTree.Data.Data += > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > item.Data.OriData + item.Data.PadData > + else: > + ParTree.Data.Data += > struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData > + if ParTree.Data.Type == 0x02: > + ParTree.Data.Size += Needed_Space > + ParPath = > os.path.abspath(os.path.dirname(os.path.abspath(__file__))) > + ToolPath = os.path.join(os.path.dirname(ParPath), > r'FMMTConfig.ini') > + guidtool = > GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Sec > tionDefinitionGuid)) > + CompressedData = > guidtool.pack(ParTree.Data.Data) > + Needed_Space = len(CompressedData) - > len(ParTree.Data.OriData) > + ParTree.Data.OriData = CompressedData > + New_Size = ParTree.Data.HeaderLength + > len(CompressedData) > + ParTree.Data.Header.Size[0] = New_Size % (16**2) > + ParTree.Data.Header.Size[1] = New_Size % (16**4) > //(16**2) > + ParTree.Data.Header.Size[2] = New_Size // (16**4) > + if ParTree.NextRel: > + New_Pad_Size = GetPadSize(New_Size, 4) > + Delta_Pad_Size = New_Pad_Size - > len(ParTree.Data.PadData) > + ParTree.Data.PadData = b'\x00' * > New_Pad_Size > + Needed_Space += Delta_Pad_Size > + else: > + ParTree.Data.PadData = b'' > + elif Needed_Space: > + ChangeSize(ParTree, -Needed_Space) > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4) > + Delta_Pad_Size = New_Pad_Size - > len(ParTree.Data.PadData) > + Needed_Space += Delta_Pad_Size > + ParTree.Data.PadData = b'\x00' * New_Pad_Size > + NewParTree = ParTree.Parent > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, > ROOT_SECTION_TREE, ROOT_TREE] > + if NewParTree and NewParTree.type not in ROOT_TYPE: > + self.ModifyTest(NewParTree, Needed_Space) > + else: > + self.Status = True > + > + def ReplaceFfs(self) -> bool: > + TargetFv = self.TargetFfs.Parent > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child > Ffs Header State need be reversed. > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: > + self.NewFfs.Data.Header.State = c_uint8( > + ~self.NewFfs.Data.Header.State) > + # NewFfs parsing will not calculate the PadSize, thus recalculate. > + self.NewFfs.Data.PadData = b'\xff' * > GetPadSize(self.NewFfs.Data.Size, 8) > + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size: > + Needed_Space = self.NewFfs.Data.Size + > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > len(self.TargetFfs.Data.PadData) > + # If TargetFv have enough free space, just move part of the > free space to NewFfs. > + if TargetFv.Data.Free_Space >= Needed_Space: > + # Modify TargetFv Child info and BiosTree. > + TargetFv.Child[-1].Data.Data = b'\xff' * > (TargetFv.Data.Free_Space - Needed_Space) > + TargetFv.Data.Free_Space -= Needed_Space > + Target_index = TargetFv.Child.index(self.TargetFfs) > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.insertChild(self.NewFfs, Target_index) > + # Modify TargetFv Header and ExtHeader info. > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModFvSize() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + # return the Status > + self.Status = True > + # If TargetFv do not have enough free space, need move part > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > + else: > + if TargetFv.type == FV_TREE: > + self.Status = False > + else: > + # Recalculate TargetFv needed space to keep it > match the BlockSize setting. > + Needed_Space -= TargetFv.Data.Free_Space > + BlockSize = > TargetFv.Data.Header.BlockMap[0].Length > + New_Add_Len = BlockSize - > Needed_Space%BlockSize > + Target_index = TargetFv.Child.index(self.TargetFfs) > + if New_Add_Len % BlockSize: > + TargetFv.Child[-1].Data.Data = b'\xff' * > New_Add_Len > + TargetFv.Data.Free_Space = New_Add_Len > + Needed_Space += New_Add_Len > + TargetFv.insertChild(self.NewFfs, Target_index) > + TargetFv.Child.remove(self.TargetFfs) > + else: > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.Data.Free_Space = 0 > + TargetFv.insertChild(self.NewFfs) > + # Encapsulate the Fv Data for update. > + TargetFv.Data.Data = b'' > + for item in TargetFv.Child: > + if item.type == FFS_FREE_SPACE: > + TargetFv.Data.Data += item.Data.Data + > item.Data.PadData > + else: > + TargetFv.Data.Data += > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > + TargetFv.Data.Size += Needed_Space > + # Modify TargetFv Data Header and ExtHeader info. > + TargetFv.Data.Header.FvLength = > TargetFv.Data.Size > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModFvSize() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + # Start free space calculating and moving process. > + self.ModifyTest(TargetFv.Parent, Needed_Space) > + else: > + New_Free_Space = self.TargetFfs.Data.Size - > self.NewFfs.Data.Size > + # If TargetFv already have free space, move the new free > space into it. > + if TargetFv.Data.Free_Space: > + TargetFv.Child[-1].Data.Data += b'\xff' * > New_Free_Space > + TargetFv.Data.Free_Space += New_Free_Space > + Target_index = TargetFv.Child.index(self.TargetFfs) > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.insertChild(self.NewFfs, Target_index) > + self.Status = True > + # If TargetFv do not have free space, create free space for Fv. > + else: > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE') > + New_Free_Space_Tree.type = FFS_FREE_SPACE > + New_Free_Space_Tree.Data = FfsNode(b'\xff' * > New_Free_Space) > + TargetFv.Data.Free_Space = New_Free_Space > + TargetFv.insertChild(New_Free_Space) > + Target_index = TargetFv.Child.index(self.TargetFfs) > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.insertChild(self.NewFfs, Target_index) > + self.Status = True > + # Modify TargetFv Header and ExtHeader info. > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModFvSize() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + return self.Status > + > + def AddFfs(self) -> bool: > + # NewFfs parsing will not calculate the PadSize, thus recalculate. > + self.NewFfs.Data.PadData = b'\xff' * > GetPadSize(self.NewFfs.Data.Size, 8) > + if self.TargetFfs.type == FFS_FREE_SPACE: > + TargetLen = self.NewFfs.Data.Size + > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > len(self.TargetFfs.Data.PadData) > + TargetFv = self.TargetFfs.Parent > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, > Child Ffs Header State need be reversed. > + if TargetFv.Data.Header.Attributes & > EFI_FVB2_ERASE_POLARITY: > + self.NewFfs.Data.Header.State = c_uint8( > + ~self.NewFfs.Data.Header.State) > + # If TargetFv have enough free space, just move part of the > free space to NewFfs, split free space to NewFfs and new free space. > + if TargetLen < 0: > + self.Status = True > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen) > + TargetFv.Data.Free_Space = (-TargetLen) > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + TargetFv.insertChild(self.NewFfs, -1) > + ModifyFfsType(self.NewFfs) > + elif TargetLen == 0: > + self.Status = True > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.insertChild(self.NewFfs) > + ModifyFfsType(self.NewFfs) > + # If TargetFv do not have enough free space, need move part > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > + else: > + if TargetFv.type == FV_TREE: > + self.Status = False > + elif TargetFv.type == SEC_FV_TREE: > + # Recalculate TargetFv needed space to keep it > match the BlockSize setting. > + BlockSize = > TargetFv.Data.Header.BlockMap[0].Length > + New_Add_Len = BlockSize - TargetLen%BlockSize > + if New_Add_Len % BlockSize: > + self.TargetFfs.Data.Data = b'\xff' * > New_Add_Len > + self.TargetFfs.Data.Size = New_Add_Len > + TargetLen += New_Add_Len > + TargetFv.insertChild(self.NewFfs, -1) > + TargetFv.Data.Free_Space = New_Add_Len > + else: > + TargetFv.Child.remove(self.TargetFfs) > + TargetFv.insertChild(self.NewFfs) > + TargetFv.Data.Free_Space = 0 > + ModifyFfsType(self.NewFfs) > + TargetFv.Data.Data = b'' > + for item in TargetFv.Child: > + if item.type == FFS_FREE_SPACE: > + TargetFv.Data.Data += item.Data.Data + > item.Data.PadData > + else: > + TargetFv.Data.Data += > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > + # Encapsulate the Fv Data for update. > + TargetFv.Data.Size += TargetLen > + TargetFv.Data.Header.FvLength = > TargetFv.Data.Size > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModFvSize() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + # Start free space calculating and moving process. > + self.ModifyTest(TargetFv.Parent, TargetLen) > + else: > + # If TargetFv do not have free space, need directly move part > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > + TargetLen = self.NewFfs.Data.Size + > len(self.NewFfs.Data.PadData) > + TargetFv = self.TargetFfs.Parent > + if TargetFv.Data.Header.Attributes & > EFI_FVB2_ERASE_POLARITY: > + self.NewFfs.Data.Header.State = c_uint8( > + ~self.NewFfs.Data.Header.State) > + if TargetFv.type == FV_TREE: > + self.Status = False > + elif TargetFv.type == SEC_FV_TREE: > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length > + New_Add_Len = BlockSize - TargetLen%BlockSize > + if New_Add_Len % BlockSize: > + New_Free_Space = BIOSTREE('FREE_SPACE') > + New_Free_Space.type = FFS_FREE_SPACE > + New_Free_Space.Data = FreeSpaceNode(b'\xff' * > New_Add_Len) > + TargetLen += New_Add_Len > + TargetFv.Data.Free_Space = New_Add_Len > + TargetFv.insertChild(self.NewFfs) > + TargetFv.insertChild(New_Free_Space) > + else: > + TargetFv.insertChild(self.NewFfs) > + ModifyFfsType(self.NewFfs) > + TargetFv.Data.Data = b'' > + for item in TargetFv.Child: > + if item.type == FFS_FREE_SPACE: > + TargetFv.Data.Data += item.Data.Data + > item.Data.PadData > + else: > + TargetFv.Data.Data += > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > + TargetFv.Data.Size += TargetLen > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size > + TargetFv.Data.ModFvExt() > + TargetFv.Data.ModFvSize() > + TargetFv.Data.ModExtHeaderData() > + self.ModifyFvExtData(TargetFv) > + TargetFv.Data.ModCheckSum() > + self.ModifyTest(TargetFv.Parent, TargetLen) > + return self.Status > + > + def DeleteFfs(self) -> bool: > + Delete_Ffs = self.TargetFfs > + Delete_Fv = Delete_Ffs.Parent > + Add_Free_Space = Delete_Ffs.Data.Size + > len(Delete_Ffs.Data.PadData) > + if Delete_Fv.Data.Free_Space: > + if Delete_Fv.type == SEC_FV_TREE: > + Used_Size = Delete_Fv.Data.Size - > Delete_Fv.Data.Free_Space - Add_Free_Space > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length > + New_Free_Space = BlockSize - Used_Size % BlockSize > + self.Remain_New_Free_Space += > Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space > + Delete_Fv.Child[-1].Data.Data = New_Free_Space * > b'\xff' > + Delete_Fv.Data.Free_Space = New_Free_Space > + else: > + Used_Size = Delete_Fv.Data.Size - > Delete_Fv.Data.Free_Space - Add_Free_Space > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * > b'\xff' > + Delete_Fv.Data.Free_Space += Add_Free_Space > + New_Free_Space = Delete_Fv.Data.Free_Space + > Add_Free_Space > + else: > + if Delete_Fv.type == SEC_FV_TREE: > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length > + New_Free_Space = BlockSize - Used_Size % BlockSize > + self.Remain_New_Free_Space += Add_Free_Space - > New_Free_Space > + Add_Free_Space = New_Free_Space > + else: > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > + New_Free_Space = Add_Free_Space > + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff') > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff' > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name) > + New_Ffs_Tree.type = FFS_FREE_SPACE > + New_Ffs_Tree.Data = New_Free_Space_Info > + Delete_Fv.insertChild(New_Ffs_Tree) > + Delete_Fv.Data.Free_Space = Add_Free_Space > + Delete_Fv.Child.remove(Delete_Ffs) > + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space > + Delete_Fv.Data.ModFvExt() > + Delete_Fv.Data.ModFvSize() > + Delete_Fv.Data.ModExtHeaderData() > + self.ModifyFvExtData(Delete_Fv) > + Delete_Fv.Data.ModCheckSum() > + self.CompressData(Delete_Fv) > + self.Status = True > + return self.Status > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py > b/BaseTools/Source/Python/FMMT/core/GuidTools.py > new file mode 100644 > index 000000000000..e21d8e0406ae > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py > @@ -0,0 +1,152 @@ > +## @file > +# This file is used to define the FMMT dependent external tool management > class. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > +import glob > +import logging > +import os > +import shutil > +import sys > +import tempfile > +import uuid > +from PI.Common import * > +from utils.FmmtLogger import FmmtLogger as logger > +import subprocess > + > +def ExecuteCommand(cmd: list) -> None: > + subprocess.run(cmd,stdout=subprocess.DEVNULL) > + > +class GUIDTool: > + def __init__(self, guid: str, short_name: str, command: str) -> None: > + self.guid: str = guid > + self.short_name: str = short_name > + self.command: str = command > + > + def pack(self, buffer: bytes) -> bytes: > + """ > + compress file. > + """ > + tool = self.command > + if tool: > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > + ToolInputFile = os.path.join(tmp, > "pack_uncompress_sec_file") > + ToolOuputFile = os.path.join(tmp, "pack_sec_file") > + try: > + file = open(ToolInputFile, "wb") > + file.write(buffer) > + file.close() > + command = [tool, '-e', '-o', ToolOuputFile, > + ToolInputFile] > + ExecuteCommand(command) > + buf = open(ToolOuputFile, "rb") > + res_buffer = buf.read() > + except Exception as msg: > + logger.error(msg) > + return "" > + else: > + buf.close() > + if os.path.exists(tmp): > + shutil.rmtree(tmp) > + return res_buffer > + else: > + logger.error( > + "Error parsing section: EFI_SECTION_GUID_DEFINED > cannot be parsed at this time.") > + logger.info("Its GUID is: %s" % self.guid) > + return "" > + > + > + def unpack(self, buffer: bytes) -> bytes: > + """ > + buffer: remove common header > + uncompress file > + """ > + tool = self.command > + if tool: > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > + ToolInputFile = os.path.join(tmp, "unpack_sec_file") > + ToolOuputFile = os.path.join(tmp, > "unpack_uncompress_sec_file") > + try: > + file = open(ToolInputFile, "wb") > + file.write(buffer) > + file.close() > + command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile] > + ExecuteCommand(command) > + buf = open(ToolOuputFile, "rb") > + res_buffer = buf.read() > + except Exception as msg: > + logger.error(msg) > + return "" > + else: > + buf.close() > + if os.path.exists(tmp): > + shutil.rmtree(tmp) > + return res_buffer > + else: > + logger.error("Error parsing section: > EFI_SECTION_GUID_DEFINED cannot be parsed at this time.") > + logger.info("Its GUID is: %s" % self.guid) > + return "" > + > +class GUIDTools: > + ''' > + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools > and provide interfaces to access those tools. > + ''' > + default_tools = { > + > struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779 > ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", > "TianoCompress"), > + > struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf > ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", > "LzmaCompress"), > + > struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083 > ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", > "GenCrc32"), > + > struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889 > ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", > "LzmaF86Compress"), > + > struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb") > ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", > "BrotliCompress"), > + } > + > + def __init__(self, tooldef_file: str=None) -> None: > + self.dir = os.path.dirname(__file__) > + self.tooldef_file = tooldef_file if tooldef_file else os.path.join( > + self.dir, "FMMTConfig.ini") > + self.tooldef = dict() > + self.load() > + > + def VerifyTools(self) -> None: > + """ > + Verify Tools and Update Tools path. > + """ > + path_env = os.environ.get("PATH") > + path_env_list = path_env.split(os.pathsep) > + path_env_list.append(os.path.dirname(__file__)) > + path_env_list = list(set(path_env_list)) > + for tool in self.tooldef.values(): > + cmd = tool.command > + if os.path.isabs(cmd): > + if not os.path.exists(cmd): > + print("Tool Not found %s" % cmd) > + else: > + for syspath in path_env_list: > + if glob.glob(os.path.join(syspath, cmd+"*")): > + break > + else: > + print("Tool Not found %s" % cmd) > + > + def load(self) -> None: > + if os.path.exists(self.tooldef_file): > + with open(self.tooldef_file, "r") as fd: > + config_data = fd.readlines() > + for line in config_data: > + try: > + guid, short_name, command = line.split() > + new_format_guid = > struct2stream(ModifyGuidFormat(guid.strip())) > + self.tooldef[new_format_guid] = GUIDTool( > + guid.strip(), short_name.strip(), > command.strip()) > + except: > + print("GuidTool load error!") > + continue > + else: > + self.tooldef.update(self.default_tools) > + > + self.VerifyTools() > + > + def __getitem__(self, guid) -> None: > + return self.tooldef.get(guid) > + > + > +guidtools = GUIDTools() > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > new file mode 100644 > index 000000000000..18f0cff96e4b > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > @@ -0,0 +1,18 @@ > +## @file > +# This file is used to define the Fmmt Logger. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > + > +## > + > +import logging > +import sys > + > +FmmtLogger = logging.getLogger('FMMT') > +FmmtLogger.setLevel(logging.INFO) > + > +lh=logging.StreamHandler(sys.stdout) > +lf=logging.Formatter("%(levelname)-8s: %(message)s") > +lh.setFormatter(lf) > +FmmtLogger.addHandler(lh) > \ No newline at end of file > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > new file mode 100644 > index 000000000000..1a6c67056266 > --- /dev/null > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > @@ -0,0 +1,54 @@ > +## @file > +# This file is used to define the printer for Bios layout. > +# > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > + > +def GetFormatter(layout_format: str): > + if layout_format == 'json': > + return JsonFormatter() > + elif layout_format == 'yaml': > + return YamlFormatter() > + elif layout_format == 'html': > + return HtmlFormatter() > + else: > + return TxtFormatter() > + > +class Formatter(object): > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None: > + raise NotImplemented > + > +class JsonFormatter(Formatter): > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> > None: > + try: > + import json > + except: > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > + return > + print(outputfile) > + if outputfile: > + with open(outputfile,"w") as fw: > + json.dump(layoutdict, fw, indent=2) > + else: > + print(json.dumps(layoutdict,indent=2)) > + > +class TxtFormatter(Formatter): > + def LogPrint(self,layoutlist: list) -> None: > + for item in layoutlist: > + print(item) > + print('\n') > + > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> > None: > + print(outputfile) > + with open(outputfile, "w") as f: > + for item in layoutlist: > + f.writelines(item + '\n') > + > +class YamlFormatter(Formatter): > + def dump(self,layoutdict, layoutlist, outputfile = None): > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > + > +class HtmlFormatter(Formatter): > + def dump(self,layoutdict, layoutlist, outputfile = None): > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > \ No newline at end of file > -- > 2.27.0.windows.1 > > > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool 2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming @ 2021-12-06 8:34 ` Yuwei Chen 2021-12-06 9:44 ` 回复: " gaoliming 0 siblings, 1 reply; 4+ messages in thread From: Yuwei Chen @ 2021-12-06 8:34 UTC (permalink / raw) To: devel@edk2.groups.io, gaoliming@byosoft.com.cn; +Cc: Feng, Bob C Hi Liming, Need your helps on the first and third issues: 1. As the PI spec defined, for Fv Header "The first 16 bytes are reserved to allow for the reset vector of processors whose reset vector is at address 0." The FVSEC.Fv generated did not follow the Spec definition, is this the issue of GenFv or FMMT, are there any references for this issue? 3. The PEIM rebase way follows which rules? Thanks, Christine (Yuwei) > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of > gaoliming > Sent: Friday, December 3, 2021 11:19 AM > To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com> > Cc: Feng, Bob C <bob.c.feng@intel.com> > Subject: 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > Yuwei: > I did some test and meet three problems. I submit BZ > https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check. > > Thanks > Liming > > -----邮件原件----- > > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen > > 发送时间: 2021年12月1日 9:29 > > 收件人: devel@edk2.groups.io > > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao > > <gaoliming@byosoft.com.cn> > > 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > > > The FMMT python tool is used for firmware files operation, which has > > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function: > > > > 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files) > > 2.Add a new FFS into a FV file (both included in a FD file or not) > > 3.Replace an FFS in a FV file with a new FFS file > > 4.Delete an FFS in a FV file (both included in a FD file or not) > > 5.Extract the FFS from a FV file (both included in a FD file or not) > > > > Currently the FMMT C tool is saved in edk2-staging repo, but its > > quality and coding style can't meet the Edk2 quality, which is hard to > > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage). > > > > The new Python version keeps same functions with origin C version. It > > has higher quality and better coding style, and it is much easier to > > extend new functions and to maintain. > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847 > > PR Link: https://github.com/tianocore/edk2-basetools/pull/12 > > RFC Link: https://edk2.groups.io/g/devel/message/82877 > > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT > > > > Cc: Bob Feng <bob.c.feng@intel.com> > > Cc: Liming Gao <gaoliming@byosoft.com.cn> > > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> > > --- > > V4 fixed the Linux file format issue and known bugs. > > BaseTools/BinWrappers/PosixLike/FMMT | 14 + > > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 + > > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++ > > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 + > > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes > > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes > > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++ > > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++ > > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++ > > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++ > > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 + > > BaseTools/Source/Python/FMMT/README.md | 180 ++++++ > > BaseTools/Source/Python/FMMT/__init__.py | 0 > > .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++ > > BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++ > > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++ > > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++ > > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++ > > .../Source/Python/FMMT/core/FvHandler.py | 521 > > ++++++++++++++++++ > > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++ > > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 + > > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++ > > 22 files changed, 2432 insertions(+) > > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT > > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat > > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py > > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini > > create mode 100644 > > BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > create mode 100644 > > BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py > > create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py > > create mode 100644 > BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py > > create mode 100644 BaseTools/Source/Python/FMMT/README.md > > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py > > create mode 100644 > > BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py > > create mode 100644 > > BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > create mode 100644 > > BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > create mode 100644 > BaseTools/Source/Python/FMMT/core/FMMTParser.py > > create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py > > create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py > > create mode 100644 > BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > create mode 100644 > > BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > > > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT > > b/BaseTools/BinWrappers/PosixLike/FMMT > > new file mode 100644 > > index 000000000000..5f5519e1e1b6 > > --- /dev/null > > +++ b/BaseTools/BinWrappers/PosixLike/FMMT > > @@ -0,0 +1,14 @@ > > +#!/usr/bin/env bash > > +#python `dirname $0`/RunToolFromSource.py `basename $0` $* > > + > > +# If a ${PYTHON_COMMAND} command is available, use it in preference > to > > python > > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > > + python_exe=${PYTHON_COMMAND} > > +fi > > + > > +full_cmd=${BASH_SOURCE:-$0} # see > > http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not > a > > good choice here > > +dir=$(dirname "$full_cmd") > > +cmd=${full_cmd##*/} > > + > > +export > > > PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY > > THONPATH:+:"$PYTHONPATH"}" > > +exec "${python_exe:-python}" -m $cmd.$cmd "$@" > > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > new file mode 100644 > > index 000000000000..f0551c4ac54a > > --- /dev/null > > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > @@ -0,0 +1,4 @@ > > +@setlocal > > +@set ToolName=%~n0% > > +@set > > > PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA > > SE_TOOLS_PATH%\Source\Python\FMMT > > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %* > > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py > > b/BaseTools/Source/Python/FMMT/FMMT.py > > new file mode 100644 > > index 000000000000..5028d8446ee0 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/FMMT.py > > @@ -0,0 +1,117 @@ > > +# @file > > +# Firmware Module Management Tool. > > +# > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > +# > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +# Import Modules > > +# > > +import argparse > > +import sys > > +from core.FMMTOperation import * > > + > > +parser = argparse.ArgumentParser(description=''' > > +View the Binary Structure of FD/FV/Ffs/Section, and > > Delete/Extract/Add/Replace a Ffs from/into a FV. > > +''') > > +parser.add_argument("--version", action="version", version='%(prog)s > > Version 1.0', > > + help="Print debug information.") > > +parser.add_argument("-v", "--View", dest="View", nargs='+', > > + help="View each FV and the named files within > > each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'") > > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+', > > + help="Delete a Ffs from FV: '-d inputfile > > TargetFfsName outputfile TargetFvName(Optional,\ > > + If not given, wil delete all the existed target > Ffs)'") > > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+', > > + help="Extract a Ffs Info: '-e inputfile TargetFfsName > > outputfile'") > > +parser.add_argument("-a", "--Add", dest="Add", nargs='+', > > + help="Add a Ffs into a FV:'-a inputfile > > TargetFvName newffsfile outputfile'") > > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+', > > + help="Replace a Ffs in a FV: '-r inputfile > > TargetFfsName newffsfile outputfile TargetFvName(Optional,\ > > + If not given, wil replace all the existed target > > Ffs with new Ffs file)'") > > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+', > > + help="The format of log file which saves Binary > > layout. Currently supports: json, txt. More formats will be added in the > > future") > > + > > +def print_banner(): > > + print("") > > + > > +class FMMT(): > > + def __init__(self) -> None: > > + self.firmware_packet = {} > > + > > + def CheckFfsName(self, FfsName:str) -> str: > > + try: > > + return uuid.UUID(FfsName) > > + except: > > + return FfsName > > + > > + def View(self, inputfile: str, logfiletype: str=None, outputfile: > str=None) -> > > None: > > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile) > > + filetype = os.path.splitext(inputfile)[1].lower() > > + if filetype == '.fd': > > + ROOT_TYPE = ROOT_TREE > > + elif filetype == '.fv': > > + ROOT_TYPE = ROOT_FV_TREE > > + elif filetype == '.ffs': > > + ROOT_TYPE = ROOT_FFS_TREE > > + elif filetype == '.sec': > > + ROOT_TYPE = ROOT_SECTION_TREE > > + else: > > + ROOT_TYPE = ROOT_TREE > > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile) > > + > > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: > str, > > Fv_name: str=None) -> None: > > + if Fv_name: > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > > outputfile, uuid.UUID(Fv_name)) > > + else: > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > > outputfile) > > + > > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> > None: > > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile) > > + > > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, > outputfile: str) -> > > None: > > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, > > outputfile) > > + > > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, > outputfile: > > str, Fv_name: str=None) -> None: > > + if Fv_name: > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), > newffsfile, > > outputfile, uuid.UUID(Fv_name)) > > + else: > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), > newffsfile, > > outputfile) > > + > > + > > +def main(): > > + args=parser.parse_args() > > + status=0 > > + > > + try: > > + fmmt=FMMT() > > + if args.View: > > + if args.LogFileType: > > + fmmt.View(args.View[0], args.LogFileType[0]) > > + else: > > + fmmt.View(args.View[0]) > > + if args.Delete: > > + if len(args.Delete) == 4: > > + > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3]) > > + else: > > + > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2]) > > + if args.Extract: > > + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2]) > > + if args.Add: > > + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3]) > > + if args.Replace: > > + if len(args.Replace) == 5: > > + > > > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > > 3],args.Replace[4]) > > + else: > > + > > > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > > 3]) > > + # TODO: > > + '''Do the main work''' > > + except Exception as e: > > + print(e) > > + > > + return status > > + > > + > > +if __name__ == "__main__": > > + exit(main()) > > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > new file mode 100644 > > index 000000000000..aa2444f11b38 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > @@ -0,0 +1,11 @@ > > +## @file > > +# This file is used to define the FMMT dependent external tool guid. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress > > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress > > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32 > > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress > > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress > > diff --git > a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > new file mode 100644 > > index > > 0000000000000000000000000000000000000000..7cc806a0133413a4aa037 > > f1d43d80000546a5246 > > GIT binary patch > > literal 29515 > > zcmcG$bySpZzxIs{h;*kQ- > QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+ > > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@- > mueX!oILX!ky# > > KL)-b > > > z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx > > mKL > > z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K > > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A- > ~0 > > Os > > zomQa`7xm?Vn1W*P-%s- > jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK > > u0 > > zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{) > > abe > > z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He > > 5*9B > > z*-Jfk;((ApOh<DBpW00KVT- > d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_ > > e > > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU- > u*mWM > > w) > > > zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK > > !@Kal= > > > zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04 > > 1 > > > z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^ > > W > > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy- > 4#Vx^C$n*R(S2#<fkNRn8K6C!26< > > O > > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<- > BdBP<AmFX)1 > > _0^ > > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt- > C5{L_ > > > zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@ > > YoAv$ > > zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o% > > > z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT > > oZlL > > z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk` > > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@- > nrRU > > > zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr > > k > > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX- > Sd(_WJqP_|B0b^CxF|AoL+M;CA > > Vm > > > zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT > + > > 5 > > > z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu > > D}JIY > > > zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY > > y > > z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk > > znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h > > W653 > > zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz > > z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8 > > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B- > 8MDTh)0*RC#EN#u!^ > > nVH$m > > zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd > > m$ > > > zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^| > > 1l > > zs#*3J+AHPINX8;)QiLwy6-Z2S$&- > jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep > > > z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l > > As > > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$- > *{a=n > > ?K!V > > zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb} > > rWM > > zKu}~4YZm`$e$42- > HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k > > sy > > > z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU > > CN$ > > > z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG > > |Lx3X6 > > > zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt > > P > > z4}!3MY9t1~*EvD4lR~M)=- > uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P! > > > zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b > > 3+@WmhX > > z>ZGUkb+ts3Tk&n$W- > n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C > > Qkvs@ > > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)- > !o_k?1CJInjgyPOhp1A%MDgUMftCS$J~ > > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA- > 1pvp;SGObla#%wB7pN+^fnJc#a?jT)B > > 8 > > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&- > l~CT@#e0@& > > vmX7 > > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*- > 7<1UbT|>O|@l;?iY=`N4 > > z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*% > > zg_$H!- > &YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW > > > z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^( > > F<T-(} > > > zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy` > > TJt!CY > > zZezN}4wz=94~>e){&{8Z- > !pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c > > PC > > > z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4| > > bv > > > zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb > > HJ6Kn > > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78- > 3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq > > ;E > > zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9 > > uN5=1 > > > z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu > > S > > > zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D > > p?; > > zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)% > > > zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw > > Z%2 > > z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl; > > utt > > z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5 > > W0`! > > > z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59 > > {es93C0D > > zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@> > > 3g{x5 > > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^- > 1kaKB+d7T > > Drx2 > > > ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB > > (wX > > zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u? > > 3XkOqt > > > zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX > > DU > > z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy > > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y- > oCVYo9xaw1S?6YWT`9V^=h<QFr > > Q} > > zHAIHMg- > ^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0 > > NyW > > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t- > !imMfLU8CUGd)w > > ^ > > > zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ > > L > > zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j} > > * > > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r- > rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb > > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ- > ?%k;$V^R5XclbB > > !ZjD > > zt=UY&?7-X9<AFk^dEO%~_#P&- > r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(= > > tOwMb > > > z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0 > > lL_ > > > z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+ > > YC > > > zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc > > OCnX > > za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss > > @v > > zSgaMn{Kb=7It4nMlG8iA*- > tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH > > Y<UT > > > zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M > > y7^ > > > zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf > > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS- > w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR > > A2ii > > > z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB > > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V- > {XCZzitML(}hGq&W > > > zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q > > zeC@D`Bk`qD- > *FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS > > bRs > > > zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw > > > z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0 > > > zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9< > > 3 > > > zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO > > 7{FtVq > > zO<`- > jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT > > -Ie5 > > > z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg > > u > > > zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV > > aGRj! > > > z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D > > h > > z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o > > M(_fvkH > > zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY > > $ > > z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H > > @@5TTQn > > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|- > *^dW > > 5 > > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG- > =t3xx > > w9x1s> > > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)- > ^X=?*fdvD > > OD > > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ- > h^Vc`*v)kGJbP?dUI5 > > #x > > > z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o > > S > > > zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5 > > sA > > > zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A > > -H_ > > > zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq > > Cg}S > > zLrkk- > #H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB > > $or- > > > z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{ > > }W > > > zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo > > wW$ > > znAFU~_wY4f2q?dP- > TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D > > &U93 > > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>- > &vpdCAooZEI# > > wk{a > > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T) > > > z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c# > > ~d > > > zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt > > z0zq > > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5- > iu6O > > P@(+ > > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p- > UTYHHHGHJ > > a^R > > z4e9LSAJ3h- > L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR > > > zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO< > > C > > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B- > aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad > > u > > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<- > CE_@x)deTU#?kEtpbb>pf > > JQ > > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#- > <B(*%Baj > > w8bG > > > z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4 > > pUp > > z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j > > kUEqfGQeE > > zsxs)ys+*k- > a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j > > > zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G* > > Aw_D > > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb- > 9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1 > > D > > > z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7 > > X^ > > > zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe > > pj>) > > > z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID< > > < > > > z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(` > > 3v > > > zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@ > > Y8EQ > > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>- > &_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar > > }<t > > > zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+ > > -Xd > > zF@iS2N;c?&GGNFv1f- > nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF > > lqL! > > > z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$ > > > zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M > > TTEJ1 > > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+- > iRa;O_hx8v1 > > pM > > > zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ > > i-E > > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{- > <qQVg#k>78 > > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#- > fvwHu8795}6 > > W > > > z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-` > > X2@$m4( > > > zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r > > A*% > > zYs#3InBRHdV- > hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L > > > zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09 > > 9|n > > > zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@ > > u > > zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6% > > Ib > > zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU > > *R)a;LqQ > > > zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w > > vUtt > > zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c > > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE- > {)&!(C4TBm|f@H > > Qxf > > > zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx > > & > > zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%= > > WmbM0 > > z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl- > q3 > > 6 > > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6- > LubB > > c > > z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha > > > zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh > > g > > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$ > > > z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB > > k2bs > > > zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#( > > t_TQ<~ > > zPpkWLsyFv=kpB8wMCMJ461d6- > pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB > > WqSJV > > zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u > > w9Z > > zIQm^k)g4d<<I-`XDjPImuOoV3k- > fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@ > > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ- > q&>D;Lu4Y*65q > > 0=*^{N > > > zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT > > bF > > > ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv< > > > z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv > > L > > > zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5 > > g^7sU > > zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*> > > 4 > > > zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t` > > ! > > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$- > 5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In > > Z;K > > z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u= > > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H- > JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V > > J)p > > zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3# > > MZ@o > > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G- > ;I<V5t?h0H4ZJmY{X!kNZmp3 > > lj > > zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo# > > 0G7mqVU > > > zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx| > > C^ > > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os- > Y*<Arj > > @T > > > zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U > > zv&u^91`JfQ*$6*pQVC- > u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z > > T > > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB- > Dh>thr$2oA7josXpNOr1+ > > 57 > > > z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~ > > zUK-- > r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd > > V-z > > > zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY > > VB& > > zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w* > > oz > > z@o`0!- > ;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe` > > m > > zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B- > { > > Y > > z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T > > nb329 > > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY- > w@fzc7$VQ4tNhm5V8N(S > > dPS > > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8- > C&&+<Zy65#V5 > > > z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw > > hf!j > > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j- > W2=miHT > > no > > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1- > qeL<q;^=2F} > > T| > > > zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC > > pwM(WO > > z`0>B1JR`+)ZDiuFC!F7Fv- > o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF > > =- > > > zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP > > (nm$ > > zgn7NXKD%P4(&M*qR- > (Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c > > <p > > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av- > 4<bCdT@wTC>GBy~|DLthW;7TX > > boX > > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C- > ixZ#a}(P > > %71 > > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg- > Xm`x2Xg > > z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA > > qe > > > z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4 > > z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8 > > z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH > > T- > > zH|7YArh@+FLkg- > WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3 > > UO`cs > > > zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB) > > 0 > > > zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25 > > zwYj@;E^4?Qbs%M^x|g>zUX- > moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A! > > IRJo > > zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL > > wpm5C > > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd- > 6Ob;XHAbX$!ujWY~NcR > > 9fz? > > zA{m&^E5y==&`JNCtrsVh*i&iF- > ?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj > > mI > > zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r > > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi- > 6N<6qBRAbW>R|5Yvc<6M7$K > > w`6V > > zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2 > > q4` > > > z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^ > > |E7=& > > zinFr&rqO5i{Cmn- > mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U > > ab > > zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO > > > zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw > > n>R7 > > zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc# > > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)- > %FkT > > XOBB > > > zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`& > > uLj > > > zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({| > > *p > > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X- > Z#BGRQr2o > > aKQ > > > zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt( > > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q- > =mGP;tP2mL@wi(xnoq6<%Cb76W9}f > > Ny@K > > > zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O > > pL)Fq>4 > > > zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf > > Mt > > z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@ > > @Yi > > > zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v > > E` > > zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u > > Q@)u > > > zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4 > > PQQA > > z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4 > > ~<o<8e > > > zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D > > <J > > > z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F` > > F4& > > > zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb > > E5 > > > z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z > > #~g=O > > zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k > > e1 > > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi- > O@I~^x{;?=(JqlKKAP)z9 > > zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF% > > *F9!4P^ > > zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N) > > x` > > > zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82# > > hx6wR > > z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp% > > FUzQ > > > zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb > > 4G2Su$ > > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&- > TpdZ4Sm%Z^!(mu%Q > > -d6 > > z8CSq{iA^TAM+Sba`K- > HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd > > qw > > z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci > > zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;> > > m > > > zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW > > DlU4VKO$Q7# > > > zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF > > m!6A > > z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s > > 2 > > > zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq > > uX > > > zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b > > URoM > > z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T; > > dh > > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b- > +I~rxJ^NTX^hUZQ_xQHPN@RYRbv= > > OAaP0< > > > z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv > > Yry > > zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls> > > &a* > > z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8- > K > > z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m > > zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j > > > > > > zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW > > d@XHe > > zvn*f~#Zp|_nC%d- > |J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`< > > x-t > > > zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc > > ny< > > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d- > chHgloB > > Wr|bA > > zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v > > > z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH > > y > > > z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ > > u7Dn > > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_- > YI>c&n(Yp>Lyir > > ~@ > > zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-< > > h!%= > > z*&>EVOnq&ad$05T2- > 6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7 > > Tcf_kK > > zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve > > HMi > > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?- > }0}e(EkUQx{gt5Qv2GI}9K > > s > > > z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~ > > | > > zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y > > *YvY > > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW- > `VxgtihK5w!+4bR%e5W4fcRUBu > > t}=3 > > z- > )H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*& > > MCZ > > zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&- > > zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}# > > (sm; > > > zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzc > E > > -_;{w > > > zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0 > > R!C > > > z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h > > o5lF > > > z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+ > > &#` > > > zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD- > > m$*V > > > zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt > > a > > > zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+& > > `~cD > > zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@> > > U5( > > zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#> > > i8( > > zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV > > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ > > > zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw > > JY7J-w > > > zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^ > > NQcQ > > zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~ > > > z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o > > m > > zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y > > C > > z<!BcWm*#gI)Q;$>P(- > ^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$ > > VQ0FW > > zGH;^fyr(a?>xrm&;uh2hKqp>D- > AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7 > > aZ > > ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z? > > !Ajpt > > > z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha > > 7z > > > z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ > > @Ox > > > zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0 > > l > > zVjM=Qw37|BK0|)- > NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj > > z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II > > Uz > > zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt} > > MtL > > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr- > NH4*=bhL7Tc<AKzmQSP`%KB$^O6d > > paf~! > > zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE- > 1A > > zv1;CZ!z3UqKTUkaP-- > mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw* > > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO- > t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs > > Eg > > z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$ > > ^*M} > > > zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v > > > z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr > > Z?;v@B > > zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_ > > zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb) > > OG > > > z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK > > n{X > > > z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1 > > pZ%wkIe6 > > > zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY- > > pR > > zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75! > > sSCv > > zOI0V)+9b%8^ak8NWz6d- > k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW& > > !*&3( > > zh6=X0QmwWX9XHj5l1@tYGXVhG)- > Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+ > > HQzlwT > > z8x|ZZV|V(- > wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH > > Psf > > > z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs > > s8V7 > > z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj > > z5_5g=+O$i$k;%- > 1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO > > 5%a > > z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z- > > qZ)Dr > > > z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E > > NpfA > > zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0 > > zd*)2v- > xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k > > XtIl50 > > > zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F > > Um > > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}- > _g|Ab91$j2ad2jnt > > +=M > > > znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg > > > zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY > > QmA > > > zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf > > HM# > > zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5 > > VI= > > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL- > `KrNzBi@nX > > eF > > > z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r > > ;!F > > z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t > > xQ > > > z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y| > > p > > > zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e > > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp- > =DEZ9aDLwe&emQpH(ng8O8f| > > N|b > > > zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO > > -%SX > > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm- > Et@op > > ^sZ > > > z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW > > 5K > > > zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes > > )B > > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o- > 9JRkFbj^Cvi9 > > l63 > > > z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v > > +d4T > > > z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^ > > `QF}Y > > zTI!eAjaQV1M2^`)i<P>gsTGz- > UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew< > > 3 > > z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V > > mt<0 > > > zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^ > > + > > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=- > Jy}m > > Zu > > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^- > &~y > > sjCF > > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC- > gE$~l!e > > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^- > Xvwp0G$Ypd!Rc|ZQdfy > > )>q > > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d- > LF2U( > > N;ve > > z`|0v08lJhE- > 43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK| > > T > > > z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`( > > m > > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<- > L*AxFh1pz<SsamItVw$U* > > KSpI > > z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ > > G; > > > zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G > > iy|~ > > z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw> > > 1jO > > zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR > > ~#6 > > > z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W > > ;)# > > zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb > > z$n8i2c(^- > EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN > > 9%7z > > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J- > iap7Ma > > 7+~R > > zr)wN#;gC`Q+R- > b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7 > > sn > > zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw > > HK > > > zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz > > zM > > zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c* > > wq)= > > > z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF > > S* > > > z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk- > > _@X* > > > za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~ > > I4 > > zMe~hi*!yt- > e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW > > B@ > > > ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z > > aMs11 > > zN|%vFr}N@XKRz- > JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW& > > XA7Ak > > z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY > > M > > z{((;&- > ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB > > > z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S > > KDX > > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`- > jSejso!@e^uJ > > < > > zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG > > HTu > > > znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH > > d+ > > zMY- > =jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+ > > k&+m > > z%ZWm1z4nMfO?(4A8G8!- > oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+- > > ^I > > z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4 > > e|4? > > > ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj# > > ^0e > > zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E; > > aO > > zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI) > > d > > z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B > > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA- > +T`x7hrGd7 > > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G- > tP(~dNEPPRy<$X2&|cAe5A > > }bI > > > z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C > > > zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM# > > g8_@a_! > > z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0 > > 06 > > > zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q# > > N > > zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@ > > M4b@Z > > zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A > > W > > zDssgPVVyB-*vr3ad5~B- > )<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f > > wo) > > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H- > BNMSM32B_HnUIx=z%Fof0ntPF#j9W > > WX+ > > > zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u > > > ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L > > D0 > > z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$ > > T2! > > zdK(Bjx%p|zQnoY<UWi- > I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb > > Nki > > zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP> > > u{Cu > > z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA > > z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a > > @W= > > zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p > > > zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b > > aP~U > > z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS? > > dZ > > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T- > wQgkxi3VLQjxyVy > > > zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod > > Up5h > > zqp!T4LK?<KJ()xH%)kcP!N1qc- > swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n > > rr| > > z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g > > $M > > > zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG > > nyO9 > > > z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<= > > QC > > > z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO > > 2Oi > > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl > > > zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI > > +uw!; > > zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL > > > z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2 > > )p > > > zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B > > c;i! > > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV- > Hkg6e~c%ayO > > }6e > > z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf > > > zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx > > yhi > > > zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE > > FSC > > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz- > *>o*46xhGpS8Y;XQ > > *+ > > z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_; > > $3Q > > zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9 > > d > > > zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq > > b-| > > zOx|zYa;20oYTSb^$f*puP6`{=@+R- > cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs > > C^ > > > zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv > > $0gQ > > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#- > a+SMQ@Tv59b7zfSbF`J@FL3|c(?~ > > Mw6 > > > zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva > > Y > > z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK > > J}o! > > > zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y > > GYg > > zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE > > > z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ > > QYoK > > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ- > ~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M > > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{- > p3I!HZ(Q(cX| > > H6u > > > zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@ > > wl > > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_- > `ds;ZHWg<At > > o > > z_!d&4;KL)krKVbM_- > %V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3 > > zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW? > > s&KLw+ > > > zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB( > > ~6l > > z==pSlrsfT~2W{Zj- > #*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU > > Xk > > > zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1( > > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$- > Ow%eFF$z!@ > > J+- > > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R > > zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR > > +Kh}Lr > > zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2 > > > zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{a > Q > > z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n > > C)ZrQ > > > zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7 > > 6h > > zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW > > > z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C > > Wu8yz > > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{) > > zw7h- > b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{ > > $z*$ > > z=zlg}>gO`p- > 0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i > > B > > z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul > > @} > > z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6 > > nc` > > z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU > > z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7 > > 2C@ > > zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM > > e > > zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2 > > > z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg > > 7 > > > z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP > > Su5 > > z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{ > > 2 > > > z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^ > > h{bn+ > > zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4 > > uNZt+ > > z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH > > @17p > > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@- > 1E > > 7@! > > z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv > > UZA3 > > ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13 > > z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq > > z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2 > > zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH > > zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY > > Ep}s > > > z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox > > > zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n > > z{aj > > zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT > > zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC& > > Q* > > z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@ > > 1dFnWtdD > > zNVk1t_y;mT- > k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr > > q=F > > zDjf9;- > DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu > > WqN > > zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM > > o0 > > > zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p > > h-@ > > z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK > > HW > > > z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y > > nKla > > zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D! > > B > > z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp > > Zw$e > > zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c; > > za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g% > > mO > > zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_- > Hx > > _2| > > zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6 > > R4Rr > > > zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N > > zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd > > > zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6& > > u@Wv > > z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6 > > 9Jd_v > > > zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a > > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56- > 8|HN!VHDt?X!7%VRV8^)x > > U0D > > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e- > h|F2yMD^>eWe)o2zdCq!a(n?9 > > >#f > > > z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO} > > F > > > z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ > # > > qTm(t > > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;- > }$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG( > > 6c > > > zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr > > a > > zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU > > zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h > > <pq > > zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC > > Mb > > zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn? > > G > > z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm! > > &o > > > zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem > > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e- > RM%C;1ods}_Dy6=&aE!DH&yZe}Po > > l_s&^ > > ztt&=Z6- > Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D} > > 1 > > > zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6 > > Vm*0jD > > zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS > > z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|> > > `XAJs > > > z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL& > > z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A- > > Mf > > z<-7K<$G6OrXCLF&g- > X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN > > > z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il > > {Aw9 > > > zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87 > > CC@?? > > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo- > ^_Ot?JdLg|1aj$ifpl{V^ > > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C- > R#Vcu^1XBSkb > > = > > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o-- > &31)1TQ|Q%EAhuIXZd?<`#d > > Hj > > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1- > k2y^JQ>&e<>!r+45@!bqRS > > D > > zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#= > > z8@e(3tmNqVWq`wXV!qG<JTY- > Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3 > > e-e`uBA > > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq- > a`x7HIXwJ=fQf_ro@BbDbjW+5A=13 > > ?M > > zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A > > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71- > xIa;QyQ+A+=ch*hu > > DSEC > > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0& > > > > literal 0 > > HcmV?d00001 > > > > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > new file mode 100644 > > index > > 0000000000000000000000000000000000000000..6335653ece1605cd0c53b > > d2cc2bc21d57d213dae > > GIT binary patch > > literal 79906 > > zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$ > > C9i > > > zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c > > } > > > zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I > > { > > z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7 > > MH&Y > > zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM| > > NThc > > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M- > DQkUsiWm_>>F`39z{F@w > > QiMSjA > > > zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^ > > -oj > > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB- > Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY > > zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1> > > > z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o > > OF-( > > ze(GY+PNz-|cTO$duNND)- > {Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR& > > %J > > zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{ > > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb- > jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD > > z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW > > %3^ > > > zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k > > vG > > > zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3 > d > > R&s7P > > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq- > u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt > > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm- > &}GK > > x(< > > > zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n > > -t? > > > z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9 > > * > > z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V > > 4Ni > > > zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu > > ^% > > > z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4 > > C= > > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+- > DI^9d~!WoYX0A1$ > > X% > > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=- > ;cGp& > > 30 > > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X- > )f2nzV!Q^qU_$m?x3Qsm > > ex3w > > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j- > #eg0l|9C)@T=sxzA > > k > > > zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E > > NK9U!c > > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4- > eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb > > nmP > > zDdg?>- > mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a > > R`2d( > > zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|< > > D<#} > > > zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o > > 8 > > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e- > W7 > > > zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_ > > P > > zLL$x|O2|$4_>pUK%4O!a-6#4- > alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT > > z`*O5L^inXLpWTzaUm%TSE<U`- > Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs > > p! > > z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{ > > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR- > #Ov6((s > > C#V > > > zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T > > @9C > > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&- > x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4 > > n= > > > z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ > > e > > zuk|Q9*5!@y$- > x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF > > 8^ > > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G- > <BptWKsIz=W_P31e > > > zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2 > > &++Q{ > > > zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv > > Y!Bo} > > > z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8 > > P< > > zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z > > RAE+ > > z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K > > > z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e > > g > > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA- > UumgF$+yN > > ^{w > > > zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR > > {j > > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0- > 9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N > > XFE > > zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj > > zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z > > v^+ > > > zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)# > > Yhjbc; > > > z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_ > > Rx-k$ > > zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r > > !n > > z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#}; > > @Voub > > > ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX > > #p{~VSr > > > zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2 > > 6z*3T > > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^- > D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d > > NUT > > zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s > > zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ > > > znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp > > utI > > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg- > y}h%yHH_0H > > a8<A > > > zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps > > >6Mc?h > > > z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e > > TQ%X > > zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M- > G > > 2{M > > > znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u& > > Jp > > zum8=!r+B_~0&G%_%VRj-TC~2mL- > ot07njmvdGDQXScyh?WMt%s_phdFXEx;v > > A6W{j > > z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam > > `+(0 > > > z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29 > > @ > > z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On > > @-tU=bw%s > > > zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{ > > YugQ} > > zM8N()%W_L~2Da%^cIAH-<- > an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v* > > wES > > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H- > AhOC|1BQKucrND=U^;)jo > > OarT+ > > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s- > 8ymFk^)c%duzJ;nL)3Nu > > } > > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx- > &f`Khm=*XOz > > ?S<B} > > z%8w-r#pfF@&BNC- > fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2 > > 2QC!aZ > > > ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP > > W > > z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!% > > U)1gME > > zXaJ!`N#R- > _I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk > > > z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@ > > ZQJwxv > > zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM > > |FT > > > z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M > > Re<Cff; > > > z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{ > > P5 > > zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L > > > zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg > > uoJJp > > > zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^ > > AC > > > z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f > > z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7- > rV > > rF > > zg3F-R(c*YRq-@%swU!k`8- > wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R( > > 9R2;h > > > z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs > > 08Z > > zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r > > wY > > zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a > > %KM75 > > zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2 > > > z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW > > G > > > zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K > > 9+X > > > zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S > > > z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ > > pa > > > zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds > > > zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^ > > rj9 > > > z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI > > 7hE2 > > > z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U > > Qp > > > zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P > > u^kAGC > > > zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p > > &qx > > zu6PAe_- > |zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce > > Wy}o- > > zDVg;W`B&bT@- > K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~ > > > zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV > > >9 > > zsE<cJl8QUANXMMXD!_@- > n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P > > q > > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC- > =%ubEfAZ > > @ > > > zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^ > > zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA > > R5My > > > zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v > > adA > > z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L > > ~M > > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW- > e{py@ > > Z9m > > zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d > > > zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G > > % > > > zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y > > 1 > > zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI> > > pGi > > z+_V- > c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+ > > X > > > zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj > > !|* > > > z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU > > M9o^q > > zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k > > z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y > > > zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G > > tq > > z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp% > > wS# > > > zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2 > > iu$ > > > zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^ > > Q > > > zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{ > > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x > > z- > axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b > > zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d > > > zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi > > GxV > > zW+Xgk^iMPoaLhyqRlH?kt- > @DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~ > > z > > z?VV;!_jL_mlUw;2nHl- > WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4- > > % > > > zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+ > > UJ > > > z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2 > > >D > > > z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{( > > <dC > > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i- > 6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2 > > % > > > z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7 > > D~m% > > > zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU > > wS<o > > > z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT > > h8Q > > zoJ6nV;1DH2O4gK#e- > q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO > > zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y- > ?g > > mho5+ > > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane- > R8v5Z3OKYwF7I{995>T{A1a4Im! > > )_ > > zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q > > wBco > > > zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8= > > %Fv%A > > > zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl > > ZU< > > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0- > }=OWCI_3x@ > > 9 > > > zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz > > hw > > z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*) > > > z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_ > > > z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC > > DNWo > > > zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T > > ! > > z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T > > > z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s > > B > > zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7 > > zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ> > > TQCm > > znzg- > `v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a > > 0J > > zIkAk(wATQFU}lxojL8BaMgpS*sZF- > `Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y > > z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e > > > zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n > > >SOcM > > > zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ > > %4x)R > > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}- > 7DJqPTCn{7Nz>p0rZlI4~7mz > > zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|! > > g`?g > > > zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO > > cr > > > zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb > > Z!t > > > zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3 > > l8e% > > > z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O > > (n > > > zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O > > pc> > > > zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>| > > 3uW > > zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{ > > UyAaR~g > > zku^pl=~dP2`Zfc98X!v015wP- > Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd > > r > > > zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j > > 9 > > > zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so > > Gf%c@ > > > zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62 > > 5bew > > z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG > > > zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN > > ^ > > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=- > Y=I$JBF{x__)9E*zZEmcCFhV9%@A > > |;C; > > z0dw89i- > PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%- > > & > > z>Q=`%q>K==&;cust- > ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV > > z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9 > > XLis > > zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P > > 1}jc > > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k- > w~FY#E${v > > @rK > > > zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp > > -fr0oM > > zeqF9y$w4I3?w- > jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU > > Fr1!2 > > z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~; > > mLh? > > z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj > > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1- > (p9OWCabzpEq45mFF > > oK|H > > z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+- > O > > Y}tK > > zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a > > zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa > > +|BJf > > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo- > {zTWc%6}gM|{b`5lyb8()nn?Zf > > > zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9 > > +T > > z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u > > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%- > (}mcvBi24si~mkArbb_~r3o|KZf^n7Uy > > E > > > z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{ > > $e > > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H- > 8)+593lMa!6m;Ey~fbc > > ;@zbu > > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g- > `zSeHh*X@cob > > g_J > > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H- > $azMlS<h3_eAd0+EVB > > ViPF*q=w > > zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS > > Tw > > zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K` > > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;- > q=U!pbpr~8VdgFOFb > > 5t^9 > > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9- > 6O1aqUt > > > zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9 > > QDz?mSX5 > > > z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l > > QHSl > > z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F > > C# > > > znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1 > > zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~ > > H > > zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_ > > oz > > z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K > > DGp > > zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o > > > zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C# > > v9 > > zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s` > > S > > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E- > y8jBnk?{Kg<Q(rP > > ?aP > > > zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M > > #<y@7X > > > zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P > > e > > > z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf} > > Dot > > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)- > tXUE^B;?g$~2}e > > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr- > h5P};PfpB7o>k|p > > # > > > zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5 > > tV > > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz- > o1WNRw7&EKpp!}70%&c^b > > 4h<X* > > z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ< > > GAqMM > > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q- > 5QmskD?C29B1Pr&(c@s&e+uwi>ijiC > > > zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz > > 6I > > > zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2 > > p^z > > z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3 > > z<50dfE9+W7#lo(K- > r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+ > > CCm > > zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7 > > 2*<<s > > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}- > rVwE?y%~_n0~M > > } > > > zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m > > &MC4 > > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw- > XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL > > -MC > > > zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY > > h39ZZ}0 > > zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb! > > L > > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v- > s0rJQC*k<wIAScDz1q_$t > > 67V9 > > z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M > > @O5t > > > zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X > > NW > > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3- > Je!ymF9!@&)jg5>?2{8NsyKmZu > > 0v4vt > > z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6 > > m~9% > > > zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$ > > 4 > > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls- > oKS&kVw270i?>6=6@nEFRC5Es` > > ~ > > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*- > LqT > > F>U > > z^KiUZAYXWSxqM(C(C=Zy<<Qa- > QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r > > G > > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=- > 4|~9MCtID_85v > > Yp > > zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W} > > hq > > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<- > JnxxY)Hg > > z?YX0XeW;3- > 48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n > > >i > > > z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU< > > pvY2 > > zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb% > > W=j > > > zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re > > %CCQ<r > > > z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1# > > &l`5 > > z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2? > > |b4 > > > zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx > > E)m# > > > zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV > > >xj > > > zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o > > b|> > > > zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB > > wX}s$ > > z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw > > m=%XJu > > > zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf > > XFK > > > z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87 > > omSx > > > z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v > > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#- > 8~w<KRe>5t8O19tX > > VdlKcX > > zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X| > > zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s > > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza- > 27uAu?{)Oh > > > zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1 > > u > > > zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll > > Tnbb(?( > > > z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L > > W5JPe > > zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT > > G > > > zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x|| > > &@ > > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B- > qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y > > Sa > > > zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw > > ( > > zY^$M(f1CD!4Fn3S@`Lx%c?j- > wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac > > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7- > Yq$ > > gRd > > z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA > > z8K_Ar&HHJwu<-S7^&Tz- > z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D > > Q{Qdr > > z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz > > > zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l > > h|` > > zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H > > d> > > > zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+ > > p8T > > > zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi > > Z`#p > > > z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK > > G > > zO!{{Gr- > ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N > > z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E > > QFcnaYc^ > > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe- > {}E&CO6a@=<Y;tXT*n > > V6 > > > zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC# > > 52^ > > > zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j( > > V7D7 > > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u- > U{ > > b > > > z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t > > ^wM9? > > zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs > > K25^ > > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff- > KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt > > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|- > EFP&Y*s>3Yf2)ZCTs)~ > > gJ+ > > zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{ > > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G- > PPJ0 > > ?Kf3 > > > z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o > > Qo< > > zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o > > UA= > > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD- > X_KaBxie|nwb|o$l{eH#^hvv27< > > Qn > > zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn > > D@ > > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb- > jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U( > > z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ > > > zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$ > > %Qo3*6 > > > zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m > > 9{p > > > z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ > > +Y > > zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl > > > z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE > > 9& > > z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$ > > &>8io > > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb- > OZgaoXUvS83(PBK8FLxH<rd+PcVL > > z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr > > @>iU79 > > zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl< > > @ > > zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth* > > NP > > z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_ > > <h1r2 > > > z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U > > U^ > > > zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S > > a#=2pN > > > z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T > > KI > > za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp > > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh- > `^5g98TqP_j#KdfRYD|0YNGFhOt4 > > #( > > z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy% > > MXI4g > > > zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc > > v > > > zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA > 6 > > 3 > > z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L > > P` > > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&- > acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z > > G > > > zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF > > Xihx > > > zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg > > ~d{ri!Y > > > zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{ > > > z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_ > > z) > > > ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi > > x|! > > z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G; > > *KA > > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a- > 2i*w9Y1kWggcE > > Az > > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz- > Yc~Qsu2kWQ?O0sIz*2Ug$6lF > > 7j$V > > > zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN > > bAk > > > ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc > > @ > > zi|8mSqO-MoaYaqA_#}w?c- > >nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G > > 65>` > > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog- > (Rz@ruT7zBf!)UI > > W~ > > > z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T > > `E > > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^- > ^WD > > % > > zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf > > zTyu*%V(L_|%5}>KD68- > 34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy > > 2 > > > zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr > > ^+)zfc4 > > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#- > Uk>=DjJl057_mpgxax|_Z7^eE > > *fBXa > > z5_DRyRueL^- > #{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;( > > z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg > > & > > > zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB > > z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&} > > h > > z32!E$+=MZ91HfdyI-J- > l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$ > > zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m > > @ > > z7tPMl@iqfxzh@Lj$xc-Z{m@G- > GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P > > nn4< > > zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX) > > q( > > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb- > qV@_uT2r9>Pn}r5o@L|E > > Y*YV > > z0`B%7x?w2<&7x>az- > wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1 > > m0yoPLQ > > zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y > > > z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W > > mG > > > zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j > > sD@ZJ > > z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28 > > 9!| > > zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR* > > r7a77 > > > zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG- > > z- > 09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e > > WrXO > > > zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC > > TI > > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk- > v)o<J5KbA=o=@`(r5hoYx > > Mi^ > > z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6 > > 6N > > > z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO > > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#- > IZ<w4%qoDyYF%VJC8 > > ue > > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n- > wj*c)&TK > > 0t? > > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm- > qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~ > > z! > > z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56 > > MWm- > > z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92 > > W=k > > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?- > nog7X%sk_s<Y+v > > *t > > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo- > `!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F > > zbCM2u?}yBTP-|YUP+qtE+N- > $^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8 > > 3OR > > > zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc| > > ej > > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{- > f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~ > > Y > > > z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5 > > mBp > > z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K- > 6r > > 9Of1 > > > z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB > > H* > > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX- > uT&S > > > z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B > > Z5=er > > zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c > > sNof` > > z=Hs3R{$%c!jWY- > L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP > > ` > > z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0 > > bt > > zlnR+ZB=thb?WfT~!j<x<0- > aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u| > > vh > > > zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7; > > J|z > > z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0& > > z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N > > YbY!ry > > zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX > > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2- > <QnUzm@<!39peL;+M > > Bzl|M > > > z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_ > > EO7gN > > > zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6 > > $i > > > zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX > > n{Of > > z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R > > @dv8E > > > zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@ > > YK > > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We- > #w4(vmfn?Vr > > u > > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6- > 4f(+RJub`mui! > > Dw > > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl- > }yeK=rbpE2k2X > > KXQx > > zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&! > > 6 > > zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj > > N > > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf- > y^iZn3c@baZ{@GX$an^4lQ&IToF+y > > zyt > > > z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd > > z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a? > > S > > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di- > #FqXjnSNMO_Y*e|TkzT6w > > L > > z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N > > L > > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!- > s9+9*KOCp;tUhBW(x32 > > DqHX > > > z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+ > > ( > > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y- > Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w > > X > > z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq% > > K > > zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel > > > z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j# > > +q& > > zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t) > > MFP > > z2e~I-K~cSXx8EG)lzE+7@73IePhx- > ;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL > > #F > > > zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5 > > ~|o > > > z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f > > zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf > > > zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af > > A<3 > > > zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw > > FM4a > > > zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD > > >YZ7` > > > zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd > > W<i* > > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q- > dnOip*0`sN2T > > a~yG > > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk- > (q@M > > TF-Nx > > > zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{ > > ` > > > zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra > > OZX > > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW- > kGO+`xCf>(h{Mcc > > %|2 > > zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE > > > zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV > > -5^$B > > zPbdR=b%2- > pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L > > ? > > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2- > pNELfG(uNbq{doFM5MP7xlb)Rgq > > < > > > zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N > > DpUF > > > zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q > > %wi~ga > > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW- > 3aN5iiL| > > ` > > > zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$ > > z > > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+- > lbp!I4w9ZnT_6aMT~=LLkg!$R > > l# > > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c- > lmKVwD > > 3GSE9z( > > z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE > > > zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw > > bk > > > z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo > > a9>Y > > > zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(# > > R > > > z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@ > > K > > > zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9 > > N? > > > z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw > > K > > zdildOB}k13;#BI@N5b9u5s- > {=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp > > z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w > > 64j > > > znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>| > > sB > > zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r > > zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL- > $T > > m> > > > zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1 > > 3i$ > > > z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k > > G5`&V > > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng-- > HdhvEg > > EU > > > z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4 > > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$- > Q%t!bC > > $cv! > > z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO) > > Br- > > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C- > 8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ > > 9x`@ > > > z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB > > Hp} > > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r- > 2YOPxyr* > > b}> > > > z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A > > DU;X > > > zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@ > > bS > > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|- > W+1H2CZtdm > > OT(s > > > zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J > > zwr > > ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$? > > Zisq > > z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo > > > zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp > > < > > > z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~ > > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x- > |BgIJfi=ju7@WZg- > > yi > > > z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW > > N<+%Xc6 > > > z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v > > Gh > > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep- > 0s*6L=4RuZ>k3UeD`pkpd= > > K6 > > > zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8 > > a1HxFs > > > zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY > > yJ6 > > > z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR* > > & > > z- > =>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk > > f > > > z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJ > G > > f > > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C- > m=TI!deWV<@u@B+g9zOd!H<h7 > > 6 > > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H- > !7w?@Nm!4fF|H&)>RG9@xH# > > VA%Kj > > zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M > > 3@ > > zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x > > zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL > > m2 > > z`KG6~&Y4#$- > >{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO > > KIXO > > > z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L > > NUGvT > > > z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr| > > %C > > z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S > > $~q > > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o- > IzYg)#61qGsUJ > > @X>V > > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY- > L2ha3l(|O > > P > > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=- > neefemATL|%SeTj > > 7KM > > > zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc > > e > > > zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u > > L7 > > z!mV(@!YY)C1EI1tx4- > 6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x > > $AP > > zwpSBL- > W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu > > yMC6_ > > zOF$m<BQ- > 2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI< > > T&4! > > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~- > ^iTXueIx8byvHT>hu$|i_OeooSft > > n > > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV? > > zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1 > > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%- > W88*^zKTEx>j2)~V > > 9UTQ`* > > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V-- > kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL > > 57 > > ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V > > z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL) > > $Zo2 > > za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I > > e~kMH > > zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?! > > %!FY6 > > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K- > s2WN^ui3C{($wPhZa^$pzWR^Hl > > 3F > > > zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw > > 4<G > > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt- > M7|}+UXRU7h?~TB=)5(t0^!( > > %P > > z- > F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc > > )h3ea > > z6- > G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W > > Nvtc > > z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O > > B-A > > > zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV > > vU`(H > > > zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW > > E37a# > > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o- > gou2?WYbb69sCMC}^w$$jzUo!Y& > > ! > > > zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm > > z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z > > # > > zq- > Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV > > L > > zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;| > > > z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO( > > 9zDJE > > z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p > > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p- > ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I > > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6- > fqr2rZ=VYP@rHCOq9pf8B0xw@Y0 > > Q|UG > > > zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY > > > zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#- > > G > > zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X! > > we > > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)- > H!*m0eZZ!QVFvyXV^=j}!Z?!plq > > > zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h > > 3 > > > zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43 > > 0oJ > > zI(_U{Z0qELvqlo1zMy(- > joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq > > I+ > > > z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+ > > VXJD) > > z- > q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV > > YY0B > > zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC! > > P| > > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r- > *H*VR4`LaS<<C1W7hg& > > ~pO+K- > > > zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM* > > ANN > > zUz%6;oPCB&&k^}WT*2fbT- > rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)( > > t{ > > > zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z > > 4P > > z{MfuNHeOI7d~NQbki>Wa*r?}Ta- > }c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw > > nR7 > > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&- > v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0` > > %z > > zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y > > O|w1& > > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih- > 2{<n)!I+;AHbRo*RPPJ<gUm%2 > > u > > za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP > > d~+Gh > > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj- > > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?- > BXUNalABrN}l?3DDjuoNkTNq%YT7 > > 3F~h > > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV- > S%|a7B=tS!rdlDQnw_~vR > > NG+ > > > z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI > > TI9~ > > z80}SbU~>FO|9I4K$=- > QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@ > > JW;6 > > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=- > TSOTON|2ebg0xls`JM}%@O`g > > K > > zmH+=v*cCg)>)6&*G74T9ntba~IB- > 18Gfz;WMB^neWL%=F6kixs3>vAmMHr<# > > a{F%5 > > zSV4%6rVjJ{9oXWh7>e;x_5=7- > ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@ > > Cxn#6 > > zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4 > > z!jPQ@A+Wb%GhI- > D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av > > QoVl > > zpg?U5sxJ^- > s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU > > u2u > > > zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH > > Y16t > > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l- > Fr_U^mpQywF > > 7_%T > > z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a > > mi% > > z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j# > > @z5( > > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi- > XyKLb > > hKa > > > zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p > > > zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt > > i- > > > zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K > > 9fOo`p > > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs- > ui){uM_Y;pwOERO_ > > ?nhh > > > zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp > > !5R#S > > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q- > UO22MYfNY > > *&sB > > > zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1 > > > zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN > > 1K > > zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt > > zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr > > |TU+ > > zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@} > > qgr0T7w > > z<XUd9YdH`MV%gjTsUwYem- > CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2# > > 7kIj!) > > > zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D > > z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx< > > D`^2 > > z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0 > > O > > > zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w > > )9* > > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz- > xEr*zAK9 > > <N?Y > > z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F > > &Xs > > > z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx > > qkyHve > > > z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp > > E(bW+ > > > zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II > > z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a > > > z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K > > 127i > > zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe > > WR1yd= > > zOy+GS3N+k- > ;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X > > 8KHw > > > zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM > > wuHG > > z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T > > NTye@ > > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+- > 8Mp5YQRWhyS@`gIr&htF@U > > =BD#r6X7 > > > zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp > > i=M9v > > > zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9 > > f4 > > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f- > C*U > > }T > > > z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2 > > T=@i > > > zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_ > > &ip > > z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED > > M > > > zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F > > Ya5e > > zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A? > > N> > > > zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n- > > -MxQ > > zG1h%OC9O9yC%If5t*4BIdz)$gh>- > Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q > > MQ > > > zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV > > SbVYbX > > zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`% > > WvX > > zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS > > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d- > XA~5}VSN6cplAA%P=_p4Y > > qn~a > > zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q% > > 9};T > > > zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w# > > X`^h > > > zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_} > > Ln= > > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw- > J{yCA}t$O?2Gbro_S0%@6bE|NUO7 > > 3JAX4o > > zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM- > 0 > > <2 > > > zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT > > D9y$ > > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4- > pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ > > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW- > 8FRu~9(wk+ock12GT_ > > Ja > > zM^?ezBrqptKLHwLt1X- > 1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0 > > #5 > > > zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82 > > +` > > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF- > GVJ3Or!j$S_H;Jw > > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!- > _c(_oR > > c| > > zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu > > ma= > > > zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW > > Kn#~- > > > zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO > > XKo0` > > > zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f& > > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v- > Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3; > > ( > > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y- > BrsYiU;W<x<Ea;>dpU > > @ > > zmR>$-PfosIWz(r5(5<wxPbjmo;#- > XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE > > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N- > z3e*X4)s#1kO^g=a > > {~c > > zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl > > z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84} > > qZ > > > zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1 > > vI2 > > > zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP > > |K > > > zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@ > > +3pvf > > > zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc > > 7 > > zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l > > WtAe > > z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$ > > w2^;3 > > z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7( > > zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844 > > > z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP > > oM > > > zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+ > > zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j> > > aq > > zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`; > > L2G > > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu- > hUH$wa > > RbE > > z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6 > > mTGS > > z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz > > w= > > > z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID; > > @ > > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb- > Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix > > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F- > ?Au{0G5tdd)TPX1hakJ3TvR90rM<^ > > Y > > z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa > > @~k)f > > > zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m > > L4-Kc > > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!- > _hOdW0;F- > > OTOp > > > zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!= > > X+}$ > > zFuvZ~++1ipISzO)2)RT}D;- > aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7 > > = > > > z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7 > > GW > > > zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU > > ePA~ > > z_hxdvS8- > a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E > > z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e > > zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(- > > C#Ha|I > > z=C2Ea@CE*LYY3?FwL2- > o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn > > be > > > z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A > > W=XSe- > > zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns > > zM- > {9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs > > 456yTg > > z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U > > XC > > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_- > =gt@_z#8g{&FBl60M > > 8q > > z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl > > < > > > z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+ > > <`F > > > zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v| > > da* > > zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv? > > e > > > zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM > > P?$BB > > zOd-J<xYW8H1RRa|E>kVw- > `TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da > > kHuGSr > > > zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z) > > P > > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r# > > > z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl > > bN}< > > zqLB8`- > ^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX > > u{1 > > > zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ > > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq > > > zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX > > )z(Tp > > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD- > jHBwcr%2 > > 0bUM~ > > > zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm > > n > > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f- > bCjEDTbbkioa3 > > AvU > > zTgs{woXY3O- > Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw > > FPeX > > zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh; > > z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G > > 86v > > > zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu > > JvQk4 > > > zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An > > t>wSc > > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af- > Xuf0lKfuTpKFA04 > > 1 > > > zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I; > > hr > > z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+ > > wHXl > > zz&1Drp|7~EN?!zH5pKw!JvbXK- > ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B > > C!KO > > > z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug > > B$R > > zx6k>}- > ^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg > > > zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD > > ;>-$c > > zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM} > > > zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO > > P{<K > > zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB > > G7 > > zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln > > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7- > kO_`Up!D&o+Zeo37N~wiT > > 81j > > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e- > +C(B!Y<Aj46`65i%71cYGD{ > > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;- > TI~; > > EW > > zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n} > > xK > > > z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I > > > z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd > > nlbj > > > zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05 > > > z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j- > > Y > > > zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^ > > 7 > > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0- > O=A5+6B7bE > > #7 > > > zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ > > !$pK^xF > > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn> > > > z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf > > ma;W > > > zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i > > xTr > > zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X} > > ms > > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D- > ^e94<`cGBaYaA!4zd=KEsJn > > eJ > > zd%}Zl026m#*+6#l9yFz!8d8<- > XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i > > } > > > zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+ > > zD#6R=4Z52d(S5iva$jQAz=xFyN- > q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~ > > ( > > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe > > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG- > UmfNcjAaL > > Epl$S > > > z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7 > > m#Z > > z1f>)aDLDPf#(_xvLI- > F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g > > XhRr > > > zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f > > zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_ > > <Ne~e > > zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S > > > znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p > > 2%fV|*A > > > zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F > > +?= > > > zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D > > 0 > > zIugZZoN&hDJvgzTn^^1- > d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X > > uR > > zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y > > wh4&L > > zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9 > > v > > z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y? > > @d>R > > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO- > x&lC0KfJO|C8kgnlMCC`W~^izTp? > > z > > > zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$ > > )4 > > > z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj > > NU_ > > > zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L > > wJy > > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o- > D+M > > C? > > > zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R > > @B3p > > zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p; > > pe# > > > z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg > > Gu > > z<x;1&YdE7!dLGg3LR#- > vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H > > xN> > > z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45% > > zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh} > > R > > zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!; > > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`- > <Skpc > > > zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI( > > zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck> > > > zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1= > > O7 > > > zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ > > Q > > z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$ > > &S(O@ > > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{- > gM3Y^a > > D&p > > > zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C > > 9 > > > zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw > > R > > z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA > > Ms? > > zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l; > > EF=S > > zx7~>-e-- > gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi > > fo > > > zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d > > P > > z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx > > RVQs > > z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e- > eJ > > (bu7W > > > z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY > > jt9 > > > zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW > > > zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M > > M>h@k1 > > zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^ > > zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7 > > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2- > Z~r3V > > 4w4#M}^k > > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7- > #MPr;?r3h8 > > kN > > zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF > > ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p > > 4&oPZ > > zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V > > W1 > > zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?* > > 5gM > > z-dO<=pUw9Hu!6VH- > $5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^ > > P$ > > zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D? > > W@}5 > > zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8 > > _Vr > > zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G > > Uu > > zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M% > > 7_V&j > > > zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ` > > > z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG > > z--mu$ZE#I*Q8<#GJ~- > LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts > > 5J#$S > > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`- > h@bk9 > > O3s > > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S- > y+h< > > ?#Y > > zk-Qk=flDo- > RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu > > z+C9W1IPvuo^Z|- > GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw > > VT0 > > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy- > t?t~fVXzqFG>P(y1EoKn > > x2hb > > > z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b| > > +mG > > > zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D > > !#34 > > z-*FDsO~mox- > k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93- > > 5v$t > > > zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO > > CE > > > zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z( > Y > > z)aDR~xD1dzXmhus5Q??fihY8I- > ?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1 > > QMq > > > zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@ > > H~~ > > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT- > h%26Z > > X# > > z7~{-@v;G{8Lxo0@cHdz4T{- > P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur > > +Z > > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6- > Xr9n > > R6 > > zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf > > w^ > > zZ3$IK{RGVZe9g9- > KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul > > qu_{W > > zTj#6IYv<7- > Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7 > > AD > > z{ZzN7#^JAPYu-X7Y- > 03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{ > > uPf9 > > > zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f > > 4A>iW > > zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d > > &( > > > zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l > > # > > > zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_ > > _~%; > > zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki > > M#a > > > zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D > > vAn@ > > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0 > > zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l > > zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~ > > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_- > EP9=wZkWSqwPf`a`R&_k > > |@1@ > > zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj(( > > |{) > > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$- > (zx$a > > ^1S > > zX!<JR+joeIbZEYtIBvgBnl#LV4- > NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g > > | > > > z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp > > zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b > > z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg% > > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz- > khs!4b#@5QjP>U9%zLiUFG > > ~av? > > zeUJ9-Dv~3N$B!appHtL@3- > IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q > > 46kGa > > > zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y > > E > > zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm > > ppAB< > > zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+) > > 7 > > > z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v > > bV > > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT- > 57V;K;+syy?R+C30w{q70#TZ1 > > (Ev > > zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V > > @y@+N~R > > zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I > > > zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k< > > >s > > z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ > > G+U > > zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U > > S > > > zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q > > HH0-&U > > zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn > > znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt > > > zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9 > > _?krc > > zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF% > > zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(| > > > z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW > > p_`g? > > zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^ > > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof} > > z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^-- > > > zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x > > `m > > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA- > cq+Wq%`jv > > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i- > +%|*Ny& > > A > > z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA > > &6k{Fd > > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5- > JAQI7W$ > > CZ<;` > > zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S > > OsN > > > zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj > > mz-w > > z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR > > 7~ > > > z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3 > > D{ > > > zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S > > UN > > zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs > > mu > > zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m; > > Nu2W > > > z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk > > V!}} > > zz+g- > u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y > > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC- > xL=Y( > > GRx > > zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q > > zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii > > > zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM > > XGy > > > zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc > > zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q > > VM > > > z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU > > > zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E; > > iUxRR > > zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v > > > zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s > > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<- > rUD)H9&S > > f@E > > zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn > > >#iM > > zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5 > > wX% > > zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@ > > > zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP > > z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298} > > 0gs > > > zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM- > > rJhB% > > z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k > > zPBTLqcmk>G0PwmJ^W#xC- > O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6 > > 7AvC > > > zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=; > > ?! > > zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*% > > J?t7L > > > zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D > > K(~ > > zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL > > zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD > > z*w1fD++$^@e$D7^UGJgf- > rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3 > > <D > > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p- > @)*^ > > N(5Ei! > > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$- > P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu > > ~ > > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP- > wj@j!4#6iMbDW)MruAkHCb1Nqxw > > NM{ > > > z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb; > > P_l#tb4g > > z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P > > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57- > ^*tCzH+>d*z@3AV|%h%!1NOg+zH > > >^N55 > > > zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h > > E5}(1< > > > zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t > > @BwZ > > > zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t > > ag > > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ > > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA- > S)#DE > > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe- > +OTZJW>x%V > > y > > z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz! > > Q? > > > zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW > > VJ > > zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT > > @L_3c > > > zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq > > w?L > > zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw- > G< > > ~n& > > > zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC > > {22 > > zX- > I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4 > > dD% > > z<YEj;4*V+0;|M- > rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes > > #~ > > zqZrF<mFWvzkmFGC{3- > LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d > > G1& > > z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v; > > ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA > > z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+ > > > z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd > > ppY;|*f > > zdVc@~A9~wr5$E1you*)8n4i?F-- > }{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l& > > wBh > > > zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o > > wnE > > > zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54 > > +~m > > > ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R > > Z> > > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z- > WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B& > > MMf > > > z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)| > 2 > > aiA > > > zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8 > > ~=75zos > > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g- > QOrn > > %{ > > > zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$ > > Wvx > > zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P > > Q5^ > > zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q > > AJ(0a~# > > > zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D > > O* > > z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN > > #0-* > > z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD > > NuPv > > z8A&gM+yWoI3+p- > Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm > > Rd > > z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki > > No!Ys > > > zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S( > > B7X}h > > zVR;Et%eD@V5- > g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3 > > #N > > zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx > > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}- > 8k0{FELICbyZM7w > > lN > > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{- > JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb > > iKo8 > > z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV > > hw$ > > > z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz > > = > > zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe > > Mux8; > > z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*; > > =YK > > zjl$=}dcQ- > TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr > > > zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj > > c > > > z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY > > 3VqP > > ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^ > > b4_ > > > zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k > > > ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC > > 6Q_? > > > zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{ > > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;- > zV}=Ffb;y0 > > z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV > > 9?w% > > > zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$ > > `2Z9 > > z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK > > MQo > > > zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$ > > #|)V;RX > > zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@ > > Ox5H > > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD- > VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{ > > # > > ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv > > <E={9 > > > zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua > > {h > > z1c&pk*C&s-u!f*^mD<d?d91- > {0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{ > > 71|@f > > zqyCdPYA>=Yf_ZfXdKIQ7K- > BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS= > > *8 > > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz-- > =+yEpn0V;dyO#f3 > > quY* > > > z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN > > n#x > > zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7) > > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp- > >DBbJFmh > > ~ > > > zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc > > 359 > > z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP > > > z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42 > > R > > > z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR- > > }t > > zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc > > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E- > c!f2kMR<>)RwV=hmWjbJxmB > > OGSp> > > z=zoS%q90`C_3r-1I|(vxy$L|<- > ~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53# > > E3 > > zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o > > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm- > eR5re6n!d6@_6hyx( > > I78k > > zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY > > Wssf9! > > zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ > > > zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P- > > %+f< > > zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G` > > > zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd > > j+el > > zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G% > > >t > > zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@% > > Il^r= > > zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg > > 6d?0S > > zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c> > > }u > > > zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh > > +5 > > > ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V > > bfpO > > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W- > !~C&zci > > |? > > > z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT > > h?j > > > zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4 > > 8K^U > > > z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+ > > 9a > > zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM- > > Wn > > z9YL6MHz1*R`Ebg>i(85{!WP- > zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M > > $< > > z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<? > > > zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk > > zjcnO0FC<- > zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP > > c8Q1 > > z>8<aHYtJ``M!kq=@76^J=2^>e*+- > ?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS > > z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb- > > KY > > zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@) > > {}ye > > zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H > > X$b5|#j > > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee- > d!ko~1?$I;0XQ0Lcy}V_T > > M9HH > > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M- > xe{E>sl9(>CA<_JNmMi > > xd > > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP- > t~(*7E<kqy26Hww<ma171sv > > !t#Q > > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X- > XGl*%Q0ElH2aXP)|ASi9~aI8 > > )Vn > > > zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s > > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;- > *c4|rL<x*=v#r8 > > > zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$ > > AaI > > > zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M > > -hX > > z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x > > B > > > zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x > > kdv8 > > > zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH > > Z > > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm > > z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv > > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g- > dTo#iWkSVwCW1XNNk>DTg > > aD;g > > > zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF > > WS_L$5 > > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk- > &zLAxDgQMl#h~ > > l)AM; > > z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK > > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm- > $hEIpj?<LiYD}ov|o=<+m77@%`dhAH~ > > ua > > > zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5 > > > zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf > > }$y^xf > > z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y > > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk- > N;TT > > N~tt > > zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o > > zQ-15yS^!}n- > @U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M > > Y69Y > > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A- > Rih9xWf6KdR0%$1u!qOps1C2Q# > > ANP > > z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u! > > Dqgb3Ca > > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86- > gbBvpzX > > R > > > z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5 > > T > > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj- > hIrr3a)n*V>r6m=eJo=M3#L3_ > > &Y > > > zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7 > > z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^ > > =n > > > zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ > > IJm > > z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9 > > z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz > > g5f7(M > > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG- > kU > > G* > > > zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no > > Oj > > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)- > 2TC_XY^XyU+7`Q)it$=yI_HeO$| > > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}- > n<&rw6V{rKB|$Og > > GoBpL > > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf- > ;e_A#;c07yl@emICdlfx6?S > > zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9- > W > > Pr4Do > > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x- > OHJh=>^ > > %$z > > zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf > > R=j_i) > > zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb-> > > N#* > > zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_ > > zLs>gSMg&%IxgXVsk+G<1aLQyI;+- > (x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p > > 4d > > > z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a > > O?%3UXP > > zmxkemLOe-bD%O81OOdPv56yFNIJswr)- > r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR > > n > > zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W > > 5H`Q > > zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=) > > @EPJJ > > z!!F00iIqj9<FImx<- > TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu > > Z > > zA@6GBn_*`<fZu;fKyYcdsVz- > LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb > > JP > > > zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD > > > z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o > > &q > > zxj*LqEY-ZnACrceN- > ~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573 > > zN&n5k9DfdGDn-n*utQW4V{X- > IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP > > Mq2Z > > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4- > Y(zEt0m3<zZQzZOBUz > > lhe > > > z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i > > ! > > > zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v= > > 5E > > zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2 > > U3cy > > zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL% > > @Pb > > > zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W > > T~0Y > > > zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f > > 3EE > > > z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt< > > {8Z-8 > > zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE > > m16 > > > z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4 > > LVb1o > > > z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@ > > x0z > > > z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn > > ~4&d > > > zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu > > G$}Tz > > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ- > Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@ > > =?WW > > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I- > )fwRt3qD8qt( > > { > > z<P<KF=}PJ1#r#`jS-C- > BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a > > (X > > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB- > $@AJqDd(YoB@ZYfK6vP54O > > =^o2 > > > z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN > > g > > zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(; > > P > > zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD > > mu > > > z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF > > {3 > > zwPHdUsL_Emi- > |sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx > > tn > > zbrc)1<0dX~X#twYtTp`&I- > K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ > > n > > > zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5 > > +#Xc > > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%- > xVei > > qO1Hf > > > z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU > > <cW > > zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c- > > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?- > up`F97 > > _ > > > zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e > > PVQj > > z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT > > z4)s@IGNTe?4-@J{iz-J0sXQl- > t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P > > U} > > > zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}& > > jB > > > zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9 > > XPvK > > z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck > > N > > zH}9#C6|qJ(- > ~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb > > 5c > > zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx > > C > > z(- > KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr > > | > > > zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS > > n)edp > > > zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh > > 94r > > > z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk > > Q; > > > zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS > > z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B! > > zLKgK@^uHSZLNEF1>n3- > )R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP > > T*O > > z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL? > > zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB> > > 4f|! > > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF- > f1_RXCi@Ib*0 > > z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4 > > 8XtM > > > z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi > > Vn > > zP5ZAFYbCS1g7- > `&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G > > uEt > > > zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N > > Vpdll > > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a- > 3`@t)z}?8R=?u@$Rw&yc>*^x > > > zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{ > > %xn > > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0 > > zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5 > > B > > > zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm > > 5jhv7qJ6 > > zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs > > G&n > > zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc > > X7Yw > > zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*- > s7 > > b^ > > zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm > > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR- > qjhh > > O > > > zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)| > > CS > > z^GD&-H%jsm7i~c(IDGo_- > ?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y > > w > > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h- > %XTOuIK%jeRlC4YOaKdYsipAm+ > > WrxJ > > > z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_ > > emtz| > > > zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alV > q > > N6 > > > zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ > > 9VH > > > zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td > > R > > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm- > z5jm=aFjj$na3>$mvN|33HD3iFuOn0 > > va3 > > > z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k > > > zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic > > ; > > zO)ScHYd^W4>p1IZF- > rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I > > nuw > > > zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq > > ~p!H > > > zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR > > z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH > > @xAy1o > > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;- > FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq > > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb- > d5Kj>373=4;|gla3^9<xGWqY!YN > > zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF > > ^ > > > z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe > > z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)% > > 6TeU > > zDai3Q)sDP}fd8!F4@GgYGt3O#w- > T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=& > > !# > > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ > > zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A> > > JLS > > > zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B > > ^2@xF > > zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo- > 1( > > TU>k > > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q- > I>Wsn^_=%oN0?9m<2++S;$}<NQ > > !2w > > z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y > > @4wr+ > > > z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW > > igCND > > > zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G > > f > > > zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM > > +HRe > > zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7> > > za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!- > N| > > - > > z;QcJ- > _4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2 > > Vq6r2 > > zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y( > > > z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X > > ^ > > zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL > > z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o > > @ew > > zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij% > > 2fn_q4 > > zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`> > > =! > > z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw% > > <b > > > zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d > > {;+cG) > > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z- > 9KqzX4ywpKgSlL&Lplu > > #f5K > > > zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN > > Be > > > zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb > > `1J > > > zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6 > > h9# > > > z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW > > Ts > > z@juu7- > 1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS > > pa} > > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;- > DANP > > e- > > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O- > 5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5 > > 6 > > z4%Obc4bQ}m#H`ZWui1dCf- > 8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q > > a > > zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K> > > Mz > > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4- > gIH0R$|yhL0%iyEWP) > > -dMFq > > zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4; > > zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(- > # > > w5 > > zSQe21- > iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH > > > zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=- > > h3 > > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#- > u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6 > > > zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V > > B > > > z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii > > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C- > NcZPpT3FT+YGkGFM > > 6L6 > > zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3> > > 49;t > > > z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@ > > ZoU > > z1o^bK^- > i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e > > <06 > > > zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23 > > |; > > zI- > 8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0 > > p%hX > > z-z&;- > 5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{ > > O2 > > zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(* > > > znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf > > > zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL > > mu > > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt- > )j9cW`J=^32#Q > > _0v= > > zYuS>- > !$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4 > > T3 > > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d- > y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%( > > U > > z6;SpLK}$lNH+Qlh-cKR- > YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>& > > oV-UQQh > > > zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U( > > c{ > > zfIZlR!@- > s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld* > > > zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e< > > WpJJ > > z- > `$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ > > N;@<uUxT > > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@- > auQ<`tj > > RFOs > > > z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A > > m > > > zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A > > G > > > zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB > > e+D$Sx > > zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-| > > z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7< > > K > > zTOHkDcgdOyfsEiOu%WtEi(>#Z- > ~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY > > u| > > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG- > KacrZ > > _ > > zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG> > > N9F > > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U- > w88FH|Vp0NA28vf|sjS > > i! > > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt- > fK$0VNHs&Mk>^C1D > > > zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce > > z$GM4 > > zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV? > > ?+@e > > zg`wK!-l8aDa_m35OpOA{bq~|+%F- > ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ > > { > > zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY > > > zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE > > f!T< > > z2ci!iV-wM?Bu7s^Huqb- > 4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C > > Ct6d4 > > > z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p; > > %j) > > > z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu > > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%- > (2Z`Wl > > @e > > > zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1 > > Smv > > z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE > > TIA > > zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH- > #T > > #5p > > z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV > > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS- > W4+WUsh43&>4RG*{QQ#GI!w > > phN<ut > > > z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O! > > 8 > > > z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC > > li > > zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF > > no2|(R > > > zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS > > 4D; > > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R- > Jpx~r9!pm?4kz;k|ao%zB@5Hbe > > < > > > z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV > > $~Mw0 > > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM- > j_UaA > > x<g; > > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu- > o$d)MnXpluW?a_({zl > > g > > > zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^ > > Nsh > > zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^ > > H> > > z@#^- > Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5# > > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd- > Ge_d>@ > > =& > > > zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK< > > zN_8RoATaW}d{5!m3i1gyT+$O()xZN- > q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n > > z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8` > > AC$53 > > > zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d > > 7^x3lQL > > > zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t > > ^ > > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n- > ;m<n!p%lxe5r| > > zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD) > > S* > > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8- > 9ip&dZ > > 5@B > > z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja > > > zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D > > @Lj > > zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_` > > ?(Q=eq > > > zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su > > ! > > > zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n` > > lly-i > > z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77- > ?_ > > D > > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=- > #ZF|U1if%4r0!Fqa4AKSYGr=Bp4 > > wS;j > > > zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f > > B > > zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w > > SvXa > > > zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg > > @KJ > > zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL` > > =` > > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q- > |Gt8<U$^Rmw`&o%H;FN+S+(N > > H@-}E > > z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx > > qT > > > z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ& > > z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7 > > v#qf > > z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp* > > M& > > > z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf > > zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!% > > R0i > > > z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C > > m*DkC > > zHs9kcukmSQnY-`;FsIMBQNgVP- > Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd > > 6 > > zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU > > 7F@} > > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI- > W354EXdcSk^K;5aK > > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)- > a48PghrZ+3AO}YN > > &bdTo > > > ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk > > ce > > zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c; > > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO- > KB7MVoi > > X`~8> > > > z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E > > h > > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe- > jybQSioRnO > > 6 > > zpm;JeMEQciVCPbow+)K59- > z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs > > X$9 > > > zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps > > 19 > > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM- > V3W7dJ0WrB4 > > !!+0k > > z;zYZk1x)Y5=+Q4I`1dZe_- > J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~ > > h > > > zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY > > ^|^o > > > zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY > > w > > z8&- > yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_ > > Pl}l > > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn- > cjsU7u?E8Rr%=Go&yh&47sj4 > > @fk~gw > > > zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz; > > Vn > > z- > 7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH- > > #bB > > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W- > 7Me#XrQ^Tzt>kfFu8R(s > > Yw > > zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi > > G > > > z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=| > > B > > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU- > `l%kXo|H)KHVD6KW > > h*Rz > > zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx= > > &< > > > zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT > > > zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr > > 1> > > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx- > gL}d<c_Mn^@%_FE+g > > ?M > > zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB > > m<8{ > > > zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB > > rHu > > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB- > gw(`|azE*a<_S1weMZAOo%w(L > > )Kl > > z- > dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_ > > 3&$$E$ > > z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3- > B{ > > GV > > zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s > > > z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d > > N > > > zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f > > E# > > ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l > > 27AMD > > > z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql > > amYM > > zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE? > > zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7 > > W<MJ > > z%- > SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH > > R8=T > > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo- > @a)b+Ml`1F<g{$T*e1di)$*fQ5m > > |)PQDO > > ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8> > > ;g4 > > zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF > > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA- > k%PLdC*dz > > w1? > > z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c< > > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G- > H!u*oMbA8 > > 4$ > > zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q| > > > z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd > > WSp > > > z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK > > !+9 > > zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq% > > zw_MRqd{G)1`B`l*- > mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg > > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~ > > > zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA > > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6- > 9?bOShFo2W$of{J{ > > gHl > > zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y > > $TzS4WWp > > z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_} > > > zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7# > > T9bz > > > zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r; > > 7VlOw; > > z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g; > > > zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@ > > ~Q`G > > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s- > 2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v > > z8QwfoitD*@- > 5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j > > ~x > > > zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o > > }${B{GLO@ > > z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO > > > > > zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@( > > W > > z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r# > > JmFX > > > zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0 > > TYK > > z-`2+H1Yr#7j9>- > Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M > > $i > > zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@} > > 8Q- > > > zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB > > {d;Z$ > > z>%q~GMLth%$)7kc<>- > ;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX > > =3xm > > > zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2 > > eba=c > > > zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn > > vLvp4* > > > zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mM > J > > XCoBHnW > > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1 > > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f > > zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO- > 2 > > |a}K?r > > zFo(mo@$6w!RCO;!k{m2{z- > _`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C > > _9 > > > ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u > > G8 > > > z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o| > > p > > > z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK > > pU > > zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G > > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`- > GBdrly&WQ1*?kDL@ > > pG<V! > > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3- > JyC<keh(WCoDi(@n0xqm`@&*0R>; > > SVa > > zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?- > i$S > > ) > > z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj > > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#- > 5>lJ2jXZ|?d~C= > > n*V > > > zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR > > 6na4 > > zw- > T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L > > i > > zajQH#9E- > re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L > > 675^ > > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T- > 5)vkqIFntDZMA1VMOHjx#|# > > gp > > z<=jzFhYH`U9&O8-fDan`- > Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ > > s9 > > z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+ > > B< > > zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(- > AS > > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W- > JCA@y|<k2?s=otq > > kXs > > zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf% > > 6 > > ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg > > V> > > z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}- > > > zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP > > e+{ > > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b- > LbUdRv*H4Cj>iO=b6AU_W > > kt_g > > zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><} > > &(L > > ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~ > > > zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCA > I > > uWDE > > > z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy > > WSRlcK > > zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL > > =h8r > > > z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L > > M^W > > z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7? > > _YY > > zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf( > > > zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W > > u$Jn > > > zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j > > Uyi# > > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1- > 7wk8y&7D+XUbG > > qc > > > zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{ > > B? > > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR- > `ynB}GDY7)z8WdiaOz1? > > $ > > > z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2 > > w_fKH^bO > > > zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C> > > r > > > z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Y > b > > }g > > zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi > > zXl`9?- > $MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29 > > @(BH > > zQPs%IT;9S({?mP*=Qnc|D5J- > |w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf= > > c > > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4- > F^%90(P&<beWqvDXsg0?i > > WV^Yr > > zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz > > m*iO > > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv- > 0T#hDV!d > > ^^pp > > > zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{ > > zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I; > > > zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu > > G > > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da- > R)wUYvP#%R8D{%W4M3=p@E&YpC5Y > > <^3Ym > > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%- > wXl_NyC`0qB > > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr- > wIc*7P > > U)!KE > > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek- > a?2dg6PVM6GVX~3`oj > > %%M; > > > z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je > > zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i > > z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`> > > g > > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T- > 2DeQ#fI > > 0ra > > zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90% > > U2ISK > > z7k~rD4m&7xFAX&{$U- > )37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA > > m&$g3 > > > z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n > > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;- > d#*zW#Tye9hV)P&G*REZ2he+xK461i > > S > > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+- > @izT8*fdO5W<a > > <>h= > > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O- > U`a;Yy~M(7 > > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0- > *)&Q!XszxM?Zk > > c > > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>- > Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s > > > z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB > > ^ > > z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y > > mQ9 > > z7-54~(UFH?f- > J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V > > zmVbN(^|1#(h+-lD+oK- > PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W > > b > > zObewKL- > P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E > > ~AL > > zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ > > mE} > > > zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS > > Ar > > > zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{ > > eM#TotF > > zf2^1WUw|=jGZ{M_KC6YOEM6I@- > R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ> > > -!8~ > > zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G > > w > > > z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ > > vh0 > > z2yd+qIez;p={X=o?0- > ^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F > > 9F > > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi- > 7AsygbO%g|<oo| > > F > > > zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7 > > mcGpsI > > > zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z > > eLf}n > > z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_ > > V58p > > > z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE; > > _G > > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?- > MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC > > uL| > > > zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y > > 7 > > z*L9AUT{ijtMS0dcKOCKHpr- > +xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR > > p+ > > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi- > eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS > > Q!<O& > > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r- > sKrwU > > sCLRyE > > > z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1 > > shL > > zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U > > e@ > > zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r > > > za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp` > > zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4 > > +q > > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D- > B$kndG=Y6ir}mBr@$2Y+D1hg2` > > HSFo?UV4 > > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs- > U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73 > > t+H6 > > z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W > > 0@Pm_Y > > zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j) > > zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK > > zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3 > > z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P > > z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH > > z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t > > $g7Mc > > > z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw > > g4XT > > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2- > &x>7Mi3KPo##3Vi5A!D > > ~zVd > > > zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ > > )g}U > > zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo > > aKg > > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y- > AD^;!g > > x| > > z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3 > > R > > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V- > O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v > > OZ > > > z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz- > > DH > > z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52 > > m? > > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET- > fIoOZ<f~u > > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol- > KEmeMx`wo+msu_i=!gCUc5 > > aAFo > > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o- > UlMiBIpwFoxSL(w@3J7A9556*;P>na > > q(Up` > > z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7 > > zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr > > > zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5 > > k7 > > > zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i > > ?0^U > > zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C > > zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq > > $ > > > zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm` > > `jz` > > > zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr > > T%2I > > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69- > HYb > > > z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9 > > > zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh* > > !tsx > > zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C > > > z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD > > & > > zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X > > @*1fT > > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr- > G6WS1r9|13yh@ > > Y{v > > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6- > {$zk^x|sZJl > > O+j > > zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x > > LE}S > > zE- > yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9` > > UBK8 > > zQ#_- > WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s > > HLzP7 > > > zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om* > > TH > > zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&= > > w*FLg > > zsI<EKP=R6SqF- > IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D > > k*l > > z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt > > gvZ`h > > zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW? > > MMr > > zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j% > > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u- > _fVYHP%QJS6G+)Vr9%12 > > >J > > z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw > > Mk8(V > > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)- > ?sMK$L?>Ng)`3v > > `R > > > z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl > > NJlM > > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi- > f1#Bw(VP<qeg{%cT1IJ97@nLSx > > z_X- > ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4 > > 5 > > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4- > kyiVyjuy47$ > > @| > > z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk > > q6<X@ > > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu- > b=1;<A1a(HF7 > > `i > > z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y- > < > > @ > > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb- > %NnQFS!>!e+)H<J7 > > % > > > z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq > > )L > > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh- > @%MC4@d > > 0h&s<FN > > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V- > _M01I| > > m8wTMI > > > zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld > > (#T` > > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK- > OFjWJG?jVvSoZ_a6 > > jbw > > zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa > > qQ > > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX- > B8hJF!+PDU)2Ng~^@q8b > > e+U > > zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk > > > zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo > > > zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L > > cp > > zKSVWp#RY$Lhkns{H6- > Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x > > d} > > > zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f > > zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*- > i8 > > r$$4 > > zZOqr7#;sW- > rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_; > > 4Fzt > > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob- > K5PWDTzJUeq*If}X<4`_2c(`X*0 > > z6;L!+h$=hX6x?t- > Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY > > <t#vw; > > > z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG > > zsy > > z&r3>eq@*BKMfN&W*>mt#- > zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d > > 4t+{ > > > zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf > > is > > > ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U; > > ?2 > > > zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv > > *TAdi > > zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS > > zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I > > > zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l > > hv > > > z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK > > z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K > > B(|Tz > > z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+ > > XbfG > > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^- > ;pwarlq8+@E8O5*D1MF > > F1&w > > zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud > > > zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA > > ^H > > > z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv > > jX2 > > RBat2OV|2<CTVmi8`9DHIo&o>> > > > > literal 0 > > HcmV?d00001 > > > > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py > > b/BaseTools/Source/Python/FMMT/PI/Common.py > > new file mode 100644 > > index 000000000000..efab874ee08b > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py > > @@ -0,0 +1,81 @@ > > +## @file > > +# This file is used to define the common C struct and functions. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from ctypes import * > > +import uuid > > + > > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}') > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = > > uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}') > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = > > uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}') > > +# EFI_FFS_VOLUME_TOP_FILE_GUID = > > uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}') > > + > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID = > > uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > > EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID = > > uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > > b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a' > > +EFI_SYSTEM_NVDATA_FV_GUID = > > uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50") > > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE = > > b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP" > > +EFI_FFS_VOLUME_TOP_FILE_GUID = > > uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09") > > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = > > b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t' > > +ZEROVECTOR_BYTE = > > b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff") > > +FVH_SIGNATURE = b'_FVH' > > + > > +class GUID(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Guid1', c_uint32), > > + ('Guid2', c_uint16), > > + ('Guid3', c_uint16), > > + ('Guid4', ARRAY(c_uint8, 8)), > > + ] > > + > > + def from_list(self, listformat: list) -> None: > > + self.Guid1 = listformat[0] > > + self.Guid2 = listformat[1] > > + self.Guid3 = listformat[2] > > + for i in range(8): > > + self.Guid4[i] = listformat[i+3] > > + > > + def __cmp__(self, otherguid) -> bool: > > + if not isinstance(otherguid, GUID): > > + return 'Input is not the GUID instance!' > > + rt = False > > + if self.Guid1 == otherguid.Guid1 and self.Guid2 == > otherguid.Guid2 > > and self.Guid3 == otherguid.Guid3: > > + rt = True > > + for i in range(8): > > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i]) > > + return rt > > + > > +def ModifyGuidFormat(target_guid: str) -> GUID: > > + target_guid = target_guid.replace('-', '') > > + target_list = [] > > + start = [0,8,12,16,18,20,22,24,26,28,30] > > + end = [8,12,16,18,20,22,24,26,28,30,32] > > + num = len(start) > > + for pos in range(num): > > + new_value = int(target_guid[start[pos]:end[pos]], 16) > > + target_list.append(new_value) > > + new_format = GUID() > > + new_format.from_list(target_list) > > + return new_format > > + > > + > > +# Get data from ctypes to bytes. > > +def struct2stream(s) -> bytes: > > + length = sizeof(s) > > + p = cast(pointer(s), POINTER(c_char * length)) > > + return p.contents.raw > > + > > + > > + > > +def GetPadSize(Size: int, alignment: int) -> int: > > + if Size % alignment == 0: > > + return 0 > > + Pad_Size = alignment - Size % alignment > > + return Pad_Size > > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > new file mode 100644 > > index 000000000000..33c49ffb50bc > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > @@ -0,0 +1,66 @@ > > +## @file > > +# This file is used to define the Ffs Header C Struct. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from struct import * > > +from ctypes import * > > +from PI.Common import * > > + > > +EFI_FFS_FILE_HEADER_LEN = 24 > > +EFI_FFS_FILE_HEADER2_LEN = 32 > > + > > +class CHECK_SUM(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Header', c_uint8), > > + ('File', c_uint8), > > + ] > > + > > +class EFI_FFS_INTEGRITY_CHECK(Union): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Checksum', CHECK_SUM), > > + ('Checksum16', c_uint16), > > + ] > > + > > + > > +class EFI_FFS_FILE_HEADER(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Name', GUID), > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > > + ('Type', c_uint8), > > + ('Attributes', c_uint8), > > + ('Size', ARRAY(c_uint8, 3)), > > + ('State', c_uint8), > > + ] > > + > > + @property > > + def FFS_FILE_SIZE(self) -> int: > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > > + > > + @property > > + def HeaderLength(self) -> int: > > + return 24 > > + > > +class EFI_FFS_FILE_HEADER2(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Name', GUID), > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > > + ('Type', c_uint8), > > + ('Attributes', c_uint8), > > + ('Size', ARRAY(c_uint8, 3)), > > + ('State', c_uint8), > > + ('ExtendedSize', c_uint64), > > + ] > > + > > + @property > > + def FFS_FILE_SIZE(self) -> int: > > + return self.ExtendedSize > > + > > + @property > > + def HeaderLength(self) -> int: > > + return 32 > > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > new file mode 100644 > > index 000000000000..aae2feae844a > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > @@ -0,0 +1,112 @@ > > +## @file > > +# This file is used to define the FV Header C Struct. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from ast import Str > > +from struct import * > > +from ctypes import * > > +from PI.Common import * > > + > > +class EFI_FV_BLOCK_MAP_ENTRY(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('NumBlocks', c_uint32), > > + ('Length', c_uint32), > > + ] > > + > > + > > +class EFI_FIRMWARE_VOLUME_HEADER(Structure): > > + _fields_ = [ > > + ('ZeroVector', ARRAY(c_uint8, 16)), > > + ('FileSystemGuid', GUID), > > + ('FvLength', c_uint64), > > + ('Signature', c_uint32), > > + ('Attributes', c_uint32), > > + ('HeaderLength', c_uint16), > > + ('Checksum', c_uint16), > > + ('ExtHeaderOffset', c_uint16), > > + ('Reserved', c_uint8), > > + ('Revision', c_uint8), > > + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, > > 1)), > > + ] > > + > > +def Refine_FV_Header(nums): > > + class EFI_FIRMWARE_VOLUME_HEADER(Structure): > > + _fields_ = [ > > + ('ZeroVector', ARRAY(c_uint8, 16)), > > + ('FileSystemGuid', GUID), > > + ('FvLength', c_uint64), > > + ('Signature', c_uint32), > > + ('Attributes', c_uint32), > > + ('HeaderLength', c_uint16), > > + ('Checksum', c_uint16), > > + ('ExtHeaderOffset', c_uint16), > > + ('Reserved', c_uint8), > > + ('Revision', c_uint8), > > + ('BlockMap', > > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)), > > + ] > > + return EFI_FIRMWARE_VOLUME_HEADER > > + > > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): > > + _fields_ = [ > > + ('FvName', GUID), > > + ('ExtHeaderSize', c_uint32) > > + ] > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure): > > + _fields_ = [ > > + ('ExtEntrySize', c_uint16), > > + ('ExtEntryType', c_uint16) > > + ] > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('TypeMask', c_uint32) > > + ] > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('TypeMask', c_uint32), > > + ('Types', ARRAY(GUID, 1)) > > + ] > > + > > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE: > > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('TypeMask', c_uint32), > > + ('Types', ARRAY(GUID, nums)) > > + ] > > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure) > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('FormatType', GUID) > > + ] > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('FormatType', GUID), > > + ('Data', ARRAY(c_uint8, 1)) > > + ] > > + > > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE: > > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('FormatType', GUID), > > + ('Data', ARRAY(c_uint8, nums)) > > + ] > > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure) > > + > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure): > > + _fields_ = [ > > + ('Hdr', > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > + ('UsedSize', c_uint32) > > + ] > > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > new file mode 100644 > > index 000000000000..c2cc8e0172fb > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > @@ -0,0 +1,110 @@ > > +## @file > > +# This file is used to define the Section Header C Struct. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from struct import * > > +from ctypes import * > > +from PI.Common import * > > + > > +EFI_COMMON_SECTION_HEADER_LEN = 4 > > +EFI_COMMON_SECTION_HEADER2_LEN = 8 > > + > > +class EFI_COMMON_SECTION_HEADER(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Size', ARRAY(c_uint8, 3)), > > + ('Type', c_uint8), > > + ] > > + > > + @property > > + def SECTION_SIZE(self) -> int: > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > > + > > + def Common_Header_Size(self) -> int: > > + return 4 > > + > > +class EFI_COMMON_SECTION_HEADER2(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('Size', ARRAY(c_uint8, 3)), > > + ('Type', c_uint8), > > + ('ExtendedSize', c_uint32), > > + ] > > + > > + @property > > + def SECTION_SIZE(self) -> int: > > + return self.ExtendedSize > > + > > + def Common_Header_Size(self) -> int: > > + return 8 > > + > > +class EFI_COMPRESSION_SECTION(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('UncompressedLength', c_uint32), > > + ('CompressionType', c_uint8), > > + ] > > + > > + def ExtHeaderSize(self) -> int: > > + return 5 > > + > > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('SubTypeGuid', GUID), > > + ] > > + > > + def ExtHeaderSize(self) -> int: > > + return 16 > > + > > +class EFI_GUID_DEFINED_SECTION(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('SectionDefinitionGuid', GUID), > > + ('DataOffset', c_uint16), > > + ('Attributes', c_uint16), > > + ] > > + > > + def ExtHeaderSize(self) -> int: > > + return 20 > > + > > +def Get_USER_INTERFACE_Header(nums: int): > > + class EFI_SECTION_USER_INTERFACE(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('FileNameString', ARRAY(c_uint16, nums)), > > + ] > > + > > + def ExtHeaderSize(self) -> int: > > + return 2 * nums > > + > > + def GetUiString(self) -> str: > > + UiString = '' > > + for i in range(nums): > > + if self.FileNameString[i]: > > + UiString += chr(self.FileNameString[i]) > > + return UiString > > + > > + return EFI_SECTION_USER_INTERFACE > > + > > +def Get_VERSION_Header(nums: int): > > + class EFI_SECTION_VERSION(Structure): > > + _pack_ = 1 > > + _fields_ = [ > > + ('BuildNumber', c_uint16), > > + ('VersionString', ARRAY(c_uint16, nums)), > > + ] > > + > > + def ExtHeaderSize(self) -> int: > > + return 2 * (nums+1) > > + > > + def GetVersionString(self) -> str: > > + VersionString = '' > > + for i in range(nums): > > + if self.VersionString[i]: > > + VersionString += chr(self.VersionString[i]) > > + return VersionString > > + > > + return EFI_SECTION_VERSION > > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py > > b/BaseTools/Source/Python/FMMT/PI/__init__.py > > new file mode 100644 > > index 000000000000..4e8296fad1ba > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py > > @@ -0,0 +1,6 @@ > > +## @file > > +# This file is used to define the FMMT dependent external tool > management > > class. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/README.md > > b/BaseTools/Source/Python/FMMT/README.md > > new file mode 100644 > > index 000000000000..e14dfa34ea66 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/README.md > > @@ -0,0 +1,180 @@ > > +# FMMT > > +## Overview > > +This FMMT tool is the python implementation of the edk2 FMMT tool > which > > locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt. > > +This implementation has the same usage as the edk2 FMMT, but it's more > > readable and relaiable. > > + > > +# FMMT User Guide > > + > > +#### Last updated October 13, 2021 > > + > > +Important Changes and Updates: > > + > > +- Oct 13, 2021 Initial Draft of FMMT Python Tool > > + > > +#### Note: > > + > > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is > > much easier to maintain and extend other functions. > > + > > + > > + > > +# 1. Introduction > > + > > +## 1.1 Overview > > + > > +The Firmware Device is a persistent physical repository that contains > > firmware code and/or data. The firmware code and/or data stored in > > Firmware Volumes. Detail layout of Firmware Volumes is described in > ?Figure > > 1. The Firmware Volume Format?. > > + > > +![](Img/FirmwareVolumeFormat.png) > > + > > +<center>Figure 1. The Firmware Volume Format</center> > > + > > +In firmware development, binary file has its firmware layout following > the > > Platform-Initialization Specification. Thus, operation on FV file / FFS > file > > (Firmware File) is an efficient and convenient way for firmware function > > testing and developing. FMMT Python tool is used for firmware files > > operation. > > + > > +## 1.2 Tool Capabilities > > + > > +The FMMT tool is capable of: > > + > > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware > > Files) > > + > > +- Add a new FFS into a FV file (both included in a FD file or not) > > + > > +- Replace an FFS in a FV file with a new FFS file > > + > > +- Delete an FFS in a FV file (both included in a FD file or not) > > + > > +- Extract the FFS from a FV file (both includ-v < Inputfile > < > Outputfile >ed > > in a FD file or not) > > + > > +## 1.3 References > > + > > +| Document | > > +| ------------------------------------------------ | > > +| UEFI Platform Initialization (PI) Specification | > > + > > + > > + > > +# 2. FMMT Python Tool Usage > > + > > +## 2.1 Required Files > > + > > +### 2.1.1 Independent use > > + > > +When independent use the FMMT Python Tool, the following files and > > settings are required: > > + > > +- GuidTool executable files used for Decompress/Compress Firmware data. > > + > > +- Environment variables path with GuidTool path setting. > > + > > +### 2.1.2 Use with Build System > > + > > +When use the FMMT Python Tool with Build System: > > + > > +- If only use Edk2 based GuidTool, do not need other preparation. > > + > > +- If use other customized GuidTool, need prepare the config file with > GuidTool > > info. The syntax for GuidTool definition shown as follow: > > + > > + ***ToolsGuid ShortName Command*** > > + > > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI > > BrotliCompress*** > > + > > +## 2.2 Syntax > > + > > +### 2.2.1 Syntax for Parse file > > + > > +***-v < Inputfile > < Outputfile > -l < LogFileType >*** > > + > > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* > is > > optional, if inputs, the *Inputfile* will be encapsulated into > *Outputfile* > > following the parsed firmware layout. *"-l LogFileType"* is optional, it > decides > > the format of log file which saves Binary layout. Currently supports: > json, txt. > > More formats will be added in the future. > > + > > +### 2.2.2 Syntax for Add a new FFS > > + > > +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < > > Outputfile >*** > > + > > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* > > (Name or Guid) is the TargetFv which *NewFfsFile* will be added into. > > + > > +### 2.2.3 Syntax for Delete an FFS > > + > > +***-d < Inputfile > < TargetFfsName > < Outputfile > < > > TargetFvName/TargetFvGuid >*** > > + > > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs > > which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is > the > > parent of TargetFfs*.* > > + > > +### 2.2.4 Syntax for Replace an FFS > > + > > +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < > > TargetFvName/TargetFvGuid >*** > > + > > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the > TargetFfs > > which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is > > the parent of TargetFfs*.* > > + > > +### 2.2.5 Syntax for Extract an FFS > > + > > +***-e < Inputfile > < TargetFfsName > < Outputfile >*** > > + > > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the > TargetFfs > > which will be extracted. > > + > > + > > + > > +# 3. FMMT Python Tool Design > > + > > +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each > > Node have its Data field, which saves the > > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the > > parse/add/delete/replace/extract operations are based on the NodeTree > > (adjusting the layout and data). > > + > > +## 3.1 NodeTree > > + > > +A whole NodeTree saves all the Firmware info. > > + > > +- Parent & Child relationship figured out the Firmware layout. > > + > > +- Each Node have several fields. ?Data? field saves an FirmwareClass > > instance which contains all the data info of the info. > > + > > +### 3.1.1 NodeTree Format > > + > > +The NodeTree will be created with parse function. When parse a file, a > Root > > Node will be initialized firstly. The Data split and Tree construction > process is > > described with an FD file shown as ?Figure 2. The NodeTree format?: > > + > > +- A Root Node is initialized. > > + > > +- Use the ?FV Signature? as FV key to split Whole FD > > Data. ?FV0?, ?FV1?, ?FV2?? Node created. > > + > > +- After FV level Node created, use the ?Ffs Data Size? as FFS key to > split each > > FV Data. ?Ffs0?...Node created. > > + > > +- After FFS level Node created, use the ?Section Data Size? as Section > key to > > split each Ffs Data. ?Section0?...Node created. > > + > > +- If some of Section includes other Sections, continue use the ?Section > Data > > Size? as Section key to split each Section Data. > > + > > +- After all Node created, the whole NodeTree saves all the info. (Can be > used > > in other functions or print the whole firmware layout into log file) > > + > > +![](Img/NodeTreeFormat.png) > > + > > +<center>Figure 2. The NodeTree format</center> > > + > > +### 3.1.2 Node Factory and Product > > + > > +As 3.1.1, Each Node is created by data split and recognition. To extend > the > > NodeTree usage, Factory pattern is used in Node created process. > > + > > +Each Node have its Factory to create Product and use Product ParserData > > function to deal with the data. > > + > > +## 3.2 GuidTool > > + > > +There are two ways to set the GuidTool. One from Config file, another > from > > environment variables. > > + > > +Current GuidTool first check if has Config file. > > + > > +- If have, load the config GuidTool Information. > > + > > +- Else get from environment variables. > > + > > +### 3.2.1 Get from Config file > > + > > +- Config file should in same folder with FMMT.py or the path in > environment > > variables. > > + > > +- Content should follow the format: > > + > > + ***ToolsGuid ShortName Command*** > > + > > +### 3.2.2 Get from Environment Variables > > + > > +- The GuidTool Command used must be set in environment variables. > > + > > +### 3.2.3 Edk2 Based GuidTool > > + > > +| ***Guid*** | ***ShortName*** > > | ***Command*** | > > +| ------------------------------------------ | --------------- | > --------------------- | > > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | > > ***TianoCompress*** | > > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | > > ***LzmaCompress*** | > > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | > > ***GenCrc32*** | > > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | > > ***LzmaF86Compress*** | > > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | > > ***BrotliCompress*** | > > diff --git a/BaseTools/Source/Python/FMMT/__init__.py > > b/BaseTools/Source/Python/FMMT/__init__.py > > new file mode 100644 > > index 000000000000..e69de29bb2d1 > > diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > new file mode 100644 > > index 000000000000..33ffe73cab27 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > @@ -0,0 +1,371 @@ > > +## @file > > +# This file is used to implement of the various bianry parser. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from re import T > > +import copy > > +import os > > +from PI.Common import * > > +from core.BiosTreeNode import * > > +from core.BiosTree import * > > +from core.GuidTools import * > > + > > +ROOT_TREE = 'ROOT' > > +ROOT_FV_TREE = 'ROOT_FV_TREE' > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > > + > > +FV_TREE = 'FV' > > +DATA_FV_TREE = 'DATA_FV' > > +FFS_TREE = 'FFS' > > +FFS_PAD = 'FFS_PAD' > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > > +SECTION_TREE = 'SECTION' > > +SEC_FV_TREE = 'SEC_FV_IMAGE' > > +BINARY_DATA = 'BINARY' > > +Fv_count = 0 > > + > > +## Abstract factory > > +class BinaryFactory(): > > + type:list = [] > > + > > + def Create_Product(): > > + pass > > + > > +class BinaryProduct(): > > + ## Use GuidTool to decompress data. > > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes: > > + ParPath = > > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. > ") > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > > + guidtool = > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > > + DecompressedData = guidtool.unpack(Section_Data) > > + return DecompressedData > > + > > + def ParserData(): > > + pass > > + > > +class SectionFactory(BinaryFactory): > > + type = [SECTION_TREE] > > + > > + def Create_Product(): > > + return SectionProduct() > > + > > +class FfsFactory(BinaryFactory): > > + type = [ROOT_SECTION_TREE, FFS_TREE] > > + > > + def Create_Product(): > > + return FfsProduct() > > + > > +class FvFactory(BinaryFactory): > > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE] > > + > > + def Create_Product(): > > + return FvProduct() > > + > > +class FdFactory(BinaryFactory): > > + type = [ROOT_FV_TREE, ROOT_TREE] > > + > > + def Create_Product(): > > + return FdProduct() > > + > > +class SectionProduct(BinaryProduct): > > + ## Decompress the compressed section. > > + def ParserData(self, Section_Tree, whole_Data: bytes, > > Rel_Whole_Offset: int=0) -> None: > > + if Section_Tree.Data.Type == 0x01: > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > + self.ParserFfs(Section_Tree, b'') > > + # Guided Define Section > > + elif Section_Tree.Data.Type == 0x02: > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > + DeCompressGuidTool = > > Section_Tree.Data.ExtHeader.SectionDefinitionGuid > > + Section_Tree.Data.Data = > > self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data) > > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) + > > Section_Tree.Data.HeaderLength > > + self.ParserFfs(Section_Tree, b'') > > + elif Section_Tree.Data.Type == 0x03: > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > + self.ParserFfs(Section_Tree, b'') > > + # SEC_FV Section > > + elif Section_Tree.Data.Type == 0x17: > > + global Fv_count > > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data) > > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count)) > > + Sec_Fv_Tree.type = SEC_FV_TREE > > + Sec_Fv_Tree.Data = Sec_Fv_Info > > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset > > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + > > Sec_Fv_Tree.Data.Header.HeaderLength > > + Sec_Fv_Tree.Data.Data = > > Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:] > > + Section_Tree.insertChild(Sec_Fv_Tree) > > + Fv_count += 1 > > + > > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > int=0) -> None: > > + Rel_Offset = 0 > > + Section_Offset = 0 > > + # Get the Data from parent tree, if do not have the tree then get > it > > from the whole_data. > > + if ParTree.Data != None: > > + Data_Size = len(ParTree.Data.Data) > > + Section_Offset = ParTree.Data.DOffset > > + Whole_Data = ParTree.Data.Data > > + else: > > + Data_Size = len(Whole_Data) > > + # Parser all the data to collect all the Section recorded in its > Parent > > Section. > > + while Rel_Offset < Data_Size: > > + # Create a SectionNode and set it as the SectionTree's Data > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > > + Section_Tree = BIOSTREE(Section_Info.Name) > > + Section_Tree.type = SECTION_TREE > > + Section_Info.Data = > > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > > Rel_Offset+Section_Info.Size] > > + Section_Info.DOffset = Section_Offset + > > Section_Info.HeaderLength + Rel_Whole_Offset > > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset > > + Section_Info.ROffset = Rel_Offset > > + if Section_Info.Header.Type == 0: > > + break > > + # The final Section in parent Section does not need to add > > padding, else must be 4-bytes align with parent Section start offset > > + Pad_Size = 0 > > + if > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != > Data_Size): > > + Pad_Size = GetPadSize(Section_Info.Size, 4) > > + Section_Info.PadData = Pad_Size * b'\x00' > > + if Section_Info.Header.Type == 0x02: > > + Section_Info.DOffset = Section_Offset + > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > > + Section_Info.Data = > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > > Rel_Offset+Section_Info.Size] > > + if Section_Info.Header.Type == 0x14: > > + ParTree.Data.Version = > > Section_Info.ExtHeader.GetVersionString() > > + if Section_Info.Header.Type == 0x15: > > + ParTree.Data.UiName = > > Section_Info.ExtHeader.GetUiString() > > + Section_Offset += Section_Info.Size + Pad_Size > > + Rel_Offset += Section_Info.Size + Pad_Size > > + Section_Tree.Data = Section_Info > > + ParTree.insertChild(Section_Tree) > > + > > +class FfsProduct(BinaryProduct): > > + # ParserFFs / GetSection > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > int=0) -> None: > > + Rel_Offset = 0 > > + Section_Offset = 0 > > + # Get the Data from parent tree, if do not have the tree then get > it > > from the whole_data. > > + if ParTree.Data != None: > > + Data_Size = len(ParTree.Data.Data) > > + Section_Offset = ParTree.Data.DOffset > > + Whole_Data = ParTree.Data.Data > > + else: > > + Data_Size = len(Whole_Data) > > + # Parser all the data to collect all the Section recorded in Ffs. > > + while Rel_Offset < Data_Size: > > + # Create a SectionNode and set it as the SectionTree's Data > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > > + Section_Tree = BIOSTREE(Section_Info.Name) > > + Section_Tree.type = SECTION_TREE > > + Section_Info.Data = > > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > > Rel_Offset+Section_Info.Size] > > + Section_Info.DOffset = Section_Offset + > > Section_Info.HeaderLength + Rel_Whole_Offset > > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset > > + Section_Info.ROffset = Rel_Offset > > + if Section_Info.Header.Type == 0: > > + break > > + # The final Section in Ffs does not need to add padding, else > > must be 4-bytes align with Ffs start offset > > + Pad_Size = 0 > > + if > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != > Data_Size): > > + Pad_Size = GetPadSize(Section_Info.Size, 4) > > + Section_Info.PadData = Pad_Size * b'\x00' > > + if Section_Info.Header.Type == 0x02: > > + Section_Info.DOffset = Section_Offset + > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > > + Section_Info.Data = > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > > Rel_Offset+Section_Info.Size] > > + # If Section is Version or UI type, it saves the version and > UI > > info of its parent Ffs. > > + if Section_Info.Header.Type == 0x14: > > + ParTree.Data.Version = > > Section_Info.ExtHeader.GetVersionString() > > + if Section_Info.Header.Type == 0x15: > > + ParTree.Data.UiName = > > Section_Info.ExtHeader.GetUiString() > > + Section_Offset += Section_Info.Size + Pad_Size > > + Rel_Offset += Section_Info.Size + Pad_Size > > + Section_Tree.Data = Section_Info > > + ParTree.insertChild(Section_Tree) > > + > > +class FvProduct(BinaryProduct): > > + ## ParserFv / GetFfs > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > int=0) -> None: > > + Ffs_Offset = 0 > > + Rel_Offset = 0 > > + # Get the Data from parent tree, if do not have the tree then get > it > > from the whole_data. > > + if ParTree.Data != None: > > + Data_Size = len(ParTree.Data.Data) > > + Ffs_Offset = ParTree.Data.DOffset > > + Whole_Data = ParTree.Data.Data > > + else: > > + Data_Size = len(Whole_Data) > > + # Parser all the data to collect all the Ffs recorded in Fv. > > + while Rel_Offset < Data_Size: > > + # Create a FfsNode and set it as the FFsTree's Data > > + if Data_Size - Rel_Offset < 24: > > + Ffs_Tree = BIOSTREE('Free_Space') > > + Ffs_Tree.type = FFS_FREE_SPACE > > + Ffs_Tree.Data = > > FreeSpaceNode(Whole_Data[Rel_Offset:]) > > + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset > > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset > > + ParTree.Data.Free_Space = Data_Size - Rel_Offset > > + ParTree.insertChild(Ffs_Tree) > > + Rel_Offset = Data_Size > > + else: > > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:]) > > + Ffs_Tree = BIOSTREE(Ffs_Info.Name) > > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset > > + Ffs_Info.DOffset = Ffs_Offset + > > Ffs_Info.Header.HeaderLength + Rel_Whole_Offset > > + Ffs_Info.ROffset = Rel_Offset > > + if Ffs_Info.Name == PADVECTOR: > > + Ffs_Tree.type = FFS_PAD > > + Ffs_Info.Data = > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > > Rel_Offset+Ffs_Info.Size] > > + Ffs_Info.Size = len(Ffs_Info.Data) + > > Ffs_Info.Header.HeaderLength > > + # if current Ffs is the final ffs of Fv and full of > b'\xff', > > define it with Free_Space > > + if struct2stream(Ffs_Info.Header).replace(b'\xff', > b'') > > == b'': > > + Ffs_Tree.type = FFS_FREE_SPACE > > + Ffs_Info.Data = Whole_Data[Rel_Offset:] > > + Ffs_Info.Size = len(Ffs_Info.Data) > > + ParTree.Data.Free_Space = Ffs_Info.Size > > + else: > > + Ffs_Tree.type = FFS_TREE > > + Ffs_Info.Data = > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > > Rel_Offset+Ffs_Info.Size] > > + # The final Ffs in Fv does not need to add padding, else > > must be 8-bytes align with Fv start offset > > + Pad_Size = 0 > > + if Ffs_Tree.type != FFS_FREE_SPACE and > > (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != > Data_Size): > > + Pad_Size = GetPadSize(Ffs_Info.Size, 8) > > + Ffs_Info.PadData = Pad_Size * b'\xff' > > + Ffs_Offset += Ffs_Info.Size + Pad_Size > > + Rel_Offset += Ffs_Info.Size + Pad_Size > > + Ffs_Tree.Data = Ffs_Info > > + ParTree.insertChild(Ffs_Tree) > > + > > +class FdProduct(BinaryProduct): > > + type = [ROOT_FV_TREE, ROOT_TREE] > > + > > + ## Create DataTree with first level /fv Info, then parser each Fv. > > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: > int=0) -> > > None: > > + # Get all Fv image in Fd with offset and length > > + Fd_Struct = self.GetFvFromFd(whole_data) > > + data_size = len(whole_data) > > + Binary_count = 0 > > + global Fv_count > > + # If the first Fv image is the Binary Fv, add it into the tree. > > + if Fd_Struct[0][1] != 0: > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > > + Binary_node.type = BINARY_DATA > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]] > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > + Binary_node.Data.HOffset = 0 + offset > > + WholeFvTree.insertChild(Binary_node) > > + Binary_count += 1 > > + # Add the first collected Fv image into the tree. > > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count)) > > + Cur_node.type = Fd_Struct[0][0] > > + Cur_node.Data = FvNode(Fv_count, > > whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]]) > > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset > > + Cur_node.Data.DOffset = > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > > + Cur_node.Data.Data = > > > whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct > > [0][1]+Cur_node.Data.Size] > > + WholeFvTree.insertChild(Cur_node) > > + Fv_count += 1 > > + Fv_num = len(Fd_Struct) > > + # Add all the collected Fv image and the Binary Fv image between > > them into the tree. > > + for i in range(Fv_num-1): > > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]: > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > > + Binary_node.type = BINARY_DATA > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > + Binary_node.Data.Data = > > whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]] > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > + Binary_node.Data.HOffset = > > Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset > > + WholeFvTree.insertChild(Binary_node) > > + Binary_count += 1 > > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count)) > > + Cur_node.type = Fd_Struct[i+1][0] > > + Cur_node.Data = FvNode(Fv_count, > > whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]]) > > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset > > + Cur_node.Data.DOffset = > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > > + Cur_node.Data.Data = > > > whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru > > ct[i+1][1]+Cur_node.Data.Size] > > + WholeFvTree.insertChild(Cur_node) > > + Fv_count += 1 > > + # If the final Fv image is the Binary Fv, add it into the tree > > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size: > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > > + Binary_node.type = BINARY_DATA > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > + Binary_node.Data.Data = > > whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:] > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > + Binary_node.Data.HOffset = > > Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset > > + WholeFvTree.insertChild(Binary_node) > > + Binary_count += 1 > > + > > + ## Get the first level Fv from Fd file. > > + def GetFvFromFd(self, whole_data: bytes=b'') -> list: > > + Fd_Struct = [] > > + data_size = len(whole_data) > > + cur_index = 0 > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV > > image offset and length. > > + while cur_index < data_size: > > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in > > whole_data[cur_index:]: > > + target_index = > > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) > + > > cur_index > > + if whole_data[target_index+24:target_index+28] == > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > ZEROVECTOR_BYTE: > > + Fd_Struct.append([FV_TREE, target_index - 16, > > unpack("Q", whole_data[target_index+16:target_index+24])]) > > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > > + else: > > + cur_index = target_index + 16 > > + else: > > + cur_index = data_size > > + cur_index = 0 > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV > > image offset and length. > > + while cur_index < data_size: > > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in > > whole_data[cur_index:]: > > + target_index = > > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) > + > > cur_index > > + if whole_data[target_index+24:target_index+28] == > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > ZEROVECTOR_BYTE: > > + Fd_Struct.append([FV_TREE, target_index - 16, > > unpack("Q", whole_data[target_index+16:target_index+24])]) > > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > > + else: > > + cur_index = target_index + 16 > > + else: > > + cur_index = data_size > > + cur_index = 0 > > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image > > offset and length. > > + while cur_index < data_size: > > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in > > whole_data[cur_index:]: > > + target_index = > > whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + > > cur_index > > + if whole_data[target_index+24:target_index+28] == > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > ZEROVECTOR_BYTE: > > + Fd_Struct.append([DATA_FV_TREE, target_index - > > 16, unpack("Q", whole_data[target_index+16:target_index+24])]) > > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0] > > + else: > > + cur_index = target_index + 16 > > + else: > > + cur_index = data_size > > + # Sort all the collect Fv image with offset. > > + Fd_Struct.sort(key=lambda x:x[1]) > > + tmp_struct = copy.deepcopy(Fd_Struct) > > + tmp_index = 0 > > + Fv_num = len(Fd_Struct) > > + # Remove the Fv image included in another Fv image. > > + for i in range(1,Fv_num): > > + if tmp_struct[i][1]+tmp_struct[i][2][0] < > > tmp_struct[i-1][1]+tmp_struct[i-1][2][0]: > > + Fd_Struct.remove(Fd_Struct[i-tmp_index]) > > + tmp_index += 1 > > + return Fd_Struct > > + > > +class ParserEntry(): > > + FactoryTable:dict = { > > + SECTION_TREE: SectionFactory, > > + ROOT_SECTION_TREE: FfsFactory, > > + FFS_TREE: FfsFactory, > > + ROOT_FFS_TREE: FvFactory, > > + FV_TREE: FvFactory, > > + SEC_FV_TREE: FvFactory, > > + ROOT_FV_TREE: FdFactory, > > + ROOT_TREE: FdFactory, > > + } > > + > > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory: > > + if Tree_type in self.FactoryTable: > > + return self.FactoryTable[Tree_type] > > + > > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: > > bytes, Offset: int) -> None: > > + New_Product = TargetFactory.Create_Product() > > + New_Product.ParserData(Tree, Data, Offset) > > + > > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None: > > + TargetFactory = self.GetTargetFactory(Tree.type) > > + if TargetFactory: > > + self.Generate_Product(TargetFactory, Tree, Data, Offset) > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py > > b/BaseTools/Source/Python/FMMT/core/BiosTree.py > > new file mode 100644 > > index 000000000000..0b6252ecc1bb > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py > > @@ -0,0 +1,198 @@ > > +## @file > > +# This file is used to define the Bios layout tree structure and related > > operations. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +import collections > > +from PI.Common import * > > + > > +ROOT_TREE = 'ROOT' > > +ROOT_FV_TREE = 'ROOT_FV_TREE' > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > > + > > +FV_TREE = 'FV' > > +DATA_FV_TREE = 'DATA_FV' > > +FFS_TREE = 'FFS' > > +FFS_PAD = 'FFS_PAD' > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > > +SECTION_TREE = 'SECTION' > > +SEC_FV_TREE = 'SEC_FV_IMAGE' > > +BINARY_DATA = 'BINARY' > > + > > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, > > ROOT_SECTION_TREE] > > +FvType = [FV_TREE, SEC_FV_TREE] > > +FfsType = FFS_TREE > > +SecType = SECTION_TREE > > + > > +class BIOSTREE: > > + def __init__(self, NodeName: str) -> None: > > + self.key = NodeName > > + self.type = None > > + self.Data = None > > + self.Child = [] > > + self.Findlist = [] > > + self.Parent = None > > + self.NextRel = None > > + self.LastRel = None > > + > > + def HasChild(self) -> bool: > > + if self.Child == []: > > + return False > > + else: > > + return True > > + > > + def isFinalChild(self) -> bool: > > + ParTree = self.Parent > > + if ParTree: > > + if ParTree.Child[-1] == self: > > + return True > > + return False > > + > > + # FvTree.insertChild() > > + def insertChild(self, newNode, pos: int=None) -> None: > > + if len(self.Child) == 0: > > + self.Child.append(newNode) > > + else: > > + if not pos: > > + LastTree = self.Child[-1] > > + self.Child.append(newNode) > > + LastTree.NextRel = newNode > > + newNode.LastRel = LastTree > > + else: > > + newNode.NextRel = self.Child[pos-1].NextRel > > + newNode.LastRel = self.Child[pos].LastRel > > + self.Child[pos-1].NextRel = newNode > > + self.Child[pos].LastRel = newNode > > + self.Child.insert(pos, newNode) > > + newNode.Parent = self > > + > > + # lastNode.insertRel(newNode) > > + def insertRel(self, newNode) -> None: > > + if self.Parent: > > + parentTree = self.Parent > > + new_index = parentTree.Child.index(self) + 1 > > + parentTree.Child.insert(new_index, newNode) > > + self.NextRel = newNode > > + newNode.LastRel = self > > + > > + def deleteNode(self, deletekey: str) -> None: > > + FindStatus, DeleteTree = self.FindNode(deletekey) > > + if FindStatus: > > + parentTree = DeleteTree.Parent > > + lastTree = DeleteTree.LastRel > > + nextTree = DeleteTree.NextRel > > + if parentTree: > > + index = parentTree.Child.index(DeleteTree) > > + del parentTree.Child[index] > > + if lastTree and nextTree: > > + lastTree.NextRel = nextTree > > + nextTree.LastRel = lastTree > > + elif lastTree: > > + lastTree.NextRel = None > > + elif nextTree: > > + nextTree.LastRel = None > > + return DeleteTree > > + else: > > + print('Could not find the target tree') > > + return None > > + > > + def FindNode(self, key: str, Findlist: list) -> None: > > + if self.key == key or (self.Data and self.Data.Name == key) or > > (self.type == FFS_TREE and self.Data.UiName == key): > > + Findlist.append(self) > > + else: > > + for item in self.Child: > > + item.FindNode(key, Findlist) > > + > > + def GetTreePath(self): > > + BiosTreePath = [self] > > + while self.Parent: > > + BiosTreePath.insert(0, self.Parent) > > + self = self.Parent > > + return BiosTreePath > > + > > + def parserTree(self, TargetDict: dict=None, Info: list=None, space: > int=0, > > ParFvId="") -> None: > > + Key = list(TargetDict.keys())[0] > > + if TargetDict[Key]["Type"] in RootType: > > + Info.append("Image File: {}".format(Key)) > > + Info.append("FilesNum: > > {}".format(TargetDict.get(Key).get('FilesNum'))) > > + Info.append("\n") > > + elif TargetDict[Key]["Type"] in FvType: > > + space += 2 > > + if TargetDict[Key]["Type"] == SEC_FV_TREE: > > + Info.append("{}Child FV named {} of {}".format(space*" ", > > Key, ParFvId)) > > + space += 2 > > + else: > > + Info.append("FvId: {}".format(Key)) > > + ParFvId = Key > > + Info.append("{}FvNameGuid: {}".format(space*" ", > > TargetDict.get(Key).get('FvNameGuid'))) > > + Info.append("{}Attributes: {}".format(space*" ", > > TargetDict.get(Key).get('Attributes'))) > > + Info.append("{}Total Volume Size: {}".format(space*" ", > > TargetDict.get(Key).get('Size'))) > > + Info.append("{}Free Volume Size: {}".format(space*" ", > > TargetDict.get(Key).get('FreeSize'))) > > + Info.append("{}Volume Offset: {}".format(space*" ", > > TargetDict.get(Key).get('Offset'))) > > + Info.append("{}FilesNum: {}".format(space*" ", > > TargetDict.get(Key).get('FilesNum'))) > > + elif TargetDict[Key]["Type"] in FfsType: > > + space += 2 > > + if TargetDict.get(Key).get('UiName') != "b''": > > + Info.append("{}File: {} / {}".format(space*" ", Key, > > TargetDict.get(Key).get('UiName'))) > > + else: > > + Info.append("{}File: {}".format(space*" ", Key)) > > + if "Files" in list(TargetDict[Key].keys()): > > + for item in TargetDict[Key]["Files"]: > > + self.parserTree(item, Info, space, ParFvId) > > + > > + def ExportTree(self,TreeInfo: dict=None) -> dict: > > + if TreeInfo is None: > > + TreeInfo =collections.OrderedDict() > > + > > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or > > self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE: > > + key = str(self.key) > > + TreeInfo[self.key] = collections.OrderedDict() > > + TreeInfo[self.key]["Name"] = key > > + TreeInfo[self.key]["Type"] = self.type > > + TreeInfo[self.key]["FilesNum"] = len(self.Child) > > + elif self.type == FV_TREE or self.type == SEC_FV_TREE: > > + key = str(self.Data.FvId) > > + TreeInfo[key] = collections.OrderedDict() > > + TreeInfo[key]["Name"] = key > > + if self.Data.FvId != self.Data.Name: > > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name) > > + TreeInfo[key]["Type"] = self.type > > + TreeInfo[key]["Attributes"] = > hex(self.Data.Header.Attributes) > > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength) > > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space) > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > + elif self.type == FFS_TREE: > > + key = str(self.Data.Name) > > + TreeInfo[key] = collections.OrderedDict() > > + TreeInfo[key]["Name"] = key > > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName) > > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version) > > + TreeInfo[key]["Type"] = self.type > > + TreeInfo[key]["Size"] = hex(self.Data.Size) > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > + elif self.type == SECTION_TREE and self.Data.Type == 0x02: > > + key = str(self.Data.Name) > > + TreeInfo[key] = collections.OrderedDict() > > + TreeInfo[key]["Name"] = key > > + TreeInfo[key]["Type"] = self.type > > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + > > self.Data.HeaderLength) > > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size) > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > + elif self is not None: > > + key = str(self.Data.Name) > > + TreeInfo[key] = collections.OrderedDict() > > + TreeInfo[key]["Name"] = key > > + TreeInfo[key]["Type"] = self.type > > + TreeInfo[key]["Size"] = hex(self.Data.Size) > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > + > > + for item in self.Child: > > + TreeInfo[key].setdefault('Files',[]).append( > item.ExportTree()) > > + > > + return TreeInfo > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > new file mode 100644 > > index 000000000000..cfb711eea5a2 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > @@ -0,0 +1,191 @@ > > +## @file > > +# This file is used to define the BIOS Tree Node. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from PI.FvHeader import * > > +from PI.FfsFileHeader import * > > +from PI.SectionHeader import * > > +from PI.Common import * > > +import uuid > > + > > +SectionHeaderType = { > > + 0x01:'EFI_COMPRESSION_SECTION', > > + 0x02:'EFI_GUID_DEFINED_SECTION', > > + 0x03:'EFI_SECTION_DISPOSABLE', > > + 0x10:'EFI_SECTION_PE32', > > + 0x11:'EFI_SECTION_PIC', > > + 0x12:'EFI_SECTION_TE', > > + 0x13:'EFI_SECTION_DXE_DEPEX', > > + 0x14:'EFI_SECTION_VERSION', > > + 0x15:'EFI_SECTION_USER_INTERFACE', > > + 0x16:'EFI_SECTION_COMPATIBILITY16', > > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', > > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION', > > + 0x19:'EFI_SECTION_RAW', > > + 0x1B:'EFI_SECTION_PEI_DEPEX', > > + 0x1C:'EFI_SECTION_MM_DEPEX' > > +} > > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18] > > + > > +class BinaryNode: > > + def __init__(self, name: str) -> None: > > + self.Size = 0 > > + self.Name = "BINARY" + str(name) > > + self.HOffset = 0 > > + self.Data = b'' > > + > > +class FvNode: > > + def __init__(self, name, buffer: bytes) -> None: > > + self.Header = > > EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer) > > + Map_num = (self.Header.HeaderLength - 56)//8 > > + self.Header = > > Refine_FV_Header(Map_num).from_buffer_copy(buffer) > > + self.FvId = "FV" + str(name) > > + self.Name = "FV" + str(name) > > + if self.Header.ExtHeaderOffset: > > + self.ExtHeader = > > > EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Heade > r > > .ExtHeaderOffset:]) > > + self.Name = > > uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName)) > > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20 > > + if self.ExtHeader.ExtHeaderSize != 20: > > + self.ExtEntryExist = 1 > > + self.ExtEntry = > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry > > Offset:]) > > + self.ExtTypeExist = 1 > > + if self.ExtEntry.ExtEntryType == 0x01: > > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16 > > + self.ExtEntry = > > > Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[ > s > > elf.ExtEntryOffset:]) > > + elif self.ExtEntry.ExtEntryType == 0x02: > > + nums = self.ExtEntry.ExtEntrySize - 20 > > + self.ExtEntry = > > > Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer > [ > > self.ExtEntryOffset:]) > > + elif self.ExtEntry.ExtEntryType == 0x03: > > + self.ExtEntry = > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b > > uffer[self.ExtEntryOffset:]) > > + else: > > + self.ExtTypeExist = 0 > > + else: > > + self.ExtEntryExist = 0 > > + self.Size = self.Header.FvLength > > + self.HeaderLength = self.Header.HeaderLength > > + self.HOffset = 0 > > + self.DOffset = 0 > > + self.ROffset = 0 > > + self.Data = b'' > > + if self.Header.Signature != 1213613663: > > + print('Invalid! Fv Header Signature {} is not > > "_FVH".'.format(self.Header.Signature)) > > + with open(str(self.Name)+'.fd', "wb") as f: > > + f.write(struct2stream(self.Header)) > > + assert False > > + self.PadData = b'' > > + self.Free_Space = 0 > > + self.ModCheckSum() > > + > > + def ModCheckSum(self) -> None: > > + # Fv Header Sums to 0. > > + Header = struct2stream(self.Header)[::-1] > > + Size = self.HeaderLength // 2 > > + Sum = 0 > > + for i in range(Size): > > + Sum += int(Header[i*2: i*2 + 2].hex(), 16) > > + if Sum & 0xffff: > > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - > > self.Header.Checksum)[-4:], 16)), 16) > > + > > + def ModFvExt(self) -> None: > > + # If used space changes and self.ExtEntry.UsedSize exists, > > self.ExtEntry.UsedSize need to be changed. > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and > > self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03: > > + self.ExtEntry.UsedSize = self.Header.FvLength - > > self.Free_Space > > + > > + def ModFvSize(self) -> None: > > + # If Fv Size changed, self.Header.FvLength and > > self.Header.BlockMap[i].NumBlocks need to be changed. > > + BlockMapNum = len(self.Header.BlockMap) > > + for i in range(BlockMapNum): > > + if self.Header.BlockMap[i].Length: > > + self.Header.BlockMap[i].NumBlocks = > > self.Header.FvLength // self.Header.BlockMap[i].Length > > + > > + def ModExtHeaderData(self) -> None: > > + if self.Header.ExtHeaderOffset: > > + ExtHeaderData = struct2stream(self.ExtHeader) > > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset - > > self.HeaderLength > > + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData > > + self.Data[ExtHeaderDataOffset+20:] > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist: > > + ExtHeaderEntryData = struct2stream(self.ExtEntry) > > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + > > 20 - self.HeaderLength > > + self.Data = self.Data[:ExtHeaderEntryDataOffset] + > > ExtHeaderEntryData + > > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):] > > + > > +class FfsNode: > > + def __init__(self, buffer: bytes) -> None: > > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer) > > + # self.Attributes = unpack("<B", buffer[21:22])[0] > > + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes != > 0xff > > and self.Header.Attributes & 0x01 == 1: > > + print('Error Ffs Header! Ffs Header Size and Attributes is > not > > matched!') > > + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes & > > 0x01 == 1: > > + self.Header = > > EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer) > > + self.Name = > > uuid.UUID(bytes_le=struct2stream(self.Header.Name)) > > + self.UiName = b'' > > + self.Version = b'' > > + self.Size = self.Header.FFS_FILE_SIZE > > + self.HeaderLength = self.Header.HeaderLength > > + self.HOffset = 0 > > + self.DOffset = 0 > > + self.ROffset = 0 > > + self.Data = b'' > > + self.PadData = b'' > > + > > + def ModCheckSum(self) -> None: > > + HeaderData = struct2stream(self.Header) > > + HeaderSum = 0 > > + for item in HeaderData: > > + HeaderSum += item > > + HeaderSum -= self.Header.State > > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File > > + if HeaderSum & 0xff: > > + Header = self.Header.IntegrityCheck.Checksum.Header + > > 0x100 - int(hex(HeaderSum)[-2:], 16) > > + self.Header.IntegrityCheck.Checksum.Header = > > int(hex(Header)[-2:], 16) > > + > > +class SectionNode: > > + def __init__(self, buffer: bytes) -> None: > > + if buffer[0:3] != b'\xff\xff\xff': > > + self.Header = > > EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer) > > + else: > > + self.Header = > > EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer) > > + if self.Header.Type in SectionHeaderType: > > + self.Name = SectionHeaderType[self.Header.Type] > > + elif self.Header.Type == 0: > > + self.Name = "EFI_SECTION_RAW" > > + else: > > + self.Name = "SECTION" > > + if self.Header.Type in HeaderType: > > + self.ExtHeader = self.GetExtHeader(self.Header.Type, > > buffer[self.Header.Common_Header_Size():], > > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size())) > > + self.HeaderLength = self.Header.Common_Header_Size() + > > self.ExtHeader.ExtHeaderSize() > > + else: > > + self.ExtHeader = None > > + self.HeaderLength = self.Header.Common_Header_Size() > > + self.Size = self.Header.SECTION_SIZE > > + self.Type = self.Header.Type > > + self.HOffset = 0 > > + self.DOffset = 0 > > + self.ROffset = 0 > > + self.Data = b'' > > + self.OriData = b'' > > + self.OriHeader = b'' > > + self.PadData = b'' > > + > > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> > None: > > + if Type == 0x01: > > + return > > EFI_COMPRESSION_SECTION.from_buffer_copy(buffer) > > + elif Type == 0x02: > > + return > > EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer) > > + elif Type == 0x14: > > + return Get_VERSION_Header((nums - > > 2)//2).from_buffer_copy(buffer) > > + elif Type == 0x15: > > + return > > Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer) > > + elif Type == 0x18: > > + return > > EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer) > > + > > +class FreeSpaceNode: > > + def __init__(self, buffer: bytes) -> None: > > + self.Name = 'Free_Space' > > + self.Data = buffer > > + self.Size = len(buffer) > > + self.HOffset = 0 > > + self.DOffset = 0 > > + self.ROffset = 0 > > + self.PadData = b'' > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > new file mode 100644 > > index 000000000000..a0432c4093cf > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > @@ -0,0 +1,140 @@ > > +## @file > > +# This file is used to define the functions to operate bios binary file. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from core.FMMTParser import * > > +from core.FvHandler import * > > +from utils.FvLayoutPrint import * > > + > > +global Fv_count > > +Fv_count = 0 > > + > > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', > 'ROOT_FFS_TREE', > > 'ROOT_SECTION_TREE' > > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, > outputfile: > > str=None) -> None: > > + # 1. Data Prepare > > + with open(inputfile, "rb") as f: > > + whole_data = f.read() > > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE) > > + # 2. DataTree Create > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > > + # 3. Log Output > > + InfoDict = FmmtParser.WholeFvTree.ExportTree() > > + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo) > > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo) > > + if logfile: > > + GetFormatter(logfile.lower()).dump(InfoDict, > > > FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile > ), > > ".{}".format(logfile.lower()))) > > + # 4. Data Encapsultion > > + if outputfile: > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > + with open(outputfile, "wb") as f: > > + f.write(FmmtParser.FinalData) > > + > > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, > Fv_name: > > str=None) -> None: > > + # 1. Data Prepare > > + with open(inputfile, "rb") as f: > > + whole_data = f.read() > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > + # 2. DataTree Create > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > > + # 3. Data Modify > > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, > > FmmtParser.WholeFvTree.Findlist) > > + # Choose the Specfic DeleteFfs with Fv info > > + if Fv_name: > > + for item in FmmtParser.WholeFvTree.Findlist: > > + if item.Parent.key != Fv_name and > > item.Parent.Data.Name != Fv_name: > > + FmmtParser.WholeFvTree.Findlist.remove(item) > > + if FmmtParser.WholeFvTree.Findlist != []: > > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: > > + FfsMod = FvHandler(None, Delete_Ffs) > > + Status = FfsMod.DeleteFfs() > > + else: > > + print('Target Ffs not found!!!') > > + # 4. Data Encapsultion > > + if Status: > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > + with open(outputfile, "wb") as f: > > + f.write(FmmtParser.FinalData) > > + > > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: > str) -> > > None: > > + # 1. Data Prepare > > + with open(inputfile, "rb") as f: > > + whole_data = f.read() > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > + # 2. DataTree Create > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > > + # Get Target Fv and Target Ffs_Pad > > + FmmtParser.WholeFvTree.FindNode(Fv_name, > > FmmtParser.WholeFvTree.Findlist) > > + # Create new ffs Tree > > + with open(newffsfile, "rb") as f: > > + new_ffs_data = f.read() > > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE) > > + Status = False > > + # 3. Data Modify > > + if FmmtParser.WholeFvTree.Findlist: > > + for TargetFv in FmmtParser.WholeFvTree.Findlist: > > + TargetFfsPad = TargetFv.Child[-1] > > + if TargetFfsPad.type == FFS_FREE_SPACE: > > + > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > > new_ffs_data, TargetFfsPad.Data.HOffset) > > + else: > > + > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > > new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size) > > + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], > > TargetFfsPad) > > + Status = FfsMod.AddFfs() > > + else: > > + print('Target Fv not found!!!') > > + # 4. Data Encapsultion > > + if Status: > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > + with open(outputfile, "wb") as f: > > + f.write(FmmtParser.FinalData) > > + > > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, > outputfile: str, > > Fv_name: str=None) -> None: > > + # 1. Data Prepare > > + with open(inputfile, "rb") as f: > > + whole_data = f.read() > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > + # 2. DataTree Create > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > > + with open(newffsfile, "rb") as f: > > + new_ffs_data = f.read() > > + newFmmtParser = FMMTParser(newffsfile, FV_TREE) > > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, > > new_ffs_data) > > + Status = False > > + # 3. Data Modify > > + new_ffs = newFmmtParser.WholeFvTree.Child[0] > > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff' > > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > > FmmtParser.WholeFvTree.Findlist) > > + if Fv_name: > > + for item in FmmtParser.WholeFvTree.Findlist: > > + if item.Parent.key != Fv_name and > > item.Parent.Data.Name != Fv_name: > > + FmmtParser.WholeFvTree.Findlist.remove(item) > > + if FmmtParser.WholeFvTree.Findlist != []: > > + for TargetFfs in FmmtParser.WholeFvTree.Findlist: > > + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], > > TargetFfs) > > + Status = FfsMod.ReplaceFfs() > > + else: > > + print('Target Ffs not found!!!') > > + # 4. Data Encapsultion > > + if Status: > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > + with open(outputfile, "wb") as f: > > + f.write(FmmtParser.FinalData) > > + > > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None: > > + with open(inputfile, "rb") as f: > > + whole_data = f.read() > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) > > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > > FmmtParser.WholeFvTree.Findlist) > > + if FmmtParser.WholeFvTree.Findlist != []: > > + TargetNode = FmmtParser.WholeFvTree.Findlist[0] > > + TargetFv = TargetNode.Parent > > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: > > + TargetNode.Data.Header.State = c_uint8( > > + ~TargetNode.Data.Header.State) > > + FinalData = struct2stream(TargetNode.Data.Header) + > > TargetNode.Data.Data > > + with open(outputfile, "wb") as f: > > + f.write(FinalData) > > + else: > > + print('Target Ffs not found!!!') > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > new file mode 100644 > > index 000000000000..6e54b860a9c9 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > @@ -0,0 +1,86 @@ > > +## @file > > +# This file is used to define the interface of Bios Parser. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +from PI.Common import * > > +from core.BinaryFactoryProduct import ParserEntry > > +from core.BiosTreeNode import * > > +from core.BiosTree import * > > +from core.GuidTools import * > > + > > +class FMMTParser: > > + def __init__(self, name: str, TYPE: str) -> None: > > + self.WholeFvTree = BIOSTREE(name) > > + self.WholeFvTree.type = TYPE > > + self.FinalData = b'' > > + self.BinaryInfo = [] > > + > > + ## Parser the nodes in WholeTree. > > + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', > > Reloffset: int=0) -> None: > > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == > > ROOT_FV_TREE: > > + ParserEntry().DataParser(self.WholeFvTree, whole_data, > > Reloffset) > > + else: > > + ParserEntry().DataParser(WholeFvTree, whole_data, > > Reloffset) > > + for Child in WholeFvTree.Child: > > + self.ParserFromRoot(Child, "") > > + > > + ## Encapuslation all the data in tree into self.FinalData > > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None: > > + # If current node is Root node, skip it. > > + if rootTree.type == ROOT_TREE or rootTree.type == > > ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == > > ROOT_SECTION_TREE: > > + print('Start at Root !') > > + # If current node do not have Header, just add Data. > > + elif rootTree.type == BINARY_DATA or rootTree.type == > > FFS_FREE_SPACE: > > + self.FinalData += rootTree.Data.Data > > + rootTree.Child = [] > > + # If current node do not have Child and ExtHeader, just add its > > Header and Data. > > + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD: > > + self.FinalData += struct2stream(rootTree.Data.Header) + > > rootTree.Data.Data + rootTree.Data.PadData > > + if rootTree.isFinalChild(): > > + ParTree = rootTree.Parent > > + if ParTree.type != 'ROOT': > > + self.FinalData += ParTree.Data.PadData > > + rootTree.Child = [] > > + # If current node is not Section node and may have Child and > > ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data. > > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or > > rootTree.type == SEC_FV_TREE: > > + if rootTree.HasChild(): > > + self.FinalData += struct2stream(rootTree.Data.Header) > > + else: > > + self.FinalData += struct2stream(rootTree.Data.Header) + > > rootTree.Data.Data + rootTree.Data.PadData > > + if rootTree.isFinalChild(): > > + ParTree = rootTree.Parent > > + if ParTree.type != 'ROOT': > > + self.FinalData += ParTree.Data.PadData > > + # If current node is Section, need to consider its ExtHeader, > Child > > and Compressed Status. > > + elif rootTree.type == SECTION_TREE: > > + # Not compressed section > > + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != > > b'' and CompressStatus): > > + if rootTree.HasChild(): > > + if rootTree.Data.ExtHeader: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) + > > struct2stream(rootTree.Data.ExtHeader) > > + else: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) > > + else: > > + Data = rootTree.Data.Data > > + if rootTree.Data.ExtHeader: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) + > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > > + else: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > > + if rootTree.isFinalChild(): > > + ParTree = rootTree.Parent > > + self.FinalData += ParTree.Data.PadData > > + # If compressed section > > + else: > > + Data = rootTree.Data.OriData > > + rootTree.Child = [] > > + if rootTree.Data.ExtHeader: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) + > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > > + else: > > + self.FinalData += > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > > + if rootTree.isFinalChild(): > > + ParTree = rootTree.Parent > > + self.FinalData += ParTree.Data.PadData > > + for Child in rootTree.Child: > > + self.Encapsulation(Child, CompressStatus) > > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py > > b/BaseTools/Source/Python/FMMT/core/FvHandler.py > > new file mode 100644 > > index 000000000000..f73f1fd65c07 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py > > @@ -0,0 +1,521 @@ > > +## @file > > +# This file is used to the implementation of Bios layout handler. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +import os > > +from core.BiosTree import * > > +from core.GuidTools import GUIDTools > > +from core.BiosTreeNode import * > > +from PI.Common import * > > + > > +EFI_FVB2_ERASE_POLARITY = 0x00000800 > > + > > +def ChangeSize(TargetTree, size_delta: int=0) -> None: > > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or > > type(TargetTree.Data.Header) == > type(EFI_COMMON_SECTION_HEADER2()): > > + TargetTree.Data.Size -= size_delta > > + TargetTree.Data.Header.ExtendedSize -= size_delta > > + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData: > > + OriSize = TargetTree.Data.Header.SECTION_SIZE > > + OriSize -= size_delta > > + TargetTree.Data.Header.Size[0] = OriSize % (16**2) > > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2) > > + TargetTree.Data.Header.Size[2] = OriSize // (16**4) > > + else: > > + TargetTree.Data.Size -= size_delta > > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2) > > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) > > //(16**2) > > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4) > > + > > +def ModifyFfsType(TargetFfs) -> None: > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and > > TargetFfs.Data.Size > 0xFFFFFF: > > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8 > > + New_Header = EFI_FFS_FILE_HEADER2() > > + New_Header.Name = TargetFfs.Data.Header.Name > > + New_Header.IntegrityCheck = > > TargetFfs.Data.Header.IntegrityCheck > > + New_Header.Type = TargetFfs.Data.Header.Type > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > > + New_Header.Size = 0 > > + New_Header.State = TargetFfs.Data.Header.State > > + New_Header.ExtendedSize = ExtendSize > > + TargetFfs.Data.Header = New_Header > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > > + TargetFfs.Data.HeaderLength = > > TargetFfs.Data.Header.HeaderLength > > + TargetFfs.Data.ModCheckSum() > > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and > > TargetFfs.Data.Size <= 0xFFFFFF: > > + New_Header = EFI_FFS_FILE_HEADER() > > + New_Header.Name = TargetFfs.Data.Header.Name > > + New_Header.IntegrityCheck = > > TargetFfs.Data.Header.IntegrityCheck > > + New_Header.Type = TargetFfs.Data.Header.Type > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > > + New_Header.Size = TargetFfs.Data.HeaderLength + > > TargetFfs.Data.Size > > + New_Header.State = TargetFfs.Data.Header.State > > + TargetFfs.Data.Header = New_Header > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > > + TargetFfs.Data.HeaderLength = > > TargetFfs.Data.Header.HeaderLength > > + TargetFfs.Data.ModCheckSum() > > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == > > EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE: > > + NeedChange = True > > + for item in TargetFfs.Parent.Child: > > + if type(item.Data.Header) == > > type(EFI_FFS_FILE_HEADER2()): > > + NeedChange = False > > + if NeedChange: > > + TargetFfs.Parent.Data.Header.FileSystemGuid = > > ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > > + > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()): > > + TarParent = TargetFfs.Parent > > + while TarParent: > > + if TarParent.type == FV_TREE and > > struct2stream(TarParent.Data.Header.FileSystemGuid) == > > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE: > > + TarParent.Data.Header.FileSystemGuid = > > ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > > + TarParent = TarParent.Parent > > + > > +class FvHandler: > > + def __init__(self, NewFfs, TargetFfs) -> None: > > + self.NewFfs = NewFfs > > + self.TargetFfs = TargetFfs > > + self.Status = False > > + self.Remain_New_Free_Space = 0 > > + > > + ## Use for Compress the Section Data > > + def CompressData(self, TargetTree) -> None: > > + TreePath = TargetTree.GetTreePath() > > + pos = len(TreePath) > > + self.Status = True > > + while pos: > > + if self.Status: > > + if TreePath[pos-1].type == SECTION_TREE and > > TreePath[pos-1].Data.Type == 0x02: > > + self.CompressSectionData(TreePath[pos-1], None, > > TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid) > > + else: > > + if pos == len(TreePath): > > + self.CompressSectionData(TreePath[pos-1], > > pos) > > + else: > > + self.CompressSectionData(TreePath[pos-1], > > None) > > + pos -= 1 > > + > > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> > > None: > > + NewData = b'' > > + temp_save_child = TargetTree.Child > > + if TargetTree.Data: > > + for item in temp_save_child: > > + if item.type == SECTION_TREE and not > > item.Data.OriData and item.Data.ExtHeader: > > + NewData += struct2stream(item.Data.Header) + > > struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData > > + elif item.type == SECTION_TREE and item.Data.OriData > > and not item.Data.ExtHeader: > > + NewData += struct2stream(item.Data.Header) + > > item.Data.OriData + item.Data.PadData > > + elif item.type == SECTION_TREE and item.Data.OriData > > and item.Data.ExtHeader: > > + NewData += struct2stream(item.Data.Header) + > > struct2stream(item.Data.ExtHeader) + item.Data.OriData + > > item.Data.PadData > > + elif item.type == FFS_FREE_SPACE: > > + NewData += item.Data.Data + item.Data.PadData > > + else: > > + NewData += struct2stream(item.Data.Header) + > > item.Data.Data + item.Data.PadData > > + if TargetTree.type == FFS_TREE: > > + New_Pad_Size = GetPadSize(len(NewData), 8) > > + Size_delta = len(NewData) - len(TargetTree.Data.Data) > > + ChangeSize(TargetTree, -Size_delta) > > + Delta_Pad_Size = len(TargetTree.Data.PadData) - > > New_Pad_Size > > + self.Remain_New_Free_Space += Delta_Pad_Size > > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size > > + TargetTree.Data.ModCheckSum() > > + elif TargetTree.type == FV_TREE or TargetTree.type == > > SEC_FV_TREE and not pos: > > + if self.Remain_New_Free_Space: > > + if TargetTree.Data.Free_Space: > > + TargetTree.Data.Free_Space += > > self.Remain_New_Free_Space > > + NewData += self.Remain_New_Free_Space * > > b'\xff' > > + TargetTree.Child[-1].Data.Data += > > self.Remain_New_Free_Space * b'\xff' > > + else: > > + TargetTree.Data.Data += > > self.Remain_New_Free_Space * b'\xff' > > + New_Free_Space = BIOSTREE('FREE_SPACE') > > + New_Free_Space.type = FFS_FREE_SPACE > > + New_Free_Space.Data = > > FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space) > > + TargetTree.insertChild(New_Free_Space) > > + self.Remain_New_Free_Space = 0 > > + if TargetTree.type == SEC_FV_TREE: > > + Size_delta = len(NewData) + > > self.Remain_New_Free_Space - len(TargetTree.Data.Data) > > + TargetTree.Data.Header.FvLength += Size_delta > > + TargetTree.Data.ModFvExt() > > + TargetTree.Data.ModFvSize() > > + TargetTree.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetTree) > > + TargetTree.Data.ModCheckSum() > > + elif TargetTree.type == SECTION_TREE and > > TargetTree.Data.Type != 0x02: > > + New_Pad_Size = GetPadSize(len(NewData), 4) > > + Size_delta = len(NewData) - len(TargetTree.Data.Data) > > + ChangeSize(TargetTree, -Size_delta) > > + if TargetTree.NextRel: > > + Delta_Pad_Size = len(TargetTree.Data.PadData) - > > New_Pad_Size > > + self.Remain_New_Free_Space += Delta_Pad_Size > > + TargetTree.Data.PadData = b'\x00' * > > New_Pad_Size > > + TargetTree.Data.Data = NewData > > + if GuidTool: > > + ParPath = > > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. > ") > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > > + guidtool = > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > > + CompressedData = guidtool.pack(TargetTree.Data.Data) > > + if len(CompressedData) < len(TargetTree.Data.OriData): > > + New_Pad_Size = GetPadSize(len(CompressedData), 4) > > + Size_delta = len(CompressedData) - > > len(TargetTree.Data.OriData) > > + ChangeSize(TargetTree, -Size_delta) > > + if TargetTree.NextRel: > > + TargetTree.Data.PadData = b'\x00' * > > New_Pad_Size > > + self.Remain_New_Free_Space = > > len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - > > len(CompressedData) - New_Pad_Size > > + else: > > + TargetTree.Data.PadData = b'' > > + self.Remain_New_Free_Space = > > len(TargetTree.Data.OriData) - len(CompressedData) > > + TargetTree.Data.OriData = CompressedData > > + elif len(CompressedData) == len(TargetTree.Data.OriData): > > + TargetTree.Data.OriData = CompressedData > > + elif len(CompressedData) > len(TargetTree.Data.OriData): > > + New_Pad_Size = GetPadSize(CompressedData, 4) > > + self.Remain_New_Free_Space = len(CompressedData) + > > New_Pad_Size - len(TargetTree.Data.OriData) - > len(TargetTree.Data.PadData) > > + Size_delta = len(TargetTree.Data.OriData) - > > len(CompressedData) > > + ChangeSize(TargetTree, -Size_delta) > > + if TargetTree.NextRel: > > + TargetTree.Data.PadData = b'\x00' * > > New_Pad_Size > > + TargetTree.Data.OriData = CompressedData > > + self.ModifyTest(TargetTree, > > self.Remain_New_Free_Space) > > + self.Status = False > > + > > + def ModifyFvExtData(self, TreeNode) -> None: > > + FvExtData = b'' > > + if TreeNode.Data.Header.ExtHeaderOffset: > > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader) > > + FvExtData += FvExtHeader > > + if TreeNode.Data.Header.ExtHeaderOffset and > > TreeNode.Data.ExtEntryExist: > > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry) > > + FvExtData += FvExtEntry > > + if FvExtData: > > + InfoNode = TreeNode.Child[0] > > + InfoNode.Data.Data = FvExtData + > > InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:] > > + InfoNode.Data.ModCheckSum() > > + > > + def ModifyTest(self, ParTree, Needed_Space: int) -> None: > > + if Needed_Space > 0: > > + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE: > > + ParTree.Data.Data = b'' > > + Needed_Space = Needed_Space - > > ParTree.Data.Free_Space > > + if Needed_Space < 0: > > + ParTree.Child[-1].Data.Data = b'\xff' * > > (-Needed_Space) > > + ParTree.Data.Free_Space = (-Needed_Space) > > + self.Status = True > > + else: > > + if ParTree.type == FV_TREE: > > + self.Status = False > > + else: > > + BlockSize = > > ParTree.Data.Header.BlockMap[0].Length > > + New_Add_Len = BlockSize - > > Needed_Space%BlockSize > > + if New_Add_Len % BlockSize: > > + ParTree.Child[-1].Data.Data = b'\xff' * > > New_Add_Len > > + ParTree.Data.Free_Space = > > New_Add_Len > > + Needed_Space += New_Add_Len > > + else: > > + ParTree.Child.remove(ParTree.Child[-1]) > > + ParTree.Data.Free_Space = 0 > > + ParTree.Data.Size += Needed_Space > > + ParTree.Data.Header.Fvlength = > > ParTree.Data.Size > > + for item in ParTree.Child: > > + if item.type == FFS_FREE_SPACE: > > + ParTree.Data.Data += item.Data.Data + > > item.Data.PadData > > + else: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > + ParTree.Data.ModFvExt() > > + ParTree.Data.ModFvSize() > > + ParTree.Data.ModExtHeaderData() > > + self.ModifyFvExtData(ParTree) > > + ParTree.Data.ModCheckSum() > > + elif ParTree.type == FFS_TREE: > > + ParTree.Data.Data = b'' > > + for item in ParTree.Child: > > + if item.Data.OriData: > > + if item.Data.ExtHeader: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > > item.Data.OriData + item.Data.PadData > > + else: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData > > + else: > > + if item.Data.ExtHeader: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > > item.Data.Data + item.Data.PadData > > + else: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > + ChangeSize(ParTree, -Needed_Space) > > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8) > > + Delta_Pad_Size = New_Pad_Size - > > len(ParTree.Data.PadData) > > + Needed_Space += Delta_Pad_Size > > + ParTree.Data.PadData = b'\xff' * > > GetPadSize(ParTree.Data.Size, 8) > > + ParTree.Data.ModCheckSum() > > + elif ParTree.type == SECTION_TREE: > > + OriData = ParTree.Data.Data > > + ParTree.Data.Data = b'' > > + for item in ParTree.Child: > > + if item.type == SECTION_TREE and > > item.Data.ExtHeader and item.Data.Type != 0x02: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > > item.Data.Data + item.Data.PadData > > + elif item.type == SECTION_TREE and > > item.Data.ExtHeader and item.Data.Type == 0x02: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + > > item.Data.OriData + item.Data.PadData > > + else: > > + ParTree.Data.Data += > > struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData > > + if ParTree.Data.Type == 0x02: > > + ParTree.Data.Size += Needed_Space > > + ParPath = > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))) > > + ToolPath = os.path.join(os.path.dirname(ParPath), > > r'FMMTConfig.ini') > > + guidtool = > > > GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Se > c > > tionDefinitionGuid)) > > + CompressedData = > > guidtool.pack(ParTree.Data.Data) > > + Needed_Space = len(CompressedData) - > > len(ParTree.Data.OriData) > > + ParTree.Data.OriData = CompressedData > > + New_Size = ParTree.Data.HeaderLength + > > len(CompressedData) > > + ParTree.Data.Header.Size[0] = New_Size % (16**2) > > + ParTree.Data.Header.Size[1] = New_Size % (16**4) > > //(16**2) > > + ParTree.Data.Header.Size[2] = New_Size // (16**4) > > + if ParTree.NextRel: > > + New_Pad_Size = GetPadSize(New_Size, 4) > > + Delta_Pad_Size = New_Pad_Size - > > len(ParTree.Data.PadData) > > + ParTree.Data.PadData = b'\x00' * > > New_Pad_Size > > + Needed_Space += Delta_Pad_Size > > + else: > > + ParTree.Data.PadData = b'' > > + elif Needed_Space: > > + ChangeSize(ParTree, -Needed_Space) > > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4) > > + Delta_Pad_Size = New_Pad_Size - > > len(ParTree.Data.PadData) > > + Needed_Space += Delta_Pad_Size > > + ParTree.Data.PadData = b'\x00' * New_Pad_Size > > + NewParTree = ParTree.Parent > > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, > > ROOT_SECTION_TREE, ROOT_TREE] > > + if NewParTree and NewParTree.type not in ROOT_TYPE: > > + self.ModifyTest(NewParTree, Needed_Space) > > + else: > > + self.Status = True > > + > > + def ReplaceFfs(self) -> bool: > > + TargetFv = self.TargetFfs.Parent > > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child > > Ffs Header State need be reversed. > > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: > > + self.NewFfs.Data.Header.State = c_uint8( > > + ~self.NewFfs.Data.Header.State) > > + # NewFfs parsing will not calculate the PadSize, thus > recalculate. > > + self.NewFfs.Data.PadData = b'\xff' * > > GetPadSize(self.NewFfs.Data.Size, 8) > > + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size: > > + Needed_Space = self.NewFfs.Data.Size + > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > > len(self.TargetFfs.Data.PadData) > > + # If TargetFv have enough free space, just move part of the > > free space to NewFfs. > > + if TargetFv.Data.Free_Space >= Needed_Space: > > + # Modify TargetFv Child info and BiosTree. > > + TargetFv.Child[-1].Data.Data = b'\xff' * > > (TargetFv.Data.Free_Space - Needed_Space) > > + TargetFv.Data.Free_Space -= Needed_Space > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.insertChild(self.NewFfs, Target_index) > > + # Modify TargetFv Header and ExtHeader info. > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModFvSize() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + # return the Status > > + self.Status = True > > + # If TargetFv do not have enough free space, need move part > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > + else: > > + if TargetFv.type == FV_TREE: > > + self.Status = False > > + else: > > + # Recalculate TargetFv needed space to keep it > > match the BlockSize setting. > > + Needed_Space -= TargetFv.Data.Free_Space > > + BlockSize = > > TargetFv.Data.Header.BlockMap[0].Length > > + New_Add_Len = BlockSize - > > Needed_Space%BlockSize > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > + if New_Add_Len % BlockSize: > > + TargetFv.Child[-1].Data.Data = b'\xff' * > > New_Add_Len > > + TargetFv.Data.Free_Space = New_Add_Len > > + Needed_Space += New_Add_Len > > + TargetFv.insertChild(self.NewFfs, Target_index) > > + TargetFv.Child.remove(self.TargetFfs) > > + else: > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.Data.Free_Space = 0 > > + TargetFv.insertChild(self.NewFfs) > > + # Encapsulate the Fv Data for update. > > + TargetFv.Data.Data = b'' > > + for item in TargetFv.Child: > > + if item.type == FFS_FREE_SPACE: > > + TargetFv.Data.Data += item.Data.Data + > > item.Data.PadData > > + else: > > + TargetFv.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > + TargetFv.Data.Size += Needed_Space > > + # Modify TargetFv Data Header and ExtHeader info. > > + TargetFv.Data.Header.FvLength = > > TargetFv.Data.Size > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModFvSize() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + # Start free space calculating and moving process. > > + self.ModifyTest(TargetFv.Parent, Needed_Space) > > + else: > > + New_Free_Space = self.TargetFfs.Data.Size - > > self.NewFfs.Data.Size > > + # If TargetFv already have free space, move the new free > > space into it. > > + if TargetFv.Data.Free_Space: > > + TargetFv.Child[-1].Data.Data += b'\xff' * > > New_Free_Space > > + TargetFv.Data.Free_Space += New_Free_Space > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.insertChild(self.NewFfs, Target_index) > > + self.Status = True > > + # If TargetFv do not have free space, create free space for > Fv. > > + else: > > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE') > > + New_Free_Space_Tree.type = FFS_FREE_SPACE > > + New_Free_Space_Tree.Data = FfsNode(b'\xff' * > > New_Free_Space) > > + TargetFv.Data.Free_Space = New_Free_Space > > + TargetFv.insertChild(New_Free_Space) > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.insertChild(self.NewFfs, Target_index) > > + self.Status = True > > + # Modify TargetFv Header and ExtHeader info. > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModFvSize() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + return self.Status > > + > > + def AddFfs(self) -> bool: > > + # NewFfs parsing will not calculate the PadSize, thus > recalculate. > > + self.NewFfs.Data.PadData = b'\xff' * > > GetPadSize(self.NewFfs.Data.Size, 8) > > + if self.TargetFfs.type == FFS_FREE_SPACE: > > + TargetLen = self.NewFfs.Data.Size + > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > > len(self.TargetFfs.Data.PadData) > > + TargetFv = self.TargetFfs.Parent > > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, > > Child Ffs Header State need be reversed. > > + if TargetFv.Data.Header.Attributes & > > EFI_FVB2_ERASE_POLARITY: > > + self.NewFfs.Data.Header.State = c_uint8( > > + ~self.NewFfs.Data.Header.State) > > + # If TargetFv have enough free space, just move part of the > > free space to NewFfs, split free space to NewFfs and new free space. > > + if TargetLen < 0: > > + self.Status = True > > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen) > > + TargetFv.Data.Free_Space = (-TargetLen) > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + TargetFv.insertChild(self.NewFfs, -1) > > + ModifyFfsType(self.NewFfs) > > + elif TargetLen == 0: > > + self.Status = True > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.insertChild(self.NewFfs) > > + ModifyFfsType(self.NewFfs) > > + # If TargetFv do not have enough free space, need move part > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > + else: > > + if TargetFv.type == FV_TREE: > > + self.Status = False > > + elif TargetFv.type == SEC_FV_TREE: > > + # Recalculate TargetFv needed space to keep it > > match the BlockSize setting. > > + BlockSize = > > TargetFv.Data.Header.BlockMap[0].Length > > + New_Add_Len = BlockSize - TargetLen%BlockSize > > + if New_Add_Len % BlockSize: > > + self.TargetFfs.Data.Data = b'\xff' * > > New_Add_Len > > + self.TargetFfs.Data.Size = New_Add_Len > > + TargetLen += New_Add_Len > > + TargetFv.insertChild(self.NewFfs, -1) > > + TargetFv.Data.Free_Space = New_Add_Len > > + else: > > + TargetFv.Child.remove(self.TargetFfs) > > + TargetFv.insertChild(self.NewFfs) > > + TargetFv.Data.Free_Space = 0 > > + ModifyFfsType(self.NewFfs) > > + TargetFv.Data.Data = b'' > > + for item in TargetFv.Child: > > + if item.type == FFS_FREE_SPACE: > > + TargetFv.Data.Data += item.Data.Data + > > item.Data.PadData > > + else: > > + TargetFv.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > + # Encapsulate the Fv Data for update. > > + TargetFv.Data.Size += TargetLen > > + TargetFv.Data.Header.FvLength = > > TargetFv.Data.Size > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModFvSize() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + # Start free space calculating and moving process. > > + self.ModifyTest(TargetFv.Parent, TargetLen) > > + else: > > + # If TargetFv do not have free space, need directly move part > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > + TargetLen = self.NewFfs.Data.Size + > > len(self.NewFfs.Data.PadData) > > + TargetFv = self.TargetFfs.Parent > > + if TargetFv.Data.Header.Attributes & > > EFI_FVB2_ERASE_POLARITY: > > + self.NewFfs.Data.Header.State = c_uint8( > > + ~self.NewFfs.Data.Header.State) > > + if TargetFv.type == FV_TREE: > > + self.Status = False > > + elif TargetFv.type == SEC_FV_TREE: > > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length > > + New_Add_Len = BlockSize - TargetLen%BlockSize > > + if New_Add_Len % BlockSize: > > + New_Free_Space = BIOSTREE('FREE_SPACE') > > + New_Free_Space.type = FFS_FREE_SPACE > > + New_Free_Space.Data = FreeSpaceNode(b'\xff' * > > New_Add_Len) > > + TargetLen += New_Add_Len > > + TargetFv.Data.Free_Space = New_Add_Len > > + TargetFv.insertChild(self.NewFfs) > > + TargetFv.insertChild(New_Free_Space) > > + else: > > + TargetFv.insertChild(self.NewFfs) > > + ModifyFfsType(self.NewFfs) > > + TargetFv.Data.Data = b'' > > + for item in TargetFv.Child: > > + if item.type == FFS_FREE_SPACE: > > + TargetFv.Data.Data += item.Data.Data + > > item.Data.PadData > > + else: > > + TargetFv.Data.Data += > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > + TargetFv.Data.Size += TargetLen > > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size > > + TargetFv.Data.ModFvExt() > > + TargetFv.Data.ModFvSize() > > + TargetFv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(TargetFv) > > + TargetFv.Data.ModCheckSum() > > + self.ModifyTest(TargetFv.Parent, TargetLen) > > + return self.Status > > + > > + def DeleteFfs(self) -> bool: > > + Delete_Ffs = self.TargetFfs > > + Delete_Fv = Delete_Ffs.Parent > > + Add_Free_Space = Delete_Ffs.Data.Size + > > len(Delete_Ffs.Data.PadData) > > + if Delete_Fv.Data.Free_Space: > > + if Delete_Fv.type == SEC_FV_TREE: > > + Used_Size = Delete_Fv.Data.Size - > > Delete_Fv.Data.Free_Space - Add_Free_Space > > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length > > + New_Free_Space = BlockSize - Used_Size % BlockSize > > + self.Remain_New_Free_Space += > > Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space > > + Delete_Fv.Child[-1].Data.Data = New_Free_Space * > > b'\xff' > > + Delete_Fv.Data.Free_Space = New_Free_Space > > + else: > > + Used_Size = Delete_Fv.Data.Size - > > Delete_Fv.Data.Free_Space - Add_Free_Space > > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * > > b'\xff' > > + Delete_Fv.Data.Free_Space += Add_Free_Space > > + New_Free_Space = Delete_Fv.Data.Free_Space + > > Add_Free_Space > > + else: > > + if Delete_Fv.type == SEC_FV_TREE: > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length > > + New_Free_Space = BlockSize - Used_Size % BlockSize > > + self.Remain_New_Free_Space += Add_Free_Space - > > New_Free_Space > > + Add_Free_Space = New_Free_Space > > + else: > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > > + New_Free_Space = Add_Free_Space > > + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff') > > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff' > > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name) > > + New_Ffs_Tree.type = FFS_FREE_SPACE > > + New_Ffs_Tree.Data = New_Free_Space_Info > > + Delete_Fv.insertChild(New_Ffs_Tree) > > + Delete_Fv.Data.Free_Space = Add_Free_Space > > + Delete_Fv.Child.remove(Delete_Ffs) > > + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space > > + Delete_Fv.Data.ModFvExt() > > + Delete_Fv.Data.ModFvSize() > > + Delete_Fv.Data.ModExtHeaderData() > > + self.ModifyFvExtData(Delete_Fv) > > + Delete_Fv.Data.ModCheckSum() > > + self.CompressData(Delete_Fv) > > + self.Status = True > > + return self.Status > > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py > > b/BaseTools/Source/Python/FMMT/core/GuidTools.py > > new file mode 100644 > > index 000000000000..e21d8e0406ae > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py > > @@ -0,0 +1,152 @@ > > +## @file > > +# This file is used to define the FMMT dependent external tool > management > > class. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > +import glob > > +import logging > > +import os > > +import shutil > > +import sys > > +import tempfile > > +import uuid > > +from PI.Common import * > > +from utils.FmmtLogger import FmmtLogger as logger > > +import subprocess > > + > > +def ExecuteCommand(cmd: list) -> None: > > + subprocess.run(cmd,stdout=subprocess.DEVNULL) > > + > > +class GUIDTool: > > + def __init__(self, guid: str, short_name: str, command: str) -> None: > > + self.guid: str = guid > > + self.short_name: str = short_name > > + self.command: str = command > > + > > + def pack(self, buffer: bytes) -> bytes: > > + """ > > + compress file. > > + """ > > + tool = self.command > > + if tool: > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > > + ToolInputFile = os.path.join(tmp, > > "pack_uncompress_sec_file") > > + ToolOuputFile = os.path.join(tmp, "pack_sec_file") > > + try: > > + file = open(ToolInputFile, "wb") > > + file.write(buffer) > > + file.close() > > + command = [tool, '-e', '-o', ToolOuputFile, > > + ToolInputFile] > > + ExecuteCommand(command) > > + buf = open(ToolOuputFile, "rb") > > + res_buffer = buf.read() > > + except Exception as msg: > > + logger.error(msg) > > + return "" > > + else: > > + buf.close() > > + if os.path.exists(tmp): > > + shutil.rmtree(tmp) > > + return res_buffer > > + else: > > + logger.error( > > + "Error parsing section: EFI_SECTION_GUID_DEFINED > > cannot be parsed at this time.") > > + logger.info("Its GUID is: %s" % self.guid) > > + return "" > > + > > + > > + def unpack(self, buffer: bytes) -> bytes: > > + """ > > + buffer: remove common header > > + uncompress file > > + """ > > + tool = self.command > > + if tool: > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > > + ToolInputFile = os.path.join(tmp, "unpack_sec_file") > > + ToolOuputFile = os.path.join(tmp, > > "unpack_uncompress_sec_file") > > + try: > > + file = open(ToolInputFile, "wb") > > + file.write(buffer) > > + file.close() > > + command = [tool, '-d', '-o', ToolOuputFile, > ToolInputFile] > > + ExecuteCommand(command) > > + buf = open(ToolOuputFile, "rb") > > + res_buffer = buf.read() > > + except Exception as msg: > > + logger.error(msg) > > + return "" > > + else: > > + buf.close() > > + if os.path.exists(tmp): > > + shutil.rmtree(tmp) > > + return res_buffer > > + else: > > + logger.error("Error parsing section: > > EFI_SECTION_GUID_DEFINED cannot be parsed at this time.") > > + logger.info("Its GUID is: %s" % self.guid) > > + return "" > > + > > +class GUIDTools: > > + ''' > > + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools > > and provide interfaces to access those tools. > > + ''' > > + default_tools = { > > + > > struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8- > 127f4c984779 > > ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", > > "TianoCompress"), > > + > > struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e- > dc7bd79403cf > > ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", > > "LzmaCompress"), > > + > > struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a- > a4600d9dd083 > > ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", > > "GenCrc32"), > > + > > struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a- > ca72a6eae889 > > ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", > > "LzmaF86Compress"), > > + > > struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e- > 0f7f630d5afb") > > ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", > > "BrotliCompress"), > > + } > > + > > + def __init__(self, tooldef_file: str=None) -> None: > > + self.dir = os.path.dirname(__file__) > > + self.tooldef_file = tooldef_file if tooldef_file else > os.path.join( > > + self.dir, "FMMTConfig.ini") > > + self.tooldef = dict() > > + self.load() > > + > > + def VerifyTools(self) -> None: > > + """ > > + Verify Tools and Update Tools path. > > + """ > > + path_env = os.environ.get("PATH") > > + path_env_list = path_env.split(os.pathsep) > > + path_env_list.append(os.path.dirname(__file__)) > > + path_env_list = list(set(path_env_list)) > > + for tool in self.tooldef.values(): > > + cmd = tool.command > > + if os.path.isabs(cmd): > > + if not os.path.exists(cmd): > > + print("Tool Not found %s" % cmd) > > + else: > > + for syspath in path_env_list: > > + if glob.glob(os.path.join(syspath, cmd+"*")): > > + break > > + else: > > + print("Tool Not found %s" % cmd) > > + > > + def load(self) -> None: > > + if os.path.exists(self.tooldef_file): > > + with open(self.tooldef_file, "r") as fd: > > + config_data = fd.readlines() > > + for line in config_data: > > + try: > > + guid, short_name, command = line.split() > > + new_format_guid = > > struct2stream(ModifyGuidFormat(guid.strip())) > > + self.tooldef[new_format_guid] = GUIDTool( > > + guid.strip(), short_name.strip(), > > command.strip()) > > + except: > > + print("GuidTool load error!") > > + continue > > + else: > > + self.tooldef.update(self.default_tools) > > + > > + self.VerifyTools() > > + > > + def __getitem__(self, guid) -> None: > > + return self.tooldef.get(guid) > > + > > + > > +guidtools = GUIDTools() > > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > new file mode 100644 > > index 000000000000..18f0cff96e4b > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > @@ -0,0 +1,18 @@ > > +## @file > > +# This file is used to define the Fmmt Logger. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +## > > + > > +import logging > > +import sys > > + > > +FmmtLogger = logging.getLogger('FMMT') > > +FmmtLogger.setLevel(logging.INFO) > > + > > +lh=logging.StreamHandler(sys.stdout) > > +lf=logging.Formatter("%(levelname)-8s: %(message)s") > > +lh.setFormatter(lf) > > +FmmtLogger.addHandler(lh) > > \ No newline at end of file > > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > new file mode 100644 > > index 000000000000..1a6c67056266 > > --- /dev/null > > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > @@ -0,0 +1,54 @@ > > +## @file > > +# This file is used to define the printer for Bios layout. > > +# > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +## > > + > > +def GetFormatter(layout_format: str): > > + if layout_format == 'json': > > + return JsonFormatter() > > + elif layout_format == 'yaml': > > + return YamlFormatter() > > + elif layout_format == 'html': > > + return HtmlFormatter() > > + else: > > + return TxtFormatter() > > + > > +class Formatter(object): > > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None: > > + raise NotImplemented > > + > > +class JsonFormatter(Formatter): > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: > str=None) -> > > None: > > + try: > > + import json > > + except: > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > + return > > + print(outputfile) > > + if outputfile: > > + with open(outputfile,"w") as fw: > > + json.dump(layoutdict, fw, indent=2) > > + else: > > + print(json.dumps(layoutdict,indent=2)) > > + > > +class TxtFormatter(Formatter): > > + def LogPrint(self,layoutlist: list) -> None: > > + for item in layoutlist: > > + print(item) > > + print('\n') > > + > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: > str=None) -> > > None: > > + print(outputfile) > > + with open(outputfile, "w") as f: > > + for item in layoutlist: > > + f.writelines(item + '\n') > > + > > +class YamlFormatter(Formatter): > > + def dump(self,layoutdict, layoutlist, outputfile = None): > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > + > > +class HtmlFormatter(Formatter): > > + def dump(self,layoutdict, layoutlist, outputfile = None): > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > \ No newline at end of file > > -- > > 2.27.0.windows.1 > > > > > > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool 2021-12-06 8:34 ` Yuwei Chen @ 2021-12-06 9:44 ` gaoliming 0 siblings, 0 replies; 4+ messages in thread From: gaoliming @ 2021-12-06 9:44 UTC (permalink / raw) To: 'Chen, Christine', devel; +Cc: 'Feng, Bob C' Christine: I add my comments below. > -----邮件原件----- > 发件人: Chen, Christine <yuwei.chen@intel.com> > 发送时间: 2021年12月6日 16:34 > 收件人: devel@edk2.groups.io; gaoliming@byosoft.com.cn > 抄送: Feng, Bob C <bob.c.feng@intel.com> > 主题: RE: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > Hi Liming, > > Need your helps on the first and third issues: > > 1. As the PI spec defined, for Fv Header "The first 16 bytes are reserved to > allow for the reset vector of processors whose reset vector is at address 0." > The FVSEC.Fv generated did not follow the Spec definition, is this the issue of > GenFv or FMMT, are there any references for this issue? This is the expected behavior. Edk2 implementation places AP reset vector into the first 16 bytes in SEC FV. > > 3. The PEIM rebase way follows which rules? > GenFv tool has the logic to rebase PEIM on its flash address. Rebase means to relocate PE image at its flash address. So, you need to calculate PE image base address in the updated FV image, then rebase PE image on this address. Thanks Liming > Thanks, > Christine (Yuwei) > > > -----Original Message----- > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of > > gaoliming > > Sent: Friday, December 3, 2021 11:19 AM > > To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com> > > Cc: Feng, Bob C <bob.c.feng@intel.com> > > Subject: 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > > > Yuwei: > > I did some test and meet three problems. I submit BZ > > https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check. > > > > Thanks > > Liming > > > -----邮件原件----- > > > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei > Chen > > > 发送时间: 2021年12月1日 9:29 > > > 收件人: devel@edk2.groups.io > > > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao > > > <gaoliming@byosoft.com.cn> > > > 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool > > > > > > The FMMT python tool is used for firmware files operation, which has > > > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function: > > > > > > 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware > Files) > > > 2.Add a new FFS into a FV file (both included in a FD file or not) > > > 3.Replace an FFS in a FV file with a new FFS file > > > 4.Delete an FFS in a FV file (both included in a FD file or not) > > > 5.Extract the FFS from a FV file (both included in a FD file or not) > > > > > > Currently the FMMT C tool is saved in edk2-staging repo, but its > > > quality and coding style can't meet the Edk2 quality, which is hard to > > > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage). > > > > > > The new Python version keeps same functions with origin C version. It > > > has higher quality and better coding style, and it is much easier to > > > extend new functions and to maintain. > > > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847 > > > PR Link: https://github.com/tianocore/edk2-basetools/pull/12 > > > RFC Link: https://edk2.groups.io/g/devel/message/82877 > > > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT > > > > > > Cc: Bob Feng <bob.c.feng@intel.com> > > > Cc: Liming Gao <gaoliming@byosoft.com.cn> > > > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> > > > --- > > > V4 fixed the Linux file format issue and known bugs. > > > BaseTools/BinWrappers/PosixLike/FMMT | 14 + > > > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 + > > > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++ > > > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 + > > > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 > bytes > > > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 > bytes > > > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++ > > > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++ > > > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++ > > > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++ > > > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 + > > > BaseTools/Source/Python/FMMT/README.md | 180 ++++++ > > > BaseTools/Source/Python/FMMT/__init__.py | 0 > > > .../Python/FMMT/core/BinaryFactoryProduct.py | 371 > +++++++++++++ > > > BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++ > > > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++ > > > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++ > > > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++ > > > .../Source/Python/FMMT/core/FvHandler.py | 521 > > > ++++++++++++++++++ > > > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++ > > > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 + > > > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++ > > > 22 files changed, 2432 insertions(+) > > > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT > > > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat > > > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py > > > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py > > > create mode 100644 > BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py > > > create mode 100644 > > BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py > > > create mode 100644 BaseTools/Source/Python/FMMT/README.md > > > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > > create mode 100644 > > BaseTools/Source/Python/FMMT/core/FMMTParser.py > > > create mode 100644 > BaseTools/Source/Python/FMMT/core/FvHandler.py > > > create mode 100644 > BaseTools/Source/Python/FMMT/core/GuidTools.py > > > create mode 100644 > > BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > > create mode 100644 > > > BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > > > > > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT > > > b/BaseTools/BinWrappers/PosixLike/FMMT > > > new file mode 100644 > > > index 000000000000..5f5519e1e1b6 > > > --- /dev/null > > > +++ b/BaseTools/BinWrappers/PosixLike/FMMT > > > @@ -0,0 +1,14 @@ > > > +#!/usr/bin/env bash > > > +#python `dirname $0`/RunToolFromSource.py `basename $0` $* > > > + > > > +# If a ${PYTHON_COMMAND} command is available, use it in preference > > to > > > python > > > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > > > + python_exe=${PYTHON_COMMAND} > > > +fi > > > + > > > +full_cmd=${BASH_SOURCE:-$0} # see > > > http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is > not > > a > > > good choice here > > > +dir=$(dirname "$full_cmd") > > > +cmd=${full_cmd##*/} > > > + > > > +export > > > > > > PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY > > > THONPATH:+:"$PYTHONPATH"}" > > > +exec "${python_exe:-python}" -m $cmd.$cmd "$@" > > > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > > b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > > new file mode 100644 > > > index 000000000000..f0551c4ac54a > > > --- /dev/null > > > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat > > > @@ -0,0 +1,4 @@ > > > +@setlocal > > > +@set ToolName=%~n0% > > > +@set > > > > > > PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA > > > SE_TOOLS_PATH%\Source\Python\FMMT > > > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %* > > > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py > > > b/BaseTools/Source/Python/FMMT/FMMT.py > > > new file mode 100644 > > > index 000000000000..5028d8446ee0 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/FMMT.py > > > @@ -0,0 +1,117 @@ > > > +# @file > > > +# Firmware Module Management Tool. > > > +# > > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > > +# > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +# > > > +## > > > + > > > +# Import Modules > > > +# > > > +import argparse > > > +import sys > > > +from core.FMMTOperation import * > > > + > > > +parser = argparse.ArgumentParser(description=''' > > > +View the Binary Structure of FD/FV/Ffs/Section, and > > > Delete/Extract/Add/Replace a Ffs from/into a FV. > > > +''') > > > +parser.add_argument("--version", action="version", version='%(prog)s > > > Version 1.0', > > > + help="Print debug information.") > > > +parser.add_argument("-v", "--View", dest="View", nargs='+', > > > + help="View each FV and the named files within > > > each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'") > > > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+', > > > + help="Delete a Ffs from FV: '-d inputfile > > > TargetFfsName outputfile TargetFvName(Optional,\ > > > + If not given, wil delete all the existed target > > Ffs)'") > > > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+', > > > + help="Extract a Ffs Info: '-e inputfile > TargetFfsName > > > outputfile'") > > > +parser.add_argument("-a", "--Add", dest="Add", nargs='+', > > > + help="Add a Ffs into a FV:'-a inputfile > > > TargetFvName newffsfile outputfile'") > > > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+', > > > + help="Replace a Ffs in a FV: '-r inputfile > > > TargetFfsName newffsfile outputfile TargetFvName(Optional,\ > > > + If not given, wil replace all the existed > target > > > Ffs with new Ffs file)'") > > > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+', > > > + help="The format of log file which saves Binary > > > layout. Currently supports: json, txt. More formats will be added in the > > > future") > > > + > > > +def print_banner(): > > > + print("") > > > + > > > +class FMMT(): > > > + def __init__(self) -> None: > > > + self.firmware_packet = {} > > > + > > > + def CheckFfsName(self, FfsName:str) -> str: > > > + try: > > > + return uuid.UUID(FfsName) > > > + except: > > > + return FfsName > > > + > > > + def View(self, inputfile: str, logfiletype: str=None, outputfile: > > str=None) -> > > > None: > > > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile) > > > + filetype = os.path.splitext(inputfile)[1].lower() > > > + if filetype == '.fd': > > > + ROOT_TYPE = ROOT_TREE > > > + elif filetype == '.fv': > > > + ROOT_TYPE = ROOT_FV_TREE > > > + elif filetype == '.ffs': > > > + ROOT_TYPE = ROOT_FFS_TREE > > > + elif filetype == '.sec': > > > + ROOT_TYPE = ROOT_SECTION_TREE > > > + else: > > > + ROOT_TYPE = ROOT_TREE > > > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile) > > > + > > > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: > > str, > > > Fv_name: str=None) -> None: > > > + if Fv_name: > > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > > > outputfile, uuid.UUID(Fv_name)) > > > + else: > > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), > > > outputfile) > > > + > > > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> > > None: > > > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile) > > > + > > > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, > > outputfile: str) -> > > > None: > > > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, > > > outputfile) > > > + > > > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, > > outputfile: > > > str, Fv_name: str=None) -> None: > > > + if Fv_name: > > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), > > newffsfile, > > > outputfile, uuid.UUID(Fv_name)) > > > + else: > > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), > > newffsfile, > > > outputfile) > > > + > > > + > > > +def main(): > > > + args=parser.parse_args() > > > + status=0 > > > + > > > + try: > > > + fmmt=FMMT() > > > + if args.View: > > > + if args.LogFileType: > > > + fmmt.View(args.View[0], args.LogFileType[0]) > > > + else: > > > + fmmt.View(args.View[0]) > > > + if args.Delete: > > > + if len(args.Delete) == 4: > > > + > > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3]) > > > + else: > > > + > > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2]) > > > + if args.Extract: > > > + > fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2]) > > > + if args.Add: > > > + > fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3]) > > > + if args.Replace: > > > + if len(args.Replace) == 5: > > > + > > > > > > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > > > 3],args.Replace[4]) > > > + else: > > > + > > > > > > fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[ > > > 3]) > > > + # TODO: > > > + '''Do the main work''' > > > + except Exception as e: > > > + print(e) > > > + > > > + return status > > > + > > > + > > > +if __name__ == "__main__": > > > + exit(main()) > > > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > > b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > > new file mode 100644 > > > index 000000000000..aa2444f11b38 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini > > > @@ -0,0 +1,11 @@ > > > +## @file > > > +# This file is used to define the FMMT dependent external tool guid. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress > > > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress > > > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32 > > > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress > > > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress > > > diff --git > > a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png > > > new file mode 100644 > > > index > > > > 0000000000000000000000000000000000000000..7cc806a0133413a4aa037 > > > f1d43d80000546a5246 > > > GIT binary patch > > > literal 29515 > > > zcmcG$bySpZzxIs{h;*kQ- > > QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+ > > > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@- > > mueX!oILX!ky# > > > KL)-b > > > > > > z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx > > > mKL > > > > z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K > > > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A- > > ~0 > > > Os > > > zomQa`7xm?Vn1W*P-%s- > > jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK > > > u0 > > > > zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{) > > > abe > > > > z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He > > > 5*9B > > > z*-Jfk;((ApOh<DBpW00KVT- > > d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_ > > > e > > > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU- > > u*mWM > > > w) > > > > > > zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK > > > !@Kal= > > > > > > zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04 > > > 1 > > > > > > z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^ > > > W > > > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy- > > 4#Vx^C$n*R(S2#<fkNRn8K6C!26< > > > O > > > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<- > > BdBP<AmFX)1 > > > _0^ > > > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt- > > C5{L_ > > > > > > zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@ > > > YoAv$ > > > > zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o% > > > > > > z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT > > > oZlL > > > > z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk` > > > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@- > > nrRU > > > > > > zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr > > > k > > > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX- > > Sd(_WJqP_|B0b^CxF|AoL+M;CA > > > Vm > > > > > > zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT > > + > > > 5 > > > > > > z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu > > > D}JIY > > > > > > zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY > > > y > > > > z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk > > > > znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h > > > W653 > > > > zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz > > > > z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8 > > > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B- > > 8MDTh)0*RC#EN#u!^ > > > nVH$m > > > > zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd > > > m$ > > > > > > zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^| > > > 1l > > > zs#*3J+AHPINX8;)QiLwy6-Z2S$&- > > jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep > > > > > > z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l > > > As > > > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$- > > *{a=n > > > ?K!V > > > > zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb} > > > rWM > > > zKu}~4YZm`$e$42- > > HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k > > > sy > > > > > > z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU > > > CN$ > > > > > > z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG > > > |Lx3X6 > > > > > > zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt > > > P > > > z4}!3MY9t1~*EvD4lR~M)=- > > uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P! > > > > > > zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b > > > 3+@WmhX > > > z>ZGUkb+ts3Tk&n$W- > > n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C > > > Qkvs@ > > > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)- > > !o_k?1CJInjgyPOhp1A%MDgUMftCS$J~ > > > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA- > > 1pvp;SGObla#%wB7pN+^fnJc#a?jT)B > > > 8 > > > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&- > > l~CT@#e0@& > > > vmX7 > > > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*- > > 7<1UbT|>O|@l;?iY=`N4 > > > > z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*% > > > zg_$H!- > > &YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW > > > > > > z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^( > > > F<T-(} > > > > > > zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy` > > > TJt!CY > > > zZezN}4wz=94~>e){&{8Z- > > !pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c > > > PC > > > > > > z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4| > > > bv > > > > > > zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb > > > HJ6Kn > > > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78- > > 3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq > > > ;E > > > > zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9 > > > uN5=1 > > > > > > z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu > > > S > > > > > > zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D > > > p?; > > > > zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)% > > > > > > zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw > > > Z%2 > > > > z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl; > > > utt > > > > z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5 > > > W0`! > > > > > > z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59 > > > {es93C0D > > > > zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@> > > > 3g{x5 > > > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^- > > 1kaKB+d7T > > > Drx2 > > > > > > ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB > > > (wX > > > > zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u? > > > 3XkOqt > > > > > > zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX > > > DU > > > > z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy > > > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y- > > oCVYo9xaw1S?6YWT`9V^=h<QFr > > > Q} > > > zHAIHMg- > > ^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0 > > > NyW > > > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t- > > !imMfLU8CUGd)w > > > ^ > > > > > > zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ > > > L > > > > zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j} > > > * > > > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r- > > rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb > > > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ- > > ?%k;$V^R5XclbB > > > !ZjD > > > zt=UY&?7-X9<AFk^dEO%~_#P&- > > r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(= > > > tOwMb > > > > > > z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0 > > > lL_ > > > > > > z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+ > > > YC > > > > > > zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc > > > OCnX > > > > za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss > > > @v > > > zSgaMn{Kb=7It4nMlG8iA*- > > tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH > > > Y<UT > > > > > > zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M > > > y7^ > > > > > > zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf > > > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS- > > w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR > > > A2ii > > > > > > z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB > > > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V- > > {XCZzitML(}hGq&W > > > > > > zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q > > > zeC@D`Bk`qD- > > *FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS > > > bRs > > > > > > zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw > > > > > > z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0 > > > > > > zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9< > > > 3 > > > > > > zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO > > > 7{FtVq > > > zO<`- > > jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT > > > -Ie5 > > > > > > z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg > > > u > > > > > > zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV > > > aGRj! > > > > > > z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D > > > h > > > > z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o > > > M(_fvkH > > > > zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY > > > $ > > > > z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H > > > @@5TTQn > > > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|- > > *^dW > > > 5 > > > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG- > > =t3xx > > > w9x1s> > > > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)- > > ^X=?*fdvD > > > OD > > > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ- > > h^Vc`*v)kGJbP?dUI5 > > > #x > > > > > > z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o > > > S > > > > > > zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5 > > > sA > > > > > > zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A > > > -H_ > > > > > > zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq > > > Cg}S > > > zLrkk- > > #H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB > > > $or- > > > > > > z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{ > > > }W > > > > > > zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo > > > wW$ > > > znAFU~_wY4f2q?dP- > > TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D > > > &U93 > > > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>- > > &vpdCAooZEI# > > > wk{a > > > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T) > > > > > > z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c# > > > ~d > > > > > > zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt > > > z0zq > > > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5- > > iu6O > > > P@(+ > > > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p- > > UTYHHHGHJ > > > a^R > > > z4e9LSAJ3h- > > L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR > > > > > > zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO< > > > C > > > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B- > > aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad > > > u > > > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<- > > CE_@x)deTU#?kEtpbb>pf > > > JQ > > > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#- > > <B(*%Baj > > > w8bG > > > > > > z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4 > > > pUp > > > > z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j > > > kUEqfGQeE > > > zsxs)ys+*k- > > a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j > > > > > > zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G* > > > Aw_D > > > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb- > > 9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1 > > > D > > > > > > z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7 > > > X^ > > > > > > zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe > > > pj>) > > > > > > z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID< > > > < > > > > > > z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(` > > > 3v > > > > > > zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@ > > > Y8EQ > > > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>- > > &_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar > > > }<t > > > > > > zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+ > > > -Xd > > > zF@iS2N;c?&GGNFv1f- > > nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF > > > lqL! > > > > > > z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$ > > > > > > zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M > > > TTEJ1 > > > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+- > > iRa;O_hx8v1 > > > pM > > > > > > zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ > > > i-E > > > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{- > > <qQVg#k>78 > > > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#- > > fvwHu8795}6 > > > W > > > > > > z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-` > > > X2@$m4( > > > > > > zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r > > > A*% > > > zYs#3InBRHdV- > > hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L > > > > > > zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09 > > > 9|n > > > > > > zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@ > > > u > > > > zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6% > > > Ib > > > > zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU > > > *R)a;LqQ > > > > > > zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w > > > vUtt > > > > zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c > > > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE- > > {)&!(C4TBm|f@H > > > Qxf > > > > > > zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx > > > & > > > > zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%= > > > WmbM0 > > > > z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl- > > q3 > > > 6 > > > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6- > > LubB > > > c > > > > z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha > > > > > > zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh > > > g > > > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$ > > > > > > z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB > > > k2bs > > > > > > zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#( > > > t_TQ<~ > > > zPpkWLsyFv=kpB8wMCMJ461d6- > > pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB > > > WqSJV > > > > zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u > > > w9Z > > > zIQm^k)g4d<<I-`XDjPImuOoV3k- > > fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@ > > > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ- > > q&>D;Lu4Y*65q > > > 0=*^{N > > > > > > zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT > > > bF > > > > > > ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv< > > > > > > z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv > > > L > > > > > > zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5 > > > g^7sU > > > > zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*> > > > 4 > > > > > > zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t` > > > ! > > > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$- > > 5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In > > > Z;K > > > > z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u= > > > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H- > > JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V > > > J)p > > > > zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3# > > > MZ@o > > > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G- > > ;I<V5t?h0H4ZJmY{X!kNZmp3 > > > lj > > > > zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo# > > > 0G7mqVU > > > > > > zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx| > > > C^ > > > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os- > > Y*<Arj > > > @T > > > > > > zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U > > > zv&u^91`JfQ*$6*pQVC- > > u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z > > > T > > > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB- > > Dh>thr$2oA7josXpNOr1+ > > > 57 > > > > > > z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~ > > > zUK-- > > r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd > > > V-z > > > > > > zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY > > > VB& > > > > zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w* > > > oz > > > z@o`0!- > > ;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe` > > > m > > > > zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B- > > { > > > Y > > > > z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T > > > nb329 > > > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY- > > w@fzc7$VQ4tNhm5V8N(S > > > dPS > > > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8- > > C&&+<Zy65#V5 > > > > > > z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw > > > hf!j > > > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j- > > W2=miHT > > > no > > > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1- > > qeL<q;^=2F} > > > T| > > > > > > zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC > > > pwM(WO > > > z`0>B1JR`+)ZDiuFC!F7Fv- > > o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF > > > =- > > > > > > zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP > > > (nm$ > > > zgn7NXKD%P4(&M*qR- > > (Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c > > > <p > > > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av- > > 4<bCdT@wTC>GBy~|DLthW;7TX > > > boX > > > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C- > > ixZ#a}(P > > > %71 > > > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg- > > Xm`x2Xg > > > > z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA > > > qe > > > > > > z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4 > > > > z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8 > > > > z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH > > > T- > > > zH|7YArh@+FLkg- > > WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3 > > > UO`cs > > > > > > zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB) > > > 0 > > > > > > zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25 > > > zwYj@;E^4?Qbs%M^x|g>zUX- > > moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A! > > > IRJo > > > > zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL > > > wpm5C > > > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd- > > 6Ob;XHAbX$!ujWY~NcR > > > 9fz? > > > zA{m&^E5y==&`JNCtrsVh*i&iF- > > ?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj > > > mI > > > > zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r > > > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi- > > 6N<6qBRAbW>R|5Yvc<6M7$K > > > w`6V > > > > zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2 > > > q4` > > > > > > z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^ > > > |E7=& > > > zinFr&rqO5i{Cmn- > > mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U > > > ab > > > > zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO > > > > > > zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw > > > n>R7 > > > > zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc# > > > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)- > > %FkT > > > XOBB > > > > > > zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`& > > > uLj > > > > > > zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({| > > > *p > > > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X- > > Z#BGRQr2o > > > aKQ > > > > > > zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt( > > > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q- > > =mGP;tP2mL@wi(xnoq6<%Cb76W9}f > > > Ny@K > > > > > > zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O > > > pL)Fq>4 > > > > > > zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf > > > Mt > > > > z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@ > > > @Yi > > > > > > zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v > > > E` > > > > zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u > > > Q@)u > > > > > > zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4 > > > PQQA > > > > z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4 > > > ~<o<8e > > > > > > zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D > > > <J > > > > > > z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F` > > > F4& > > > > > > zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb > > > E5 > > > > > > z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z > > > #~g=O > > > > zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k > > > e1 > > > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi- > > O@I~^x{;?=(JqlKKAP)z9 > > > > zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF% > > > *F9!4P^ > > > > zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N) > > > x` > > > > > > zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82# > > > hx6wR > > > > z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp% > > > FUzQ > > > > > > zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb > > > 4G2Su$ > > > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&- > > TpdZ4Sm%Z^!(mu%Q > > > -d6 > > > z8CSq{iA^TAM+Sba`K- > > HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd > > > qw > > > > z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci > > > > zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;> > > > m > > > > > > zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW > > > DlU4VKO$Q7# > > > > > > zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF > > > m!6A > > > > z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s > > > 2 > > > > > > zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq > > > uX > > > > > > zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b > > > URoM > > > > z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T; > > > dh > > > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b- > > +I~rxJ^NTX^hUZQ_xQHPN@RYRbv= > > > OAaP0< > > > > > > z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv > > > Yry > > > > zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls> > > > &a* > > > > z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8- > > K > > > > z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m > > > > zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j > > > > > > > > > > zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW > > > d@XHe > > > zvn*f~#Zp|_nC%d- > > |J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`< > > > x-t > > > > > > zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc > > > ny< > > > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d- > > chHgloB > > > Wr|bA > > > > zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v > > > > > > z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH > > > y > > > > > > z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ > > > u7Dn > > > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_- > > YI>c&n(Yp>Lyir > > > ~@ > > > > zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-< > > > h!%= > > > z*&>EVOnq&ad$05T2- > > 6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7 > > > Tcf_kK > > > > zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve > > > HMi > > > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?- > > }0}e(EkUQx{gt5Qv2GI}9K > > > s > > > > > > z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~ > > > | > > > > zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y > > > *YvY > > > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW- > > `VxgtihK5w!+4bR%e5W4fcRUBu > > > t}=3 > > > z- > > )H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*& > > > MCZ > > > > zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&- > > > > zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}# > > > (sm; > > > > > > zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzc > > E > > > -_;{w > > > > > > zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0 > > > R!C > > > > > > z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h > > > o5lF > > > > > > z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+ > > > &#` > > > > > > zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD- > > > m$*V > > > > > > zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt > > > a > > > > > > zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+& > > > `~cD > > > > zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@> > > > U5( > > > > zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#> > > > i8( > > > > zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV > > > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ > > > > > > zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw > > > JY7J-w > > > > > > zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^ > > > NQcQ > > > > zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~ > > > > > > z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o > > > m > > > > zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y > > > C > > > z<!BcWm*#gI)Q;$>P(- > > ^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$ > > > VQ0FW > > > zGH;^fyr(a?>xrm&;uh2hKqp>D- > > AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7 > > > aZ > > > > ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z? > > > !Ajpt > > > > > > z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha > > > 7z > > > > > > z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ > > > @Ox > > > > > > zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0 > > > l > > > zVjM=Qw37|BK0|)- > > NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj > > > > z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II > > > Uz > > > > zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt} > > > MtL > > > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr- > > NH4*=bhL7Tc<AKzmQSP`%KB$^O6d > > > paf~! > > > > zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE- > > 1A > > > zv1;CZ!z3UqKTUkaP-- > > mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw* > > > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO- > > t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs > > > Eg > > > > z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$ > > > ^*M} > > > > > > zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v > > > > > > z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr > > > Z?;v@B > > > > zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_ > > > > zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb) > > > OG > > > > > > z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK > > > n{X > > > > > > z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1 > > > pZ%wkIe6 > > > > > > zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY- > > > pR > > > > zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75! > > > sSCv > > > zOI0V)+9b%8^ak8NWz6d- > > k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW& > > > !*&3( > > > zh6=X0QmwWX9XHj5l1@tYGXVhG)- > > Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+ > > > HQzlwT > > > z8x|ZZV|V(- > > wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH > > > Psf > > > > > > z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs > > > s8V7 > > > > z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj > > > z5_5g=+O$i$k;%- > > 1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO > > > 5%a > > > > z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z- > > > qZ)Dr > > > > > > z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E > > > NpfA > > > > zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0 > > > zd*)2v- > > xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k > > > XtIl50 > > > > > > zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F > > > Um > > > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}- > > _g|Ab91$j2ad2jnt > > > +=M > > > > > > znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg > > > > > > zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY > > > QmA > > > > > > zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf > > > HM# > > > > zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5 > > > VI= > > > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL- > > `KrNzBi@nX > > > eF > > > > > > z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r > > > ;!F > > > > z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t > > > xQ > > > > > > z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y| > > > p > > > > > > zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e > > > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp- > > =DEZ9aDLwe&emQpH(ng8O8f| > > > N|b > > > > > > zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO > > > -%SX > > > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm- > > Et@op > > > ^sZ > > > > > > z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW > > > 5K > > > > > > zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes > > > )B > > > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o- > > 9JRkFbj^Cvi9 > > > l63 > > > > > > z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v > > > +d4T > > > > > > z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^ > > > `QF}Y > > > zTI!eAjaQV1M2^`)i<P>gsTGz- > > UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew< > > > 3 > > > > z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V > > > mt<0 > > > > > > zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^ > > > + > > > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=- > > Jy}m > > > Zu > > > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^- > > &~y > > > sjCF > > > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC- > > gE$~l!e > > > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^- > > Xvwp0G$Ypd!Rc|ZQdfy > > > )>q > > > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d- > > LF2U( > > > N;ve > > > z`|0v08lJhE- > > 43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK| > > > T > > > > > > z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`( > > > m > > > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<- > > L*AxFh1pz<SsamItVw$U* > > > KSpI > > > > z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ > > > G; > > > > > > zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G > > > iy|~ > > > > z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw> > > > 1jO > > > > zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR > > > ~#6 > > > > > > z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W > > > ;)# > > > > zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb > > > z$n8i2c(^- > > EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN > > > 9%7z > > > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J- > > iap7Ma > > > 7+~R > > > zr)wN#;gC`Q+R- > > b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7 > > > sn > > > > zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw > > > HK > > > > > > zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz > > > zM > > > > zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c* > > > wq)= > > > > > > z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF > > > S* > > > > > > z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk- > > > _@X* > > > > > > za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~ > > > I4 > > > zMe~hi*!yt- > > e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW > > > B@ > > > > > > ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z > > > aMs11 > > > zN|%vFr}N@XKRz- > > JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW& > > > XA7Ak > > > > z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY > > > M > > > z{((;&- > > ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB > > > > > > z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S > > > KDX > > > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`- > > jSejso!@e^uJ > > > < > > > > zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG > > > HTu > > > > > > znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH > > > d+ > > > zMY- > > =jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+ > > > k&+m > > > z%ZWm1z4nMfO?(4A8G8!- > > oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+- > > > ^I > > > > z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4 > > > e|4? > > > > > > ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj# > > > ^0e > > > > zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E; > > > aO > > > > zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI) > > > d > > > > z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B > > > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA- > > +T`x7hrGd7 > > > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G- > > tP(~dNEPPRy<$X2&|cAe5A > > > }bI > > > > > > z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C > > > > > > zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM# > > > g8_@a_! > > > > z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0 > > > 06 > > > > > > zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q# > > > N > > > > zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@ > > > M4b@Z > > > > zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A > > > W > > > zDssgPVVyB-*vr3ad5~B- > > )<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f > > > wo) > > > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H- > > BNMSM32B_HnUIx=z%Fof0ntPF#j9W > > > WX+ > > > > > > zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u > > > > > > ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L > > > D0 > > > > z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$ > > > T2! > > > zdK(Bjx%p|zQnoY<UWi- > > I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb > > > Nki > > > > zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP> > > > u{Cu > > > > z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA > > > > z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a > > > @W= > > > > zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p > > > > > > zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b > > > aP~U > > > > z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS? > > > dZ > > > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T- > > wQgkxi3VLQjxyVy > > > > > > zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod > > > Up5h > > > zqp!T4LK?<KJ()xH%)kcP!N1qc- > > swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n > > > rr| > > > > z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g > > > $M > > > > > > zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG > > > nyO9 > > > > > > z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<= > > > QC > > > > > > z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO > > > 2Oi > > > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl > > > > > > zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI > > > +uw!; > > > > zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL > > > > > > z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2 > > > )p > > > > > > zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B > > > c;i! > > > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV- > > Hkg6e~c%ayO > > > }6e > > > > z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf > > > > > > zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx > > > yhi > > > > > > zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE > > > FSC > > > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz- > > *>o*46xhGpS8Y;XQ > > > *+ > > > > z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_; > > > $3Q > > > > zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9 > > > d > > > > > > zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq > > > b-| > > > zOx|zYa;20oYTSb^$f*puP6`{=@+R- > > cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs > > > C^ > > > > > > zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv > > > $0gQ > > > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#- > > a+SMQ@Tv59b7zfSbF`J@FL3|c(?~ > > > Mw6 > > > > > > zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva > > > Y > > > > z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK > > > J}o! > > > > > > zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y > > > GYg > > > > zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE > > > > > > z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ > > > QYoK > > > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ- > > ~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M > > > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{- > > p3I!HZ(Q(cX| > > > H6u > > > > > > zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@ > > > wl > > > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_- > > `ds;ZHWg<At > > > o > > > z_!d&4;KL)krKVbM_- > > %V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3 > > > > zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW? > > > s&KLw+ > > > > > > zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB( > > > ~6l > > > z==pSlrsfT~2W{Zj- > > #*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU > > > Xk > > > > > > zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1( > > > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$- > > Ow%eFF$z!@ > > > J+- > > > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R > > > > zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR > > > +Kh}Lr > > > > zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2 > > > > > > zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{a > > Q > > > > z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n > > > C)ZrQ > > > > > > zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7 > > > 6h > > > > zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW > > > > > > z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C > > > Wu8yz > > > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{) > > > zw7h- > > b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{ > > > $z*$ > > > z=zlg}>gO`p- > > 0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i > > > B > > > > z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul > > > @} > > > > z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6 > > > nc` > > > > z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU > > > > z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7 > > > 2C@ > > > > zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM > > > e > > > > zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2 > > > > > > z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg > > > 7 > > > > > > z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP > > > Su5 > > > > z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{ > > > 2 > > > > > > z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^ > > > h{bn+ > > > > zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4 > > > uNZt+ > > > > z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH > > > @17p > > > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@- > > 1E > > > 7@! > > > > z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv > > > UZA3 > > > > ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13 > > > > z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq > > > > z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2 > > > > zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH > > > > zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY > > > Ep}s > > > > > > z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox > > > > > > zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n > > > z{aj > > > > zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT > > > > zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC& > > > Q* > > > > z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@ > > > 1dFnWtdD > > > zNVk1t_y;mT- > > k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr > > > q=F > > > zDjf9;- > > DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu > > > WqN > > > > zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM > > > o0 > > > > > > zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p > > > h-@ > > > > z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK > > > HW > > > > > > z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y > > > nKla > > > > zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D! > > > B > > > > z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp > > > Zw$e > > > > zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c; > > > > za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g% > > > mO > > > > zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_- > > Hx > > > _2| > > > > zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6 > > > R4Rr > > > > > > zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N > > > > zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd > > > > > > zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6& > > > u@Wv > > > > z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6 > > > 9Jd_v > > > > > > zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a > > > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56- > > 8|HN!VHDt?X!7%VRV8^)x > > > U0D > > > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e- > > h|F2yMD^>eWe)o2zdCq!a(n?9 > > > >#f > > > > > > z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO} > > > F > > > > > > z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ > > # > > > qTm(t > > > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;- > > }$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG( > > > 6c > > > > > > zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr > > > a > > > > zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU > > > > zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h > > > <pq > > > > zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC > > > Mb > > > > zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn? > > > G > > > > z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm! > > > &o > > > > > > zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem > > > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e- > > RM%C;1ods}_Dy6=&aE!DH&yZe}Po > > > l_s&^ > > > ztt&=Z6- > > Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D} > > > 1 > > > > > > zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6 > > > Vm*0jD > > > > zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS > > > > z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|> > > > `XAJs > > > > > > z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL& > > > > z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A- > > > Mf > > > z<-7K<$G6OrXCLF&g- > > X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN > > > > > > z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il > > > {Aw9 > > > > > > zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87 > > > CC@?? > > > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo- > > ^_Ot?JdLg|1aj$ifpl{V^ > > > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C- > > R#Vcu^1XBSkb > > > = > > > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o-- > > &31)1TQ|Q%EAhuIXZd?<`#d > > > Hj > > > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1- > > k2y^JQ>&e<>!r+45@!bqRS > > > D > > > > zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#= > > > z8@e(3tmNqVWq`wXV!qG<JTY- > > Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3 > > > e-e`uBA > > > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq- > > a`x7HIXwJ=fQf_ro@BbDbjW+5A=13 > > > ?M > > > > zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A > > > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71- > > xIa;QyQ+A+=ch*hu > > > DSEC > > > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0& > > > > > > literal 0 > > > HcmV?d00001 > > > > > > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > > b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png > > > new file mode 100644 > > > index > > > > 0000000000000000000000000000000000000000..6335653ece1605cd0c53b > > > d2cc2bc21d57d213dae > > > GIT binary patch > > > literal 79906 > > > > zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$ > > > C9i > > > > > > zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c > > > } > > > > > > zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I > > > { > > > > z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7 > > > MH&Y > > > > zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM| > > > NThc > > > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M- > > DQkUsiWm_>>F`39z{F@w > > > QiMSjA > > > > > > zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^ > > > -oj > > > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB- > > Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY > > > > zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1> > > > > > > z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o > > > OF-( > > > ze(GY+PNz-|cTO$duNND)- > > {Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR& > > > %J > > > > zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{ > > > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb- > > jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD > > > > z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW > > > %3^ > > > > > > zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k > > > vG > > > > > > zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3 > > d > > > R&s7P > > > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq- > > u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt > > > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm- > > &}GK > > > x(< > > > > > > zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n > > > -t? > > > > > > z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9 > > > * > > > > z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V > > > 4Ni > > > > > > zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu > > > ^% > > > > > > z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4 > > > C= > > > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+- > > DI^9d~!WoYX0A1$ > > > X% > > > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=- > > ;cGp& > > > 30 > > > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X- > > )f2nzV!Q^qU_$m?x3Qsm > > > ex3w > > > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j- > > #eg0l|9C)@T=sxzA > > > k > > > > > > zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E > > > NK9U!c > > > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4- > > eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb > > > nmP > > > zDdg?>- > > mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a > > > R`2d( > > > > zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|< > > > D<#} > > > > > > zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o > > > 8 > > > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e- > > W7 > > > > > > zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_ > > > P > > > zLL$x|O2|$4_>pUK%4O!a-6#4- > > alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT > > > z`*O5L^inXLpWTzaUm%TSE<U`- > > Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs > > > p! > > > > z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{ > > > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR- > > #Ov6((s > > > C#V > > > > > > zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T > > > @9C > > > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&- > > x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4 > > > n= > > > > > > z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ > > > e > > > zuk|Q9*5!@y$- > > x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF > > > 8^ > > > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G- > > <BptWKsIz=W_P31e > > > > > > zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2 > > > &++Q{ > > > > > > zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv > > > Y!Bo} > > > > > > z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8 > > > P< > > > > zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z > > > RAE+ > > > > z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K > > > > > > z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e > > > g > > > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA- > > UumgF$+yN > > > ^{w > > > > > > zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR > > > {j > > > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0- > > 9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N > > > XFE > > > > zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj > > > > zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z > > > v^+ > > > > > > zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)# > > > Yhjbc; > > > > > > z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_ > > > Rx-k$ > > > > zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r > > > !n > > > > z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#}; > > > @Voub > > > > > > ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX > > > #p{~VSr > > > > > > zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2 > > > 6z*3T > > > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^- > > D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d > > > NUT > > > > zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s > > > > zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ > > > > > > znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp > > > utI > > > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg- > > y}h%yHH_0H > > > a8<A > > > > > > zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps > > > >6Mc?h > > > > > > z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e > > > TQ%X > > > > zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M- > > G > > > 2{M > > > > > > znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u& > > > Jp > > > zum8=!r+B_~0&G%_%VRj-TC~2mL- > > ot07njmvdGDQXScyh?WMt%s_phdFXEx;v > > > A6W{j > > > > z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam > > > `+(0 > > > > > > z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29 > > > @ > > > > z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On > > > @-tU=bw%s > > > > > > zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{ > > > YugQ} > > > zM8N()%W_L~2Da%^cIAH-<- > > an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v* > > > wES > > > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H- > > AhOC|1BQKucrND=U^;)jo > > > OarT+ > > > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s- > > 8ymFk^)c%duzJ;nL)3Nu > > > } > > > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx- > > &f`Khm=*XOz > > > ?S<B} > > > z%8w-r#pfF@&BNC- > > fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2 > > > 2QC!aZ > > > > > > ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP > > > W > > > > z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!% > > > U)1gME > > > zXaJ!`N#R- > > _I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk > > > > > > z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@ > > > ZQJwxv > > > > zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM > > > |FT > > > > > > z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M > > > Re<Cff; > > > > > > z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{ > > > P5 > > > > zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L > > > > > > zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg > > > uoJJp > > > > > > zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^ > > > AC > > > > > > z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f > > > > z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7- > > rV > > > rF > > > zg3F-R(c*YRq-@%swU!k`8- > > wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R( > > > 9R2;h > > > > > > z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs > > > 08Z > > > > zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r > > > wY > > > > zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a > > > %KM75 > > > > zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2 > > > > > > z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW > > > G > > > > > > zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K > > > 9+X > > > > > > zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S > > > > > > z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ > > > pa > > > > > > zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds > > > > > > zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^ > > > rj9 > > > > > > z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI > > > 7hE2 > > > > > > z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U > > > Qp > > > > > > zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P > > > u^kAGC > > > > > > zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p > > > &qx > > > zu6PAe_- > > |zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce > > > Wy}o- > > > zDVg;W`B&bT@- > > K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~ > > > > > > zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV > > > >9 > > > zsE<cJl8QUANXMMXD!_@- > > n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P > > > q > > > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC- > > =%ubEfAZ > > > @ > > > > > > zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^ > > > > zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA > > > R5My > > > > > > zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v > > > adA > > > > z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L > > > ~M > > > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW- > > e{py@ > > > Z9m > > > > zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d > > > > > > zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G > > > % > > > > > > zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y > > > 1 > > > > zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI> > > > pGi > > > z+_V- > > c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+ > > > X > > > > > > zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj > > > !|* > > > > > > z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU > > > M9o^q > > > > zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k > > > > z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y > > > > > > zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G > > > tq > > > > z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp% > > > wS# > > > > > > zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2 > > > iu$ > > > > > > zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^ > > > Q > > > > > > zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{ > > > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x > > > z- > > axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b > > > > zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d > > > > > > zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi > > > GxV > > > zW+Xgk^iMPoaLhyqRlH?kt- > > @DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~ > > > z > > > z?VV;!_jL_mlUw;2nHl- > > WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4- > > > % > > > > > > zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+ > > > UJ > > > > > > z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2 > > > >D > > > > > > z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{( > > > <dC > > > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i- > > 6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2 > > > % > > > > > > z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7 > > > D~m% > > > > > > zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU > > > wS<o > > > > > > z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT > > > h8Q > > > zoJ6nV;1DH2O4gK#e- > > q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO > > > > zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y- > > ?g > > > mho5+ > > > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane- > > R8v5Z3OKYwF7I{995>T{A1a4Im! > > > )_ > > > > zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q > > > wBco > > > > > > zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8= > > > %Fv%A > > > > > > zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl > > > ZU< > > > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0- > > }=OWCI_3x@ > > > 9 > > > > > > zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz > > > hw > > > > z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*) > > > > > > z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_ > > > > > > z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC > > > DNWo > > > > > > zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T > > > ! > > > > z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T > > > > > > z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s > > > B > > > > zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7 > > > > zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ> > > > TQCm > > > znzg- > > `v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a > > > 0J > > > zIkAk(wATQFU}lxojL8BaMgpS*sZF- > > `Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y > > > > z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e > > > > > > zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n > > > >SOcM > > > > > > zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ > > > %4x)R > > > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}- > > 7DJqPTCn{7Nz>p0rZlI4~7mz > > > > zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|! > > > g`?g > > > > > > zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO > > > cr > > > > > > zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb > > > Z!t > > > > > > zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3 > > > l8e% > > > > > > z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O > > > (n > > > > > > zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O > > > pc> > > > > > > zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>| > > > 3uW > > > > zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{ > > > UyAaR~g > > > zku^pl=~dP2`Zfc98X!v015wP- > > Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd > > > r > > > > > > zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j > > > 9 > > > > > > zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so > > > Gf%c@ > > > > > > zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62 > > > 5bew > > > > z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG > > > > > > zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN > > > ^ > > > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=- > > Y=I$JBF{x__)9E*zZEmcCFhV9%@A > > > |;C; > > > z0dw89i- > > PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%- > > > & > > > z>Q=`%q>K==&;cust- > > ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV > > > > z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9 > > > XLis > > > > zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P > > > 1}jc > > > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k- > > w~FY#E${v > > > @rK > > > > > > zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp > > > -fr0oM > > > zeqF9y$w4I3?w- > > jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU > > > Fr1!2 > > > > z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~; > > > mLh? > > > > z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj > > > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1- > > (p9OWCabzpEq45mFF > > > oK|H > > > > z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+- > > O > > > Y}tK > > > > zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a > > > > zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa > > > +|BJf > > > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo- > > {zTWc%6}gM|{b`5lyb8()nn?Zf > > > > > > zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9 > > > +T > > > > z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u > > > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%- > > (}mcvBi24si~mkArbb_~r3o|KZf^n7Uy > > > E > > > > > > z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{ > > > $e > > > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H- > > 8)+593lMa!6m;Ey~fbc > > > ;@zbu > > > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g- > > `zSeHh*X@cob > > > g_J > > > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H- > > $azMlS<h3_eAd0+EVB > > > ViPF*q=w > > > > zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS > > > Tw > > > > zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K` > > > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;- > > q=U!pbpr~8VdgFOFb > > > 5t^9 > > > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9- > > 6O1aqUt > > > > > > zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9 > > > QDz?mSX5 > > > > > > z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l > > > QHSl > > > > z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F > > > C# > > > > > > znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1 > > > > zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~ > > > H > > > > zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_ > > > oz > > > > z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K > > > DGp > > > > zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o > > > > > > zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C# > > > v9 > > > > zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s` > > > S > > > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E- > > y8jBnk?{Kg<Q(rP > > > ?aP > > > > > > zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M > > > #<y@7X > > > > > > zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P > > > e > > > > > > z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf} > > > Dot > > > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)- > > tXUE^B;?g$~2}e > > > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr- > > h5P};PfpB7o>k|p > > > # > > > > > > zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5 > > > tV > > > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz- > > o1WNRw7&EKpp!}70%&c^b > > > 4h<X* > > > > z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ< > > > GAqMM > > > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q- > > 5QmskD?C29B1Pr&(c@s&e+uwi>ijiC > > > > > > zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz > > > 6I > > > > > > zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2 > > > p^z > > > > z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3 > > > z<50dfE9+W7#lo(K- > > r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+ > > > CCm > > > > zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7 > > > 2*<<s > > > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}- > > rVwE?y%~_n0~M > > > } > > > > > > zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m > > > &MC4 > > > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw- > > XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL > > > -MC > > > > > > zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY > > > h39ZZ}0 > > > > zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb! > > > L > > > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v- > > s0rJQC*k<wIAScDz1q_$t > > > 67V9 > > > > z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M > > > @O5t > > > > > > zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X > > > NW > > > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3- > > Je!ymF9!@&)jg5>?2{8NsyKmZu > > > 0v4vt > > > > z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6 > > > m~9% > > > > > > zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$ > > > 4 > > > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls- > > oKS&kVw270i?>6=6@nEFRC5Es` > > > ~ > > > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*- > > LqT > > > F>U > > > z^KiUZAYXWSxqM(C(C=Zy<<Qa- > > QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r > > > G > > > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=- > > 4|~9MCtID_85v > > > Yp > > > > zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W} > > > hq > > > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<- > > JnxxY)Hg > > > z?YX0XeW;3- > > 48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n > > > >i > > > > > > z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU< > > > pvY2 > > > > zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb% > > > W=j > > > > > > zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re > > > %CCQ<r > > > > > > z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1# > > > &l`5 > > > > z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2? > > > |b4 > > > > > > zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx > > > E)m# > > > > > > zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV > > > >xj > > > > > > zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o > > > b|> > > > > > > zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB > > > wX}s$ > > > > z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw > > > m=%XJu > > > > > > zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf > > > XFK > > > > > > z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87 > > > omSx > > > > > > z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v > > > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#- > > 8~w<KRe>5t8O19tX > > > VdlKcX > > > > zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X| > > > > zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s > > > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza- > > 27uAu?{)Oh > > > > > > zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1 > > > u > > > > > > zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll > > > Tnbb(?( > > > > > > z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L > > > W5JPe > > > > zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT > > > G > > > > > > zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x|| > > > &@ > > > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B- > > qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y > > > Sa > > > > > > zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw > > > ( > > > zY^$M(f1CD!4Fn3S@`Lx%c?j- > > wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac > > > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7- > > Yq$ > > > gRd > > > > z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA > > > z8K_Ar&HHJwu<-S7^&Tz- > > z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D > > > Q{Qdr > > > > z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz > > > > > > zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l > > > h|` > > > > zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H > > > d> > > > > > > zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+ > > > p8T > > > > > > zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi > > > Z`#p > > > > > > z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK > > > G > > > zO!{{Gr- > > ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N > > > > z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E > > > QFcnaYc^ > > > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe- > > {}E&CO6a@=<Y;tXT*n > > > V6 > > > > > > zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC# > > > 52^ > > > > > > zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j( > > > V7D7 > > > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u- > > U{ > > > b > > > > > > z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t > > > ^wM9? > > > > zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs > > > K25^ > > > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff- > > KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt > > > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|- > > EFP&Y*s>3Yf2)ZCTs)~ > > > gJ+ > > > > zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{ > > > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G- > > PPJ0 > > > ?Kf3 > > > > > > z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o > > > Qo< > > > > zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o > > > UA= > > > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD- > > X_KaBxie|nwb|o$l{eH#^hvv27< > > > Qn > > > > zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn > > > D@ > > > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb- > > jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U( > > > > z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ > > > > > > zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$ > > > %Qo3*6 > > > > > > zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m > > > 9{p > > > > > > z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ > > > +Y > > > > zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl > > > > > > z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE > > > 9& > > > > z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$ > > > &>8io > > > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb- > > OZgaoXUvS83(PBK8FLxH<rd+PcVL > > > > z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr > > > @>iU79 > > > > zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl< > > > @ > > > > zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth* > > > NP > > > > z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_ > > > <h1r2 > > > > > > z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U > > > U^ > > > > > > zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S > > > a#=2pN > > > > > > z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T > > > KI > > > > za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp > > > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh- > > `^5g98TqP_j#KdfRYD|0YNGFhOt4 > > > #( > > > > z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy% > > > MXI4g > > > > > > zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc > > > v > > > > > > zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA > > 6 > > > 3 > > > > z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L > > > P` > > > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&- > > acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z > > > G > > > > > > zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF > > > Xihx > > > > > > zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg > > > ~d{ri!Y > > > > > > zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{ > > > > > > z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_ > > > z) > > > > > > ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi > > > x|! > > > > z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G; > > > *KA > > > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a- > > 2i*w9Y1kWggcE > > > Az > > > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz- > > Yc~Qsu2kWQ?O0sIz*2Ug$6lF > > > 7j$V > > > > > > zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN > > > bAk > > > > > > ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc > > > @ > > > zi|8mSqO-MoaYaqA_#}w?c- > > >nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G > > > 65>` > > > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog- > > (Rz@ruT7zBf!)UI > > > W~ > > > > > > z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T > > > `E > > > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^- > > ^WD > > > % > > > > zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf > > > zTyu*%V(L_|%5}>KD68- > > 34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy > > > 2 > > > > > > zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr > > > ^+)zfc4 > > > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#- > > Uk>=DjJl057_mpgxax|_Z7^eE > > > *fBXa > > > z5_DRyRueL^- > > #{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;( > > > > z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg > > > & > > > > > > zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB > > > > z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&} > > > h > > > z32!E$+=MZ91HfdyI-J- > > l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$ > > > > zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m > > > @ > > > z7tPMl@iqfxzh@Lj$xc-Z{m@G- > > GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P > > > nn4< > > > > zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX) > > > q( > > > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb- > > qV@_uT2r9>Pn}r5o@L|E > > > Y*YV > > > z0`B%7x?w2<&7x>az- > > wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1 > > > m0yoPLQ > > > > zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y > > > > > > z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W > > > mG > > > > > > zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j > > > sD@ZJ > > > > z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28 > > > 9!| > > > > zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR* > > > r7a77 > > > > > > zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG- > > > z- > > 09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e > > > WrXO > > > > > > zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC > > > TI > > > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk- > > v)o<J5KbA=o=@`(r5hoYx > > > Mi^ > > > > z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6 > > > 6N > > > > > > z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO > > > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#- > > IZ<w4%qoDyYF%VJC8 > > > ue > > > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n- > > wj*c)&TK > > > 0t? > > > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm- > > qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~ > > > z! > > > > z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56 > > > MWm- > > > > z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92 > > > W=k > > > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?- > > nog7X%sk_s<Y+v > > > *t > > > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo- > > `!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F > > > zbCM2u?}yBTP-|YUP+qtE+N- > > $^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8 > > > 3OR > > > > > > zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc| > > > ej > > > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{- > > f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~ > > > Y > > > > > > z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5 > > > mBp > > > > z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K- > > 6r > > > 9Of1 > > > > > > z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB > > > H* > > > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX- > > uT&S > > > > > > z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B > > > Z5=er > > > > zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c > > > sNof` > > > z=Hs3R{$%c!jWY- > > L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP > > > ` > > > > z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0 > > > bt > > > zlnR+ZB=thb?WfT~!j<x<0- > > aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u| > > > vh > > > > > > zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7; > > > J|z > > > > z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0& > > > > z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N > > > YbY!ry > > > > zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX > > > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2- > > <QnUzm@<!39peL;+M > > > Bzl|M > > > > > > z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_ > > > EO7gN > > > > > > zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6 > > > $i > > > > > > zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX > > > n{Of > > > > z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R > > > @dv8E > > > > > > zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@ > > > YK > > > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We- > > #w4(vmfn?Vr > > > u > > > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6- > > 4f(+RJub`mui! > > > Dw > > > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl- > > }yeK=rbpE2k2X > > > KXQx > > > > zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&! > > > 6 > > > > zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj > > > N > > > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf- > > y^iZn3c@baZ{@GX$an^4lQ&IToF+y > > > zyt > > > > > > z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd > > > > z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a? > > > S > > > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di- > > #FqXjnSNMO_Y*e|TkzT6w > > > L > > > > z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N > > > L > > > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!- > > s9+9*KOCp;tUhBW(x32 > > > DqHX > > > > > > z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+ > > > ( > > > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y- > > Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w > > > X > > > > z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq% > > > K > > > > zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel > > > > > > z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j# > > > +q& > > > > zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t) > > > MFP > > > z2e~I-K~cSXx8EG)lzE+7@73IePhx- > > ;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL > > > #F > > > > > > zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5 > > > ~|o > > > > > > z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f > > > > zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf > > > > > > zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af > > > A<3 > > > > > > zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw > > > FM4a > > > > > > zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD > > > >YZ7` > > > > > > zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd > > > W<i* > > > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q- > > dnOip*0`sN2T > > > a~yG > > > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk- > > (q@M > > > TF-Nx > > > > > > zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{ > > > ` > > > > > > zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra > > > OZX > > > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW- > > kGO+`xCf>(h{Mcc > > > %|2 > > > > zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE > > > > > > zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV > > > -5^$B > > > zPbdR=b%2- > > pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L > > > ? > > > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2- > > pNELfG(uNbq{doFM5MP7xlb)Rgq > > > < > > > > > > zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N > > > DpUF > > > > > > zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q > > > %wi~ga > > > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW- > > 3aN5iiL| > > > ` > > > > > > zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$ > > > z > > > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+- > > lbp!I4w9ZnT_6aMT~=LLkg!$R > > > l# > > > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c- > > lmKVwD > > > 3GSE9z( > > > > z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE > > > > > > zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw > > > bk > > > > > > z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo > > > a9>Y > > > > > > zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(# > > > R > > > > > > z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@ > > > K > > > > > > zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9 > > > N? > > > > > > z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw > > > K > > > zdildOB}k13;#BI@N5b9u5s- > > {=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp > > > > z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w > > > 64j > > > > > > znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>| > > > sB > > > > zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r > > > > zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL- > > $T > > > m> > > > > > > zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1 > > > 3i$ > > > > > > z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k > > > G5`&V > > > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng-- > > HdhvEg > > > EU > > > > > > z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4 > > > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$- > > Q%t!bC > > > $cv! > > > > z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO) > > > Br- > > > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C- > > 8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ > > > 9x`@ > > > > > > z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB > > > Hp} > > > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r- > > 2YOPxyr* > > > b}> > > > > > > z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A > > > DU;X > > > > > > zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@ > > > bS > > > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|- > > W+1H2CZtdm > > > OT(s > > > > > > zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J > > > zwr > > > > ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$? > > > Zisq > > > > z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo > > > > > > zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp > > > < > > > > > > z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~ > > > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x- > > |BgIJfi=ju7@WZg- > > > yi > > > > > > z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW > > > N<+%Xc6 > > > > > > z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v > > > Gh > > > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep- > > 0s*6L=4RuZ>k3UeD`pkpd= > > > K6 > > > > > > zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8 > > > a1HxFs > > > > > > zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY > > > yJ6 > > > > > > z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR* > > > & > > > z- > > =>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk > > > f > > > > > z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJ > > G > > > f > > > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C- > > m=TI!deWV<@u@B+g9zOd!H<h7 > > > 6 > > > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H- > > !7w?@Nm!4fF|H&)>RG9@xH# > > > VA%Kj > > > > zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M > > > 3@ > > > > zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x > > > > zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL > > > m2 > > > z`KG6~&Y4#$- > > >{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO > > > KIXO > > > > > > z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L > > > NUGvT > > > > > > z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr| > > > %C > > > > z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S > > > $~q > > > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o- > > IzYg)#61qGsUJ > > > @X>V > > > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY- > > L2ha3l(|O > > > P > > > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=- > > neefemATL|%SeTj > > > 7KM > > > > > > zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc > > > e > > > > > > zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u > > > L7 > > > z!mV(@!YY)C1EI1tx4- > > 6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x > > > $AP > > > zwpSBL- > > W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu > > > yMC6_ > > > zOF$m<BQ- > > 2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI< > > > T&4! > > > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~- > > ^iTXueIx8byvHT>hu$|i_OeooSft > > > n > > > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV? > > > > zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1 > > > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%- > > W88*^zKTEx>j2)~V > > > 9UTQ`* > > > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V-- > > kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL > > > 57 > > > > ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V > > > > z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL) > > > $Zo2 > > > > za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I > > > e~kMH > > > > zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?! > > > %!FY6 > > > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K- > > s2WN^ui3C{($wPhZa^$pzWR^Hl > > > 3F > > > > > > zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw > > > 4<G > > > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt- > > M7|}+UXRU7h?~TB=)5(t0^!( > > > %P > > > z- > > F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc > > > )h3ea > > > z6- > > G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W > > > Nvtc > > > > z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O > > > B-A > > > > > > zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV > > > vU`(H > > > > > > zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW > > > E37a# > > > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o- > > gou2?WYbb69sCMC}^w$$jzUo!Y& > > > ! > > > > > > zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm > > > > z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z > > > # > > > zq- > > Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV > > > L > > > > zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;| > > > > > > z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO( > > > 9zDJE > > > > z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p > > > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p- > > ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I > > > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6- > > fqr2rZ=VYP@rHCOq9pf8B0xw@Y0 > > > Q|UG > > > > > > zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY > > > > > > zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#- > > > G > > > > zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X! > > > we > > > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)- > > H!*m0eZZ!QVFvyXV^=j}!Z?!plq > > > > > > zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h > > > 3 > > > > > > zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43 > > > 0oJ > > > zI(_U{Z0qELvqlo1zMy(- > > joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq > > > I+ > > > > > > z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+ > > > VXJD) > > > z- > > q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV > > > YY0B > > > > zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC! > > > P| > > > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r- > > *H*VR4`LaS<<C1W7hg& > > > ~pO+K- > > > > > > zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM* > > > ANN > > > zUz%6;oPCB&&k^}WT*2fbT- > > rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)( > > > t{ > > > > > > zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z > > > 4P > > > z{MfuNHeOI7d~NQbki>Wa*r?}Ta- > > }c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw > > > nR7 > > > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&- > > v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0` > > > %z > > > > zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y > > > O|w1& > > > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih- > > 2{<n)!I+;AHbRo*RPPJ<gUm%2 > > > u > > > > za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP > > > d~+Gh > > > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj- > > > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?- > > BXUNalABrN}l?3DDjuoNkTNq%YT7 > > > 3F~h > > > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV- > > S%|a7B=tS!rdlDQnw_~vR > > > NG+ > > > > > > z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI > > > TI9~ > > > z80}SbU~>FO|9I4K$=- > > QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@ > > > JW;6 > > > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=- > > TSOTON|2ebg0xls`JM}%@O`g > > > K > > > zmH+=v*cCg)>)6&*G74T9ntba~IB- > > 18Gfz;WMB^neWL%=F6kixs3>vAmMHr<# > > > a{F%5 > > > zSV4%6rVjJ{9oXWh7>e;x_5=7- > > ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@ > > > Cxn#6 > > > > zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4 > > > z!jPQ@A+Wb%GhI- > > D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av > > > QoVl > > > zpg?U5sxJ^- > > s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU > > > u2u > > > > > > zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH > > > Y16t > > > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l- > > Fr_U^mpQywF > > > 7_%T > > > > z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a > > > mi% > > > > z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j# > > > @z5( > > > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi- > > XyKLb > > > hKa > > > > > > zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p > > > > > > zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt > > > i- > > > > > > zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K > > > 9fOo`p > > > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs- > > ui){uM_Y;pwOERO_ > > > ?nhh > > > > > > zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp > > > !5R#S > > > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q- > > UO22MYfNY > > > *&sB > > > > > > zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1 > > > > > > zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN > > > 1K > > > > zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt > > > > zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr > > > |TU+ > > > > zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@} > > > qgr0T7w > > > z<XUd9YdH`MV%gjTsUwYem- > > CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2# > > > 7kIj!) > > > > > > zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D > > > > z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx< > > > D`^2 > > > > z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0 > > > O > > > > > > zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w > > > )9* > > > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz- > > xEr*zAK9 > > > <N?Y > > > > z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F > > > &Xs > > > > > > z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx > > > qkyHve > > > > > > z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp > > > E(bW+ > > > > > > zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II > > > > z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a > > > > > > z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K > > > 127i > > > > zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe > > > WR1yd= > > > zOy+GS3N+k- > > ;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X > > > 8KHw > > > > > > zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM > > > wuHG > > > > z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T > > > NTye@ > > > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+- > > 8Mp5YQRWhyS@`gIr&htF@U > > > =BD#r6X7 > > > > > > zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp > > > i=M9v > > > > > > zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9 > > > f4 > > > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f- > > C*U > > > }T > > > > > > z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2 > > > T=@i > > > > > > zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_ > > > &ip > > > > z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED > > > M > > > > > > zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F > > > Ya5e > > > > zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A? > > > N> > > > > > > zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n- > > > -MxQ > > > zG1h%OC9O9yC%If5t*4BIdz)$gh>- > > Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q > > > MQ > > > > > > zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV > > > SbVYbX > > > > zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`% > > > WvX > > > > zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS > > > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d- > > XA~5}VSN6cplAA%P=_p4Y > > > qn~a > > > > zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q% > > > 9};T > > > > > > zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w# > > > X`^h > > > > > > zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_} > > > Ln= > > > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw- > > J{yCA}t$O?2Gbro_S0%@6bE|NUO7 > > > 3JAX4o > > > > zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM- > > 0 > > > <2 > > > > > > zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT > > > D9y$ > > > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4- > > pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ > > > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW- > > 8FRu~9(wk+ock12GT_ > > > Ja > > > zM^?ezBrqptKLHwLt1X- > > 1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0 > > > #5 > > > > > > zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82 > > > +` > > > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF- > > GVJ3Or!j$S_H;Jw > > > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!- > > _c(_oR > > > c| > > > > zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu > > > ma= > > > > > > zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW > > > Kn#~- > > > > > > zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO > > > XKo0` > > > > > > zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f& > > > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v- > > Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3; > > > ( > > > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y- > > BrsYiU;W<x<Ea;>dpU > > > @ > > > zmR>$-PfosIWz(r5(5<wxPbjmo;#- > > XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE > > > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N- > > z3e*X4)s#1kO^g=a > > > {~c > > > > zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl > > > > z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84} > > > qZ > > > > > > zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1 > > > vI2 > > > > > > zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP > > > |K > > > > > > zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@ > > > +3pvf > > > > > > zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc > > > 7 > > > > zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l > > > WtAe > > > > z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$ > > > w2^;3 > > > > z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7( > > > > zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844 > > > > > > z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP > > > oM > > > > > > zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+ > > > > zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j> > > > aq > > > > zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`; > > > L2G > > > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu- > > hUH$wa > > > RbE > > > > z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6 > > > mTGS > > > > z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz > > > w= > > > > > > z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID; > > > @ > > > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb- > > Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix > > > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F- > > ?Au{0G5tdd)TPX1hakJ3TvR90rM<^ > > > Y > > > > z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa > > > @~k)f > > > > > > zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m > > > L4-Kc > > > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!- > > _hOdW0;F- > > > OTOp > > > > > > zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!= > > > X+}$ > > > zFuvZ~++1ipISzO)2)RT}D;- > > aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7 > > > = > > > > > > z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7 > > > GW > > > > > > zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU > > > ePA~ > > > z_hxdvS8- > > a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E > > > > z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e > > > > zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(- > > > C#Ha|I > > > z=C2Ea@CE*LYY3?FwL2- > > o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn > > > be > > > > > > z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A > > > W=XSe- > > > > zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns > > > zM- > > {9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs > > > 456yTg > > > > z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U > > > XC > > > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_- > > =gt@_z#8g{&FBl60M > > > 8q > > > > z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl > > > < > > > > > > z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+ > > > <`F > > > > > > zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v| > > > da* > > > > zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv? > > > e > > > > > > zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM > > > P?$BB > > > zOd-J<xYW8H1RRa|E>kVw- > > `TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da > > > kHuGSr > > > > > > zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z) > > > P > > > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r# > > > > > > z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl > > > bN}< > > > zqLB8`- > > ^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX > > > u{1 > > > > > > zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ > > > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq > > > > > > zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX > > > )z(Tp > > > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD- > > jHBwcr%2 > > > 0bUM~ > > > > > > zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm > > > n > > > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f- > > bCjEDTbbkioa3 > > > AvU > > > zTgs{woXY3O- > > Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw > > > FPeX > > > > zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh; > > > > z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G > > > 86v > > > > > > zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu > > > JvQk4 > > > > > > zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An > > > t>wSc > > > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af- > > Xuf0lKfuTpKFA04 > > > 1 > > > > > > zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I; > > > hr > > > > z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+ > > > wHXl > > > zz&1Drp|7~EN?!zH5pKw!JvbXK- > > ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B > > > C!KO > > > > > > z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug > > > B$R > > > zx6k>}- > > ^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg > > > > > > zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD > > > ;>-$c > > > > zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM} > > > > > > zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO > > > P{<K > > > > zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB > > > G7 > > > > zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln > > > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7- > > kO_`Up!D&o+Zeo37N~wiT > > > 81j > > > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e- > > +C(B!Y<Aj46`65i%71cYGD{ > > > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;- > > TI~; > > > EW > > > > zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n} > > > xK > > > > > > z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I > > > > > > z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd > > > nlbj > > > > > > zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05 > > > > > > z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j- > > > Y > > > > > > zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^ > > > 7 > > > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0- > > O=A5+6B7bE > > > #7 > > > > > > zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ > > > !$pK^xF > > > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn> > > > > > z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf > > > ma;W > > > > > > zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i > > > xTr > > > > zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X} > > > ms > > > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D- > > ^e94<`cGBaYaA!4zd=KEsJn > > > eJ > > > zd%}Zl026m#*+6#l9yFz!8d8<- > > XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i > > > } > > > > > > zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+ > > > zD#6R=4Z52d(S5iva$jQAz=xFyN- > > q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~ > > > ( > > > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe > > > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG- > > UmfNcjAaL > > > Epl$S > > > > > > z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7 > > > m#Z > > > z1f>)aDLDPf#(_xvLI- > > F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g > > > XhRr > > > > > > zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f > > > > zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_ > > > <Ne~e > > > > zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S > > > > > > znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p > > > 2%fV|*A > > > > > > zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F > > > +?= > > > > > > zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D > > > 0 > > > zIugZZoN&hDJvgzTn^^1- > > d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X > > > uR > > > > zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y > > > wh4&L > > > > zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9 > > > v > > > > z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y? > > > @d>R > > > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO- > > x&lC0KfJO|C8kgnlMCC`W~^izTp? > > > z > > > > > > zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$ > > > )4 > > > > > > z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj > > > NU_ > > > > > > zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L > > > wJy > > > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o- > > D+M > > > C? > > > > > > zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R > > > @B3p > > > > zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p; > > > pe# > > > > > > z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg > > > Gu > > > z<x;1&YdE7!dLGg3LR#- > > vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H > > > xN> > > > > z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45% > > > > zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh} > > > R > > > > zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!; > > > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`- > > <Skpc > > > > > > zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI( > > > > zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck> > > > > > > zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1= > > > O7 > > > > > > zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ > > > Q > > > > z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$ > > > &S(O@ > > > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{- > > gM3Y^a > > > D&p > > > > > > zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C > > > 9 > > > > > > zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw > > > R > > > > z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA > > > Ms? > > > > zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l; > > > EF=S > > > zx7~>-e-- > > gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi > > > fo > > > > > > zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d > > > P > > > > z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx > > > RVQs > > > > z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e- > > eJ > > > (bu7W > > > > > > z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY > > > jt9 > > > > > > zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW > > > > > > zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M > > > M>h@k1 > > > > zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^ > > > > zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7 > > > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2- > > Z~r3V > > > 4w4#M}^k > > > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7- > > #MPr;?r3h8 > > > kN > > > > zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF > > > > ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p > > > 4&oPZ > > > > zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V > > > W1 > > > > zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?* > > > 5gM > > > z-dO<=pUw9Hu!6VH- > > $5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^ > > > P$ > > > > zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D? > > > W@}5 > > > > zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8 > > > _Vr > > > > zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G > > > Uu > > > > zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M% > > > 7_V&j > > > > > > zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ` > > > > > > z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG > > > z--mu$ZE#I*Q8<#GJ~- > > LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts > > > 5J#$S > > > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`- > > h@bk9 > > > O3s > > > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S- > > y+h< > > > ?#Y > > > zk-Qk=flDo- > > RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu > > > z+C9W1IPvuo^Z|- > > GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw > > > VT0 > > > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy- > > t?t~fVXzqFG>P(y1EoKn > > > x2hb > > > > > > z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b| > > > +mG > > > > > > zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D > > > !#34 > > > z-*FDsO~mox- > > k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93- > > > 5v$t > > > > > > zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO > > > CE > > > > > > zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z( > > Y > > > z)aDR~xD1dzXmhus5Q??fihY8I- > > ?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1 > > > QMq > > > > > > zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@ > > > H~~ > > > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT- > > h%26Z > > > X# > > > z7~{-@v;G{8Lxo0@cHdz4T{- > > P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur > > > +Z > > > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6- > > Xr9n > > > R6 > > > > zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf > > > w^ > > > zZ3$IK{RGVZe9g9- > > KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul > > > qu_{W > > > zTj#6IYv<7- > > Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7 > > > AD > > > z{ZzN7#^JAPYu-X7Y- > > 03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{ > > > uPf9 > > > > > > zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f > > > 4A>iW > > > > zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d > > > &( > > > > > > zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l > > > # > > > > > > zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_ > > > _~%; > > > > zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki > > > M#a > > > > > > zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D > > > vAn@ > > > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0 > > > > zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l > > > > zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~ > > > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_- > > EP9=wZkWSqwPf`a`R&_k > > > |@1@ > > > > zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj(( > > > |{) > > > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$- > > (zx$a > > > ^1S > > > zX!<JR+joeIbZEYtIBvgBnl#LV4- > > NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g > > > | > > > > > > z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp > > > > zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b > > > > z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg% > > > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz- > > khs!4b#@5QjP>U9%zLiUFG > > > ~av? > > > zeUJ9-Dv~3N$B!appHtL@3- > > IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q > > > 46kGa > > > > > > zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y > > > E > > > > zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm > > > ppAB< > > > > zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+) > > > 7 > > > > > > z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v > > > bV > > > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT- > > 57V;K;+syy?R+C30w{q70#TZ1 > > > (Ev > > > > zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V > > > @y@+N~R > > > > zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I > > > > > > zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k< > > > >s > > > > z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ > > > G+U > > > > zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U > > > S > > > > > > zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q > > > HH0-&U > > > > zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn > > > > znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt > > > > > > zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9 > > > _?krc > > > > zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF% > > > > zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(| > > > > > > z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW > > > p_`g? > > > > zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^ > > > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof} > > > > z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^-- > > > > > > zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x > > > `m > > > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA- > > cq+Wq%`jv > > > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i- > > +%|*Ny& > > > A > > > > z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA > > > &6k{Fd > > > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5- > > JAQI7W$ > > > CZ<;` > > > > zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S > > > OsN > > > > > > zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj > > > mz-w > > > > z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR > > > 7~ > > > > > > z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3 > > > D{ > > > > > > zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S > > > UN > > > > zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs > > > mu > > > > zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m; > > > Nu2W > > > > > > z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk > > > V!}} > > > zz+g- > > u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y > > > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC- > > xL=Y( > > > GRx > > > > zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q > > > > zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii > > > > > > zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM > > > XGy > > > > > > zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc > > > > zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q > > > VM > > > > > > z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU > > > > > > zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E; > > > iUxRR > > > > zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v > > > > > > zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s > > > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<- > > rUD)H9&S > > > f@E > > > > zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn > > > >#iM > > > > zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5 > > > wX% > > > > zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@ > > > > > > zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP > > > > z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298} > > > 0gs > > > > > > zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM- > > > rJhB% > > > > z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k > > > zPBTLqcmk>G0PwmJ^W#xC- > > O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6 > > > 7AvC > > > > > > zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=; > > > ?! > > > > zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*% > > > J?t7L > > > > > > zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D > > > K(~ > > > > zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL > > > > zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD > > > z*w1fD++$^@e$D7^UGJgf- > > rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3 > > > <D > > > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p- > > @)*^ > > > N(5Ei! > > > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$- > > P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu > > > ~ > > > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP- > > wj@j!4#6iMbDW)MruAkHCb1Nqxw > > > NM{ > > > > > > z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb; > > > P_l#tb4g > > > > z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P > > > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57- > > ^*tCzH+>d*z@3AV|%h%!1NOg+zH > > > >^N55 > > > > > > zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h > > > E5}(1< > > > > > > zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t > > > @BwZ > > > > > > zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t > > > ag > > > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ > > > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA- > > S)#DE > > > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe- > > +OTZJW>x%V > > > y > > > > z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz! > > > Q? > > > > > > zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW > > > VJ > > > > zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT > > > @L_3c > > > > > > zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq > > > w?L > > > > zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw- > > G< > > > ~n& > > > > > > zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC > > > {22 > > > zX- > > I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4 > > > dD% > > > z<YEj;4*V+0;|M- > > rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes > > > #~ > > > zqZrF<mFWvzkmFGC{3- > > LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d > > > G1& > > > > z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v; > > > > ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA > > > > z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+ > > > > > > z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd > > > ppY;|*f > > > zdVc@~A9~wr5$E1you*)8n4i?F-- > > }{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l& > > > wBh > > > > > > zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o > > > wnE > > > > > > zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54 > > > +~m > > > > > > ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R > > > Z> > > > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z- > > WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B& > > > MMf > > > > > > z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)| > > 2 > > > aiA > > > > > > zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8 > > > ~=75zos > > > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g- > > QOrn > > > %{ > > > > > > zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$ > > > Wvx > > > > zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P > > > Q5^ > > > > zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q > > > AJ(0a~# > > > > > > zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D > > > O* > > > > z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN > > > #0-* > > > > z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD > > > NuPv > > > z8A&gM+yWoI3+p- > > Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm > > > Rd > > > > z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki > > > No!Ys > > > > > > zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S( > > > B7X}h > > > zVR;Et%eD@V5- > > g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3 > > > #N > > > > zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx > > > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}- > > 8k0{FELICbyZM7w > > > lN > > > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{- > > JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb > > > iKo8 > > > > z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV > > > hw$ > > > > > > z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz > > > = > > > > zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe > > > Mux8; > > > > z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*; > > > =YK > > > zjl$=}dcQ- > > TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr > > > > > > zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj > > > c > > > > > > z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY > > > 3VqP > > > > ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^ > > > b4_ > > > > > > zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k > > > > > > ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC > > > 6Q_? > > > > > > zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{ > > > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;- > > zV}=Ffb;y0 > > > > z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV > > > 9?w% > > > > > > zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$ > > > `2Z9 > > > > z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK > > > MQo > > > > > > zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$ > > > #|)V;RX > > > > zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@ > > > Ox5H > > > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD- > > VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{ > > > # > > > > ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv > > > <E={9 > > > > > > zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua > > > {h > > > z1c&pk*C&s-u!f*^mD<d?d91- > > {0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{ > > > 71|@f > > > zqyCdPYA>=Yf_ZfXdKIQ7K- > > BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS= > > > *8 > > > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz-- > > =+yEpn0V;dyO#f3 > > > quY* > > > > > > z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN > > > n#x > > > > zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7) > > > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp- > > >DBbJFmh > > > ~ > > > > > > zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc > > > 359 > > > > z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP > > > > > > z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42 > > > R > > > > > > z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR- > > > }t > > > > zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc > > > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E- > > c!f2kMR<>)RwV=hmWjbJxmB > > > OGSp> > > > z=zoS%q90`C_3r-1I|(vxy$L|<- > > ~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53# > > > E3 > > > > zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o > > > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm- > > eR5re6n!d6@_6hyx( > > > I78k > > > > zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY > > > Wssf9! > > > > zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ > > > > > > zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P- > > > %+f< > > > > zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G` > > > > > > zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd > > > j+el > > > > zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G% > > > >t > > > > zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@% > > > Il^r= > > > > zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg > > > 6d?0S > > > > zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c> > > > }u > > > > > > zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh > > > +5 > > > > > > ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V > > > bfpO > > > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W- > > !~C&zci > > > |? > > > > > > z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT > > > h?j > > > > > > zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4 > > > 8K^U > > > > > > z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+ > > > 9a > > > > zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM- > > > Wn > > > z9YL6MHz1*R`Ebg>i(85{!WP- > > zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M > > > $< > > > > z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<? > > > > > > zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk > > > zjcnO0FC<- > > zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP > > > c8Q1 > > > z>8<aHYtJ``M!kq=@76^J=2^>e*+- > > ?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS > > > > z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb- > > > KY > > > > zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@) > > > {}ye > > > > zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H > > > X$b5|#j > > > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee- > > d!ko~1?$I;0XQ0Lcy}V_T > > > M9HH > > > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M- > > xe{E>sl9(>CA<_JNmMi > > > xd > > > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP- > > t~(*7E<kqy26Hww<ma171sv > > > !t#Q > > > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X- > > XGl*%Q0ElH2aXP)|ASi9~aI8 > > > )Vn > > > > > > zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s > > > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;- > > *c4|rL<x*=v#r8 > > > > > > zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$ > > > AaI > > > > > > zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M > > > -hX > > > > z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x > > > B > > > > > > zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x > > > kdv8 > > > > > > zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH > > > Z > > > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm > > > > z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv > > > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g- > > dTo#iWkSVwCW1XNNk>DTg > > > aD;g > > > > > > zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF > > > WS_L$5 > > > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk- > > &zLAxDgQMl#h~ > > > l)AM; > > > > z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK > > > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm- > > $hEIpj?<LiYD}ov|o=<+m77@%`dhAH~ > > > ua > > > > > > zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5 > > > > > > zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf > > > }$y^xf > > > > z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y > > > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk- > > N;TT > > > N~tt > > > > zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o > > > zQ-15yS^!}n- > > @U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M > > > Y69Y > > > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A- > > Rih9xWf6KdR0%$1u!qOps1C2Q# > > > ANP > > > > z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u! > > > Dqgb3Ca > > > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86- > > gbBvpzX > > > R > > > > > > z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5 > > > T > > > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj- > > hIrr3a)n*V>r6m=eJo=M3#L3_ > > > &Y > > > > > > zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7 > > > > z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^ > > > =n > > > > > > zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ > > > IJm > > > > z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9 > > > > z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz > > > g5f7(M > > > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG- > > kU > > > G* > > > > > > zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no > > > Oj > > > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)- > > 2TC_XY^XyU+7`Q)it$=yI_HeO$| > > > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}- > > n<&rw6V{rKB|$Og > > > GoBpL > > > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf- > > ;e_A#;c07yl@emICdlfx6?S > > > > zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9- > > W > > > Pr4Do > > > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x- > > OHJh=>^ > > > %$z > > > > zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf > > > R=j_i) > > > > zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb-> > > > N#* > > > > zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_ > > > zLs>gSMg&%IxgXVsk+G<1aLQyI;+- > > (x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p > > > 4d > > > > > > z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a > > > O?%3UXP > > > zmxkemLOe-bD%O81OOdPv56yFNIJswr)- > > r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR > > > n > > > > zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W > > > 5H`Q > > > > zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=) > > > @EPJJ > > > z!!F00iIqj9<FImx<- > > TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu > > > Z > > > zA@6GBn_*`<fZu;fKyYcdsVz- > > LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb > > > JP > > > > > > zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD > > > > > > z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o > > > &q > > > zxj*LqEY-ZnACrceN- > > ~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573 > > > zN&n5k9DfdGDn-n*utQW4V{X- > > IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP > > > Mq2Z > > > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4- > > Y(zEt0m3<zZQzZOBUz > > > lhe > > > > > > z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i > > > ! > > > > > > zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v= > > > 5E > > > > zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2 > > > U3cy > > > > zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL% > > > @Pb > > > > > > zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W > > > T~0Y > > > > > > zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f > > > 3EE > > > > > > z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt< > > > {8Z-8 > > > > zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE > > > m16 > > > > > > z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4 > > > LVb1o > > > > > > z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@ > > > x0z > > > > > > z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn > > > ~4&d > > > > > > zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu > > > G$}Tz > > > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ- > > Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@ > > > =?WW > > > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I- > > )fwRt3qD8qt( > > > { > > > z<P<KF=}PJ1#r#`jS-C- > > BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a > > > (X > > > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB- > > $@AJqDd(YoB@ZYfK6vP54O > > > =^o2 > > > > > > z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN > > > g > > > > zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(; > > > P > > > > zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD > > > mu > > > > > > z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF > > > {3 > > > zwPHdUsL_Emi- > > |sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx > > > tn > > > zbrc)1<0dX~X#twYtTp`&I- > > K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ > > > n > > > > > > zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5 > > > +#Xc > > > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%- > > xVei > > > qO1Hf > > > > > > z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU > > > <cW > > > > zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c- > > > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?- > > up`F97 > > > _ > > > > > > zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e > > > PVQj > > > > z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT > > > z4)s@IGNTe?4-@J{iz-J0sXQl- > > t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P > > > U} > > > > > > zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}& > > > jB > > > > > > zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9 > > > XPvK > > > > z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck > > > N > > > zH}9#C6|qJ(- > > ~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb > > > 5c > > > > zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx > > > C > > > z(- > > KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr > > > | > > > > > > zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS > > > n)edp > > > > > > zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh > > > 94r > > > > > > z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk > > > Q; > > > > > > zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS > > > > z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B! > > > zLKgK@^uHSZLNEF1>n3- > > )R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP > > > T*O > > > > z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL? > > > > zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB> > > > 4f|! > > > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF- > > f1_RXCi@Ib*0 > > > > z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4 > > > 8XtM > > > > > > z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi > > > Vn > > > zP5ZAFYbCS1g7- > > `&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G > > > uEt > > > > > > zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N > > > Vpdll > > > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a- > > 3`@t)z}?8R=?u@$Rw&yc>*^x > > > > > > zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{ > > > %xn > > > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0 > > > > zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5 > > > B > > > > > > zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm > > > 5jhv7qJ6 > > > > zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs > > > G&n > > > > zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc > > > X7Yw > > > > zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*- > > s7 > > > b^ > > > > zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm > > > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR- > > qjhh > > > O > > > > > > zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)| > > > CS > > > z^GD&-H%jsm7i~c(IDGo_- > > ?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y > > > w > > > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h- > > %XTOuIK%jeRlC4YOaKdYsipAm+ > > > WrxJ > > > > > > z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_ > > > emtz| > > > > > > zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alV > > q > > > N6 > > > > > > zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ > > > 9VH > > > > > > zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td > > > R > > > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm- > > z5jm=aFjj$na3>$mvN|33HD3iFuOn0 > > > va3 > > > > > > z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k > > > > > > zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic > > > ; > > > zO)ScHYd^W4>p1IZF- > > rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I > > > nuw > > > > > > zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq > > > ~p!H > > > > > > zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR > > > > z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH > > > @xAy1o > > > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;- > > FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq > > > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb- > > d5Kj>373=4;|gla3^9<xGWqY!YN > > > > zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF > > > ^ > > > > > > z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe > > > > z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)% > > > 6TeU > > > zDai3Q)sDP}fd8!F4@GgYGt3O#w- > > T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=& > > > !# > > > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ > > > > zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A> > > > JLS > > > > > > zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B > > > ^2@xF > > > > zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo- > > 1( > > > TU>k > > > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q- > > I>Wsn^_=%oN0?9m<2++S;$}<NQ > > > !2w > > > > z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y > > > @4wr+ > > > > > > z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW > > > igCND > > > > > > zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G > > > f > > > > > > zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM > > > +HRe > > > > zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7> > > > > za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!- > > N| > > > - > > > z;QcJ- > > _4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2 > > > Vq6r2 > > > > zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y( > > > > > > z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X > > > ^ > > > > zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL > > > > z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o > > > @ew > > > > zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij% > > > 2fn_q4 > > > > zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`> > > > =! > > > > z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw% > > > <b > > > > > > zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d > > > {;+cG) > > > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z- > > 9KqzX4ywpKgSlL&Lplu > > > #f5K > > > > > > zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN > > > Be > > > > > > zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb > > > `1J > > > > > > zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6 > > > h9# > > > > > > z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW > > > Ts > > > z@juu7- > > 1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS > > > pa} > > > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;- > > DANP > > > e- > > > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O- > > 5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5 > > > 6 > > > z4%Obc4bQ}m#H`ZWui1dCf- > > 8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q > > > a > > > > zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K> > > > Mz > > > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4- > > gIH0R$|yhL0%iyEWP) > > > -dMFq > > > > zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4; > > > > zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(- > > # > > > w5 > > > zSQe21- > > iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH > > > > > > zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=- > > > h3 > > > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#- > > u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6 > > > > > > zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V > > > B > > > > > > z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii > > > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C- > > NcZPpT3FT+YGkGFM > > > 6L6 > > > > zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3> > > > 49;t > > > > > > z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@ > > > ZoU > > > z1o^bK^- > > i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e > > > <06 > > > > > > zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23 > > > |; > > > zI- > > 8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0 > > > p%hX > > > z-z&;- > > 5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{ > > > O2 > > > > zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(* > > > > > > znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf > > > > > > zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL > > > mu > > > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt- > > )j9cW`J=^32#Q > > > _0v= > > > zYuS>- > > !$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4 > > > T3 > > > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d- > > y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%( > > > U > > > z6;SpLK}$lNH+Qlh-cKR- > > YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>& > > > oV-UQQh > > > > > > zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U( > > > c{ > > > zfIZlR!@- > > s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld* > > > > > > zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e< > > > WpJJ > > > z- > > `$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ > > > N;@<uUxT > > > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@- > > auQ<`tj > > > RFOs > > > > > > z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A > > > m > > > > > > zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A > > > G > > > > > > zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB > > > e+D$Sx > > > > zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-| > > > > z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7< > > > K > > > zTOHkDcgdOyfsEiOu%WtEi(>#Z- > > ~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY > > > u| > > > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG- > > KacrZ > > > _ > > > > zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG> > > > N9F > > > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U- > > w88FH|Vp0NA28vf|sjS > > > i! > > > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt- > > fK$0VNHs&Mk>^C1D > > > > > > zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce > > > z$GM4 > > > > zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV? > > > ?+@e > > > zg`wK!-l8aDa_m35OpOA{bq~|+%F- > > ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ > > > { > > > > zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY > > > > > > zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE > > > f!T< > > > z2ci!iV-wM?Bu7s^Huqb- > > 4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C > > > Ct6d4 > > > > > > z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p; > > > %j) > > > > > z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu > > > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%- > > (2Z`Wl > > > @e > > > > > > zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1 > > > Smv > > > > z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE > > > TIA > > > > zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH- > > #T > > > #5p > > > > z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV > > > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS- > > W4+WUsh43&>4RG*{QQ#GI!w > > > phN<ut > > > > > > z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O! > > > 8 > > > > > > z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC > > > li > > > > zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF > > > no2|(R > > > > > > zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS > > > 4D; > > > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R- > > Jpx~r9!pm?4kz;k|ao%zB@5Hbe > > > < > > > > > > z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV > > > $~Mw0 > > > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM- > > j_UaA > > > x<g; > > > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu- > > o$d)MnXpluW?a_({zl > > > g > > > > > > zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^ > > > Nsh > > > > zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^ > > > H> > > > z@#^- > > Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5# > > > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd- > > Ge_d>@ > > > =& > > > > > > zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK< > > > zN_8RoATaW}d{5!m3i1gyT+$O()xZN- > > q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n > > > > z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8` > > > AC$53 > > > > > > zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d > > > 7^x3lQL > > > > > > zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t > > > ^ > > > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n- > > ;m<n!p%lxe5r| > > > > zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD) > > > S* > > > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8- > > 9ip&dZ > > > 5@B > > > > z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja > > > > > > zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D > > > @Lj > > > > zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_` > > > ?(Q=eq > > > > > > zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su > > > ! > > > > > > zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n` > > > lly-i > > > > z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77- > > ?_ > > > D > > > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=- > > #ZF|U1if%4r0!Fqa4AKSYGr=Bp4 > > > wS;j > > > > > > zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f > > > B > > > > zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w > > > SvXa > > > > > > zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg > > > @KJ > > > > zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL` > > > =` > > > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q- > > |Gt8<U$^Rmw`&o%H;FN+S+(N > > > H@-}E > > > > z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx > > > qT > > > > > > z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ& > > > > z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7 > > > v#qf > > > > z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp* > > > M& > > > > > > z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf > > > > zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!% > > > R0i > > > > > > z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C > > > m*DkC > > > zHs9kcukmSQnY-`;FsIMBQNgVP- > > Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd > > > 6 > > > > zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU > > > 7F@} > > > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI- > > W354EXdcSk^K;5aK > > > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)- > > a48PghrZ+3AO}YN > > > &bdTo > > > > > > ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk > > > ce > > > > zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c; > > > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO- > > KB7MVoi > > > X`~8> > > > > > > z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E > > > h > > > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe- > > jybQSioRnO > > > 6 > > > zpm;JeMEQciVCPbow+)K59- > > z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs > > > X$9 > > > > > > zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps > > > 19 > > > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM- > > V3W7dJ0WrB4 > > > !!+0k > > > z;zYZk1x)Y5=+Q4I`1dZe_- > > J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~ > > > h > > > > > > zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY > > > ^|^o > > > > > > zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY > > > w > > > z8&- > > yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_ > > > Pl}l > > > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn- > > cjsU7u?E8Rr%=Go&yh&47sj4 > > > @fk~gw > > > > > > zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz; > > > Vn > > > z- > > 7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH- > > > #bB > > > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W- > > 7Me#XrQ^Tzt>kfFu8R(s > > > Yw > > > > zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi > > > G > > > > > > z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=| > > > B > > > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU- > > `l%kXo|H)KHVD6KW > > > h*Rz > > > > zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx= > > > &< > > > > > > zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT > > > > > > zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr > > > 1> > > > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx- > > gL}d<c_Mn^@%_FE+g > > > ?M > > > > zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB > > > m<8{ > > > > > > zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB > > > rHu > > > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB- > > gw(`|azE*a<_S1weMZAOo%w(L > > > )Kl > > > z- > > dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_ > > > 3&$$E$ > > > > z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3- > > B{ > > > GV > > > > zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s > > > > > > z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d > > > N > > > > > > zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f > > > E# > > > > ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l > > > 27AMD > > > > > > z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql > > > amYM > > > > zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE? > > > > zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7 > > > W<MJ > > > z%- > > SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH > > > R8=T > > > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo- > > @a)b+Ml`1F<g{$T*e1di)$*fQ5m > > > |)PQDO > > > > ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8> > > > ;g4 > > > > zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF > > > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA- > > k%PLdC*dz > > > w1? > > > > z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c< > > > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G- > > H!u*oMbA8 > > > 4$ > > > > zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q| > > > > > > z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd > > > WSp > > > > > > z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK > > > !+9 > > > > zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq% > > > zw_MRqd{G)1`B`l*- > > mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg > > > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~ > > > > > > zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA > > > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6- > > 9?bOShFo2W$of{J{ > > > gHl > > > > zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y > > > $TzS4WWp > > > > z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_} > > > > > > zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7# > > > T9bz > > > > > > zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r; > > > 7VlOw; > > > > z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g; > > > > > > zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@ > > > ~Q`G > > > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s- > > 2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v > > > z8QwfoitD*@- > > 5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j > > > ~x > > > > > > zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o > > > }${B{GLO@ > > > > z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO > > > > > > > > zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@( > > > W > > > > z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r# > > > JmFX > > > > > > zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0 > > > TYK > > > z-`2+H1Yr#7j9>- > > Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M > > > $i > > > > zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@} > > > 8Q- > > > > > > zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB > > > {d;Z$ > > > z>%q~GMLth%$)7kc<>- > > ;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX > > > =3xm > > > > > > zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2 > > > eba=c > > > > > > zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn > > > vLvp4* > > > > > > zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mM > > J > > > XCoBHnW > > > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1 > > > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f > > > > zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO- > > 2 > > > |a}K?r > > > zFo(mo@$6w!RCO;!k{m2{z- > > _`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C > > > _9 > > > > > > ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u > > > G8 > > > > > > z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o| > > > p > > > > > > z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK > > > pU > > > > zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G > > > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`- > > GBdrly&WQ1*?kDL@ > > > pG<V! > > > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3- > > JyC<keh(WCoDi(@n0xqm`@&*0R>; > > > SVa > > > > zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?- > > i$S > > > ) > > > > z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj > > > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#- > > 5>lJ2jXZ|?d~C= > > > n*V > > > > > > zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR > > > 6na4 > > > zw- > > T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L > > > i > > > zajQH#9E- > > re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L > > > 675^ > > > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T- > > 5)vkqIFntDZMA1VMOHjx#|# > > > gp > > > z<=jzFhYH`U9&O8-fDan`- > > Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ > > > s9 > > > > z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+ > > > B< > > > > zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(- > > AS > > > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W- > > JCA@y|<k2?s=otq > > > kXs > > > > zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf% > > > 6 > > > > ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg > > > V> > > > > z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}- > > > > > > zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP > > > e+{ > > > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b- > > LbUdRv*H4Cj>iO=b6AU_W > > > kt_g > > > > zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><} > > > &(L > > > > ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~ > > > > > > zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCA > > I > > > uWDE > > > > > > z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy > > > WSRlcK > > > > zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL > > > =h8r > > > > > > z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L > > > M^W > > > > z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7? > > > _YY > > > zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf( > > > > > > zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W > > > u$Jn > > > > > > zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j > > > Uyi# > > > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1- > > 7wk8y&7D+XUbG > > > qc > > > > > > zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{ > > > B? > > > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR- > > `ynB}GDY7)z8WdiaOz1? > > > $ > > > > > > z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2 > > > w_fKH^bO > > > > > > zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C> > > > r > > > > > > z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Y > > b > > > }g > > > > zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi > > > zXl`9?- > > $MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29 > > > @(BH > > > zQPs%IT;9S({?mP*=Qnc|D5J- > > |w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf= > > > c > > > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4- > > F^%90(P&<beWqvDXsg0?i > > > WV^Yr > > > > zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz > > > m*iO > > > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv- > > 0T#hDV!d > > > ^^pp > > > > > > zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{ > > > > zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I; > > > > > > zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu > > > G > > > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da- > > R)wUYvP#%R8D{%W4M3=p@E&YpC5Y > > > <^3Ym > > > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%- > > wXl_NyC`0qB > > > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr- > > wIc*7P > > > U)!KE > > > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek- > > a?2dg6PVM6GVX~3`oj > > > %%M; > > > > > > z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je > > > zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i > > > > z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`> > > > g > > > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T- > > 2DeQ#fI > > > 0ra > > > > zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90% > > > U2ISK > > > z7k~rD4m&7xFAX&{$U- > > )37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA > > > m&$g3 > > > > > > z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n > > > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;- > > d#*zW#Tye9hV)P&G*REZ2he+xK461i > > > S > > > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+- > > @izT8*fdO5W<a > > > <>h= > > > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O- > > U`a;Yy~M(7 > > > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0- > > *)&Q!XszxM?Zk > > > c > > > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>- > > Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s > > > > > > z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB > > > ^ > > > > z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y > > > mQ9 > > > z7-54~(UFH?f- > > J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V > > > zmVbN(^|1#(h+-lD+oK- > > PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W > > > b > > > zObewKL- > > P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E > > > ~AL > > > > zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ > > > mE} > > > > > > zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS > > > Ar > > > > > > zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{ > > > eM#TotF > > > zf2^1WUw|=jGZ{M_KC6YOEM6I@- > > R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ> > > > -!8~ > > > > zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G > > > w > > > > > > z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ > > > vh0 > > > z2yd+qIez;p={X=o?0- > > ^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F > > > 9F > > > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi- > > 7AsygbO%g|<oo| > > > F > > > > > > zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7 > > > mcGpsI > > > > > > zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z > > > eLf}n > > > > z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_ > > > V58p > > > > > > z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE; > > > _G > > > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?- > > MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC > > > uL| > > > > > > zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y > > > 7 > > > z*L9AUT{ijtMS0dcKOCKHpr- > > +xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR > > > p+ > > > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi- > > eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS > > > Q!<O& > > > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r- > > sKrwU > > > sCLRyE > > > > > > z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1 > > > shL > > > > zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U > > > e@ > > > > zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r > > > > > > za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp` > > > > zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4 > > > +q > > > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D- > > B$kndG=Y6ir}mBr@$2Y+D1hg2` > > > HSFo?UV4 > > > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs- > > U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73 > > > t+H6 > > > > z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W > > > 0@Pm_Y > > > > zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j) > > > > zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK > > > > zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3 > > > > z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P > > > > z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH > > > > z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t > > > $g7Mc > > > > > > z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw > > > g4XT > > > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2- > > &x>7Mi3KPo##3Vi5A!D > > > ~zVd > > > > > > zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ > > > )g}U > > > > zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo > > > aKg > > > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y- > > AD^;!g > > > x| > > > > z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3 > > > R > > > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V- > > O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v > > > OZ > > > > > > z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz- > > > DH > > > > z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52 > > > m? > > > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET- > > fIoOZ<f~u > > > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol- > > KEmeMx`wo+msu_i=!gCUc5 > > > aAFo > > > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o- > > UlMiBIpwFoxSL(w@3J7A9556*;P>na > > > q(Up` > > > > z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7 > > > > zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr > > > > > > zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5 > > > k7 > > > > > > zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i > > > ?0^U > > > > zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C > > > > zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq > > > $ > > > > > > zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm` > > > `jz` > > > > > > zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr > > > T%2I > > > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69- > > HYb > > > > > > z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9 > > > > > > zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh* > > > !tsx > > > > zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C > > > > > > z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD > > > & > > > > zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X > > > @*1fT > > > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr- > > G6WS1r9|13yh@ > > > Y{v > > > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6- > > {$zk^x|sZJl > > > O+j > > > > zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x > > > LE}S > > > zE- > > yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9` > > > UBK8 > > > zQ#_- > > WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s > > > HLzP7 > > > > > > zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om* > > > TH > > > > zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&= > > > w*FLg > > > zsI<EKP=R6SqF- > > IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D > > > k*l > > > > z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt > > > gvZ`h > > > > zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW? > > > MMr > > > > zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j% > > > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u- > > _fVYHP%QJS6G+)Vr9%12 > > > >J > > > > z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw > > > Mk8(V > > > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)- > > ?sMK$L?>Ng)`3v > > > `R > > > > > > z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl > > > NJlM > > > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi- > > f1#Bw(VP<qeg{%cT1IJ97@nLSx > > > z_X- > > ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4 > > > 5 > > > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4- > > kyiVyjuy47$ > > > @| > > > > z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk > > > q6<X@ > > > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu- > > b=1;<A1a(HF7 > > > `i > > > > z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y- > > < > > > @ > > > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb- > > %NnQFS!>!e+)H<J7 > > > % > > > > > > z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq > > > )L > > > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh- > > @%MC4@d > > > 0h&s<FN > > > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V- > > _M01I| > > > m8wTMI > > > > > > zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld > > > (#T` > > > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK- > > OFjWJG?jVvSoZ_a6 > > > jbw > > > > zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa > > > qQ > > > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX- > > B8hJF!+PDU)2Ng~^@q8b > > > e+U > > > > zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk > > > > > > zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo > > > > > > zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L > > > cp > > > zKSVWp#RY$Lhkns{H6- > > Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x > > > d} > > > > > > zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f > > > > zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*- > > i8 > > > r$$4 > > > zZOqr7#;sW- > > rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_; > > > 4Fzt > > > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob- > > K5PWDTzJUeq*If}X<4`_2c(`X*0 > > > z6;L!+h$=hX6x?t- > > Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY > > > <t#vw; > > > > > > z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG > > > zsy > > > z&r3>eq@*BKMfN&W*>mt#- > > zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d > > > 4t+{ > > > > > > zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf > > > is > > > > > > ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U; > > > ?2 > > > > > > zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv > > > *TAdi > > > > zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS > > > > zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I > > > > > > zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l > > > hv > > > > > > z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK > > > > z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K > > > B(|Tz > > > > z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+ > > > XbfG > > > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^- > > ;pwarlq8+@E8O5*D1MF > > > F1&w > > > > zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud > > > > > > zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA > > > ^H > > > > > > z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv > > > jX2 > > > RBat2OV|2<CTVmi8`9DHIo&o>> > > > > > > literal 0 > > > HcmV?d00001 > > > > > > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py > > > b/BaseTools/Source/Python/FMMT/PI/Common.py > > > new file mode 100644 > > > index 000000000000..efab874ee08b > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py > > > @@ -0,0 +1,81 @@ > > > +## @file > > > +# This file is used to define the common C struct and functions. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from ctypes import * > > > +import uuid > > > + > > > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}') > > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = > > > uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}') > > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = > > > uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}') > > > +# EFI_FFS_VOLUME_TOP_FILE_GUID = > > > uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}') > > > + > > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID = > > > uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = > > > EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes > > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID = > > > uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3' > > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = > > > b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a' > > > +EFI_SYSTEM_NVDATA_FV_GUID = > > > uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50") > > > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE = > > > b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP" > > > +EFI_FFS_VOLUME_TOP_FILE_GUID = > > > uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09") > > > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = > > > b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t' > > > +ZEROVECTOR_BYTE = > > > > b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > > > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff") > > > +FVH_SIGNATURE = b'_FVH' > > > + > > > +class GUID(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Guid1', c_uint32), > > > + ('Guid2', c_uint16), > > > + ('Guid3', c_uint16), > > > + ('Guid4', ARRAY(c_uint8, 8)), > > > + ] > > > + > > > + def from_list(self, listformat: list) -> None: > > > + self.Guid1 = listformat[0] > > > + self.Guid2 = listformat[1] > > > + self.Guid3 = listformat[2] > > > + for i in range(8): > > > + self.Guid4[i] = listformat[i+3] > > > + > > > + def __cmp__(self, otherguid) -> bool: > > > + if not isinstance(otherguid, GUID): > > > + return 'Input is not the GUID instance!' > > > + rt = False > > > + if self.Guid1 == otherguid.Guid1 and self.Guid2 == > > otherguid.Guid2 > > > and self.Guid3 == otherguid.Guid3: > > > + rt = True > > > + for i in range(8): > > > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i]) > > > + return rt > > > + > > > +def ModifyGuidFormat(target_guid: str) -> GUID: > > > + target_guid = target_guid.replace('-', '') > > > + target_list = [] > > > + start = [0,8,12,16,18,20,22,24,26,28,30] > > > + end = [8,12,16,18,20,22,24,26,28,30,32] > > > + num = len(start) > > > + for pos in range(num): > > > + new_value = int(target_guid[start[pos]:end[pos]], 16) > > > + target_list.append(new_value) > > > + new_format = GUID() > > > + new_format.from_list(target_list) > > > + return new_format > > > + > > > + > > > +# Get data from ctypes to bytes. > > > +def struct2stream(s) -> bytes: > > > + length = sizeof(s) > > > + p = cast(pointer(s), POINTER(c_char * length)) > > > + return p.contents.raw > > > + > > > + > > > + > > > +def GetPadSize(Size: int, alignment: int) -> int: > > > + if Size % alignment == 0: > > > + return 0 > > > + Pad_Size = alignment - Size % alignment > > > + return Pad_Size > > > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > > b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > > new file mode 100644 > > > index 000000000000..33c49ffb50bc > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py > > > @@ -0,0 +1,66 @@ > > > +## @file > > > +# This file is used to define the Ffs Header C Struct. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from struct import * > > > +from ctypes import * > > > +from PI.Common import * > > > + > > > +EFI_FFS_FILE_HEADER_LEN = 24 > > > +EFI_FFS_FILE_HEADER2_LEN = 32 > > > + > > > +class CHECK_SUM(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Header', c_uint8), > > > + ('File', c_uint8), > > > + ] > > > + > > > +class EFI_FFS_INTEGRITY_CHECK(Union): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Checksum', CHECK_SUM), > > > + ('Checksum16', c_uint16), > > > + ] > > > + > > > + > > > +class EFI_FFS_FILE_HEADER(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Name', GUID), > > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > > > + ('Type', c_uint8), > > > + ('Attributes', c_uint8), > > > + ('Size', ARRAY(c_uint8, 3)), > > > + ('State', c_uint8), > > > + ] > > > + > > > + @property > > > + def FFS_FILE_SIZE(self) -> int: > > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > > > + > > > + @property > > > + def HeaderLength(self) -> int: > > > + return 24 > > > + > > > +class EFI_FFS_FILE_HEADER2(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Name', GUID), > > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), > > > + ('Type', c_uint8), > > > + ('Attributes', c_uint8), > > > + ('Size', ARRAY(c_uint8, 3)), > > > + ('State', c_uint8), > > > + ('ExtendedSize', c_uint64), > > > + ] > > > + > > > + @property > > > + def FFS_FILE_SIZE(self) -> int: > > > + return self.ExtendedSize > > > + > > > + @property > > > + def HeaderLength(self) -> int: > > > + return 32 > > > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > > b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > > new file mode 100644 > > > index 000000000000..aae2feae844a > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py > > > @@ -0,0 +1,112 @@ > > > +## @file > > > +# This file is used to define the FV Header C Struct. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from ast import Str > > > +from struct import * > > > +from ctypes import * > > > +from PI.Common import * > > > + > > > +class EFI_FV_BLOCK_MAP_ENTRY(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('NumBlocks', c_uint32), > > > + ('Length', c_uint32), > > > + ] > > > + > > > + > > > +class EFI_FIRMWARE_VOLUME_HEADER(Structure): > > > + _fields_ = [ > > > + ('ZeroVector', ARRAY(c_uint8, 16)), > > > + ('FileSystemGuid', GUID), > > > + ('FvLength', c_uint64), > > > + ('Signature', c_uint32), > > > + ('Attributes', c_uint32), > > > + ('HeaderLength', c_uint16), > > > + ('Checksum', c_uint16), > > > + ('ExtHeaderOffset', c_uint16), > > > + ('Reserved', c_uint8), > > > + ('Revision', c_uint8), > > > + ('BlockMap', > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, > > > 1)), > > > + ] > > > + > > > +def Refine_FV_Header(nums): > > > + class EFI_FIRMWARE_VOLUME_HEADER(Structure): > > > + _fields_ = [ > > > + ('ZeroVector', ARRAY(c_uint8, 16)), > > > + ('FileSystemGuid', GUID), > > > + ('FvLength', c_uint64), > > > + ('Signature', c_uint32), > > > + ('Attributes', c_uint32), > > > + ('HeaderLength', c_uint16), > > > + ('Checksum', c_uint16), > > > + ('ExtHeaderOffset', c_uint16), > > > + ('Reserved', c_uint8), > > > + ('Revision', c_uint8), > > > + ('BlockMap', > > > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)), > > > + ] > > > + return EFI_FIRMWARE_VOLUME_HEADER > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): > > > + _fields_ = [ > > > + ('FvName', GUID), > > > + ('ExtHeaderSize', c_uint32) > > > + ] > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure): > > > + _fields_ = [ > > > + ('ExtEntrySize', c_uint16), > > > + ('ExtEntryType', c_uint16) > > > + ] > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('TypeMask', c_uint32) > > > + ] > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('TypeMask', c_uint32), > > > + ('Types', ARRAY(GUID, 1)) > > > + ] > > > + > > > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE: > > > + class > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('TypeMask', c_uint32), > > > + ('Types', ARRAY(GUID, nums)) > > > + ] > > > + return > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure) > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('FormatType', GUID) > > > + ] > > > + > > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('FormatType', GUID), > > > + ('Data', ARRAY(c_uint8, 1)) > > > + ] > > > + > > > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE: > > > + class > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('FormatType', GUID), > > > + ('Data', ARRAY(c_uint8, nums)) > > > + ] > > > + return > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure) > > > + > > > +class > EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure): > > > + _fields_ = [ > > > + ('Hdr', > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY), > > > + ('UsedSize', c_uint32) > > > + ] > > > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > > b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > > new file mode 100644 > > > index 000000000000..c2cc8e0172fb > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py > > > @@ -0,0 +1,110 @@ > > > +## @file > > > +# This file is used to define the Section Header C Struct. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from struct import * > > > +from ctypes import * > > > +from PI.Common import * > > > + > > > +EFI_COMMON_SECTION_HEADER_LEN = 4 > > > +EFI_COMMON_SECTION_HEADER2_LEN = 8 > > > + > > > +class EFI_COMMON_SECTION_HEADER(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Size', ARRAY(c_uint8, 3)), > > > + ('Type', c_uint8), > > > + ] > > > + > > > + @property > > > + def SECTION_SIZE(self) -> int: > > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16 > > > + > > > + def Common_Header_Size(self) -> int: > > > + return 4 > > > + > > > +class EFI_COMMON_SECTION_HEADER2(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('Size', ARRAY(c_uint8, 3)), > > > + ('Type', c_uint8), > > > + ('ExtendedSize', c_uint32), > > > + ] > > > + > > > + @property > > > + def SECTION_SIZE(self) -> int: > > > + return self.ExtendedSize > > > + > > > + def Common_Header_Size(self) -> int: > > > + return 8 > > > + > > > +class EFI_COMPRESSION_SECTION(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('UncompressedLength', c_uint32), > > > + ('CompressionType', c_uint8), > > > + ] > > > + > > > + def ExtHeaderSize(self) -> int: > > > + return 5 > > > + > > > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('SubTypeGuid', GUID), > > > + ] > > > + > > > + def ExtHeaderSize(self) -> int: > > > + return 16 > > > + > > > +class EFI_GUID_DEFINED_SECTION(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('SectionDefinitionGuid', GUID), > > > + ('DataOffset', c_uint16), > > > + ('Attributes', c_uint16), > > > + ] > > > + > > > + def ExtHeaderSize(self) -> int: > > > + return 20 > > > + > > > +def Get_USER_INTERFACE_Header(nums: int): > > > + class EFI_SECTION_USER_INTERFACE(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('FileNameString', ARRAY(c_uint16, nums)), > > > + ] > > > + > > > + def ExtHeaderSize(self) -> int: > > > + return 2 * nums > > > + > > > + def GetUiString(self) -> str: > > > + UiString = '' > > > + for i in range(nums): > > > + if self.FileNameString[i]: > > > + UiString += chr(self.FileNameString[i]) > > > + return UiString > > > + > > > + return EFI_SECTION_USER_INTERFACE > > > + > > > +def Get_VERSION_Header(nums: int): > > > + class EFI_SECTION_VERSION(Structure): > > > + _pack_ = 1 > > > + _fields_ = [ > > > + ('BuildNumber', c_uint16), > > > + ('VersionString', ARRAY(c_uint16, nums)), > > > + ] > > > + > > > + def ExtHeaderSize(self) -> int: > > > + return 2 * (nums+1) > > > + > > > + def GetVersionString(self) -> str: > > > + VersionString = '' > > > + for i in range(nums): > > > + if self.VersionString[i]: > > > + VersionString += chr(self.VersionString[i]) > > > + return VersionString > > > + > > > + return EFI_SECTION_VERSION > > > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py > > > b/BaseTools/Source/Python/FMMT/PI/__init__.py > > > new file mode 100644 > > > index 000000000000..4e8296fad1ba > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py > > > @@ -0,0 +1,6 @@ > > > +## @file > > > +# This file is used to define the FMMT dependent external tool > > management > > > class. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/README.md > > > b/BaseTools/Source/Python/FMMT/README.md > > > new file mode 100644 > > > index 000000000000..e14dfa34ea66 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/README.md > > > @@ -0,0 +1,180 @@ > > > +# FMMT > > > +## Overview > > > +This FMMT tool is the python implementation of the edk2 FMMT tool > > which > > > locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt. > > > +This implementation has the same usage as the edk2 FMMT, but it's > more > > > readable and relaiable. > > > + > > > +# FMMT User Guide > > > + > > > +#### Last updated October 13, 2021 > > > + > > > +Important Changes and Updates: > > > + > > > +- Oct 13, 2021 Initial Draft of FMMT Python Tool > > > + > > > +#### Note: > > > + > > > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is > > > much easier to maintain and extend other functions. > > > + > > > + > > > + > > > +# 1. Introduction > > > + > > > +## 1.1 Overview > > > + > > > +The Firmware Device is a persistent physical repository that contains > > > firmware code and/or data. The firmware code and/or data stored in > > > Firmware Volumes. Detail layout of Firmware Volumes is described in > > ?Figure > > > 1. The Firmware Volume Format?. > > > + > > > +![](Img/FirmwareVolumeFormat.png) > > > + > > > +<center>Figure 1. The Firmware Volume Format</center> > > > + > > > +In firmware development, binary file has its firmware layout following > > the > > > Platform-Initialization Specification. Thus, operation on FV file / FFS > > file > > > (Firmware File) is an efficient and convenient way for firmware function > > > testing and developing. FMMT Python tool is used for firmware files > > > operation. > > > + > > > +## 1.2 Tool Capabilities > > > + > > > +The FMMT tool is capable of: > > > + > > > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware > > > Files) > > > + > > > +- Add a new FFS into a FV file (both included in a FD file or not) > > > + > > > +- Replace an FFS in a FV file with a new FFS file > > > + > > > +- Delete an FFS in a FV file (both included in a FD file or not) > > > + > > > +- Extract the FFS from a FV file (both includ-v < Inputfile > < > > Outputfile >ed > > > in a FD file or not) > > > + > > > +## 1.3 References > > > + > > > +| Document | > > > +| ------------------------------------------------ | > > > +| UEFI Platform Initialization (PI) Specification | > > > + > > > + > > > + > > > +# 2. FMMT Python Tool Usage > > > + > > > +## 2.1 Required Files > > > + > > > +### 2.1.1 Independent use > > > + > > > +When independent use the FMMT Python Tool, the following files and > > > settings are required: > > > + > > > +- GuidTool executable files used for Decompress/Compress Firmware > data. > > > + > > > +- Environment variables path with GuidTool path setting. > > > + > > > +### 2.1.2 Use with Build System > > > + > > > +When use the FMMT Python Tool with Build System: > > > + > > > +- If only use Edk2 based GuidTool, do not need other preparation. > > > + > > > +- If use other customized GuidTool, need prepare the config file with > > GuidTool > > > info. The syntax for GuidTool definition shown as follow: > > > + > > > + ***ToolsGuid ShortName Command*** > > > + > > > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI > > > BrotliCompress*** > > > + > > > +## 2.2 Syntax > > > + > > > +### 2.2.1 Syntax for Parse file > > > + > > > +***-v < Inputfile > < Outputfile > -l < LogFileType >*** > > > + > > > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* > > is > > > optional, if inputs, the *Inputfile* will be encapsulated into > > *Outputfile* > > > following the parsed firmware layout. *"-l LogFileType"* is optional, it > > decides > > > the format of log file which saves Binary layout. Currently supports: > > json, txt. > > > More formats will be added in the future. > > > + > > > +### 2.2.2 Syntax for Add a new FFS > > > + > > > +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < > > > Outputfile >*** > > > + > > > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* > > > (Name or Guid) is the TargetFv which *NewFfsFile* will be added into. > > > + > > > +### 2.2.3 Syntax for Delete an FFS > > > + > > > +***-d < Inputfile > < TargetFfsName > < Outputfile > < > > > TargetFvName/TargetFvGuid >*** > > > + > > > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs > > > which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is > > the > > > parent of TargetFfs*.* > > > + > > > +### 2.2.4 Syntax for Replace an FFS > > > + > > > +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < > > > TargetFvName/TargetFvGuid >*** > > > + > > > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the > > TargetFfs > > > which will be replaced. *TargetFvName/TargetFvGuid* is optional, which > is > > > the parent of TargetFfs*.* > > > + > > > +### 2.2.5 Syntax for Extract an FFS > > > + > > > +***-e < Inputfile > < TargetFfsName > < Outputfile >*** > > > + > > > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the > > TargetFfs > > > which will be extracted. > > > + > > > + > > > + > > > +# 3. FMMT Python Tool Design > > > + > > > +FMMT Python Tool uses the NodeTree saves whole Firmware layout. > Each > > > Node have its Data field, which saves the > > > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the > > > parse/add/delete/replace/extract operations are based on the NodeTree > > > (adjusting the layout and data). > > > + > > > +## 3.1 NodeTree > > > + > > > +A whole NodeTree saves all the Firmware info. > > > + > > > +- Parent & Child relationship figured out the Firmware layout. > > > + > > > +- Each Node have several fields. ?Data? field saves an FirmwareClass > > > instance which contains all the data info of the info. > > > + > > > +### 3.1.1 NodeTree Format > > > + > > > +The NodeTree will be created with parse function. When parse a file, a > > Root > > > Node will be initialized firstly. The Data split and Tree construction > > process is > > > described with an FD file shown as ?Figure 2. The NodeTree format?: > > > + > > > +- A Root Node is initialized. > > > + > > > +- Use the ?FV Signature? as FV key to split Whole FD > > > Data. ?FV0?, ?FV1?, ?FV2?? Node created. > > > + > > > +- After FV level Node created, use the ?Ffs Data Size? as FFS key to > > split each > > > FV Data. ?Ffs0?...Node created. > > > + > > > +- After FFS level Node created, use the ?Section Data Size? as Section > > key to > > > split each Ffs Data. ?Section0?...Node created. > > > + > > > +- If some of Section includes other Sections, continue use the ?Section > > Data > > > Size? as Section key to split each Section Data. > > > + > > > +- After all Node created, the whole NodeTree saves all the info. (Can be > > used > > > in other functions or print the whole firmware layout into log file) > > > + > > > +![](Img/NodeTreeFormat.png) > > > + > > > +<center>Figure 2. The NodeTree format</center> > > > + > > > +### 3.1.2 Node Factory and Product > > > + > > > +As 3.1.1, Each Node is created by data split and recognition. To extend > > the > > > NodeTree usage, Factory pattern is used in Node created process. > > > + > > > +Each Node have its Factory to create Product and use Product > ParserData > > > function to deal with the data. > > > + > > > +## 3.2 GuidTool > > > + > > > +There are two ways to set the GuidTool. One from Config file, another > > from > > > environment variables. > > > + > > > +Current GuidTool first check if has Config file. > > > + > > > +- If have, load the config GuidTool Information. > > > + > > > +- Else get from environment variables. > > > + > > > +### 3.2.1 Get from Config file > > > + > > > +- Config file should in same folder with FMMT.py or the path in > > environment > > > variables. > > > + > > > +- Content should follow the format: > > > + > > > + ***ToolsGuid ShortName Command*** > > > + > > > +### 3.2.2 Get from Environment Variables > > > + > > > +- The GuidTool Command used must be set in environment variables. > > > + > > > +### 3.2.3 Edk2 Based GuidTool > > > + > > > +| ***Guid*** | > ***ShortName*** > > > | ***Command*** | > > > +| ------------------------------------------ | --------------- | > > --------------------- | > > > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** > | > > > ***TianoCompress*** | > > > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** > | > > > ***LzmaCompress*** | > > > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** > | > > > ***GenCrc32*** | > > > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** > | > > > ***LzmaF86Compress*** | > > > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** > | > > > ***BrotliCompress*** | > > > diff --git a/BaseTools/Source/Python/FMMT/__init__.py > > > b/BaseTools/Source/Python/FMMT/__init__.py > > > new file mode 100644 > > > index 000000000000..e69de29bb2d1 > > > diff --git > a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > > new file mode 100644 > > > index 000000000000..33ffe73cab27 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py > > > @@ -0,0 +1,371 @@ > > > +## @file > > > +# This file is used to implement of the various bianry parser. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from re import T > > > +import copy > > > +import os > > > +from PI.Common import * > > > +from core.BiosTreeNode import * > > > +from core.BiosTree import * > > > +from core.GuidTools import * > > > + > > > +ROOT_TREE = 'ROOT' > > > +ROOT_FV_TREE = 'ROOT_FV_TREE' > > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > > > + > > > +FV_TREE = 'FV' > > > +DATA_FV_TREE = 'DATA_FV' > > > +FFS_TREE = 'FFS' > > > +FFS_PAD = 'FFS_PAD' > > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > > > +SECTION_TREE = 'SECTION' > > > +SEC_FV_TREE = 'SEC_FV_IMAGE' > > > +BINARY_DATA = 'BINARY' > > > +Fv_count = 0 > > > + > > > +## Abstract factory > > > +class BinaryFactory(): > > > + type:list = [] > > > + > > > + def Create_Product(): > > > + pass > > > + > > > +class BinaryProduct(): > > > + ## Use GuidTool to decompress data. > > > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes: > > > + ParPath = > > > > > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. > > ") > > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > > > + guidtool = > > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > > > + DecompressedData = guidtool.unpack(Section_Data) > > > + return DecompressedData > > > + > > > + def ParserData(): > > > + pass > > > + > > > +class SectionFactory(BinaryFactory): > > > + type = [SECTION_TREE] > > > + > > > + def Create_Product(): > > > + return SectionProduct() > > > + > > > +class FfsFactory(BinaryFactory): > > > + type = [ROOT_SECTION_TREE, FFS_TREE] > > > + > > > + def Create_Product(): > > > + return FfsProduct() > > > + > > > +class FvFactory(BinaryFactory): > > > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE] > > > + > > > + def Create_Product(): > > > + return FvProduct() > > > + > > > +class FdFactory(BinaryFactory): > > > + type = [ROOT_FV_TREE, ROOT_TREE] > > > + > > > + def Create_Product(): > > > + return FdProduct() > > > + > > > +class SectionProduct(BinaryProduct): > > > + ## Decompress the compressed section. > > > + def ParserData(self, Section_Tree, whole_Data: bytes, > > > Rel_Whole_Offset: int=0) -> None: > > > + if Section_Tree.Data.Type == 0x01: > > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > > + self.ParserFfs(Section_Tree, b'') > > > + # Guided Define Section > > > + elif Section_Tree.Data.Type == 0x02: > > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > > + DeCompressGuidTool = > > > Section_Tree.Data.ExtHeader.SectionDefinitionGuid > > > + Section_Tree.Data.Data = > > > self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data) > > > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) + > > > Section_Tree.Data.HeaderLength > > > + self.ParserFfs(Section_Tree, b'') > > > + elif Section_Tree.Data.Type == 0x03: > > > + Section_Tree.Data.OriData = Section_Tree.Data.Data > > > + self.ParserFfs(Section_Tree, b'') > > > + # SEC_FV Section > > > + elif Section_Tree.Data.Type == 0x17: > > > + global Fv_count > > > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data) > > > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count)) > > > + Sec_Fv_Tree.type = SEC_FV_TREE > > > + Sec_Fv_Tree.Data = Sec_Fv_Info > > > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset > > > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + > > > Sec_Fv_Tree.Data.Header.HeaderLength > > > + Sec_Fv_Tree.Data.Data = > > > Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:] > > > + Section_Tree.insertChild(Sec_Fv_Tree) > > > + Fv_count += 1 > > > + > > > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > > int=0) -> None: > > > + Rel_Offset = 0 > > > + Section_Offset = 0 > > > + # Get the Data from parent tree, if do not have the tree then > get > > it > > > from the whole_data. > > > + if ParTree.Data != None: > > > + Data_Size = len(ParTree.Data.Data) > > > + Section_Offset = ParTree.Data.DOffset > > > + Whole_Data = ParTree.Data.Data > > > + else: > > > + Data_Size = len(Whole_Data) > > > + # Parser all the data to collect all the Section recorded in its > > Parent > > > Section. > > > + while Rel_Offset < Data_Size: > > > + # Create a SectionNode and set it as the SectionTree's > Data > > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > > > + Section_Tree = BIOSTREE(Section_Info.Name) > > > + Section_Tree.type = SECTION_TREE > > > + Section_Info.Data = > > > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > > > Rel_Offset+Section_Info.Size] > > > + Section_Info.DOffset = Section_Offset + > > > Section_Info.HeaderLength + Rel_Whole_Offset > > > + Section_Info.HOffset = Section_Offset + > Rel_Whole_Offset > > > + Section_Info.ROffset = Rel_Offset > > > + if Section_Info.Header.Type == 0: > > > + break > > > + # The final Section in parent Section does not need to add > > > padding, else must be 4-bytes align with parent Section start offset > > > + Pad_Size = 0 > > > + if > > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != > > Data_Size): > > > + Pad_Size = GetPadSize(Section_Info.Size, 4) > > > + Section_Info.PadData = Pad_Size * b'\x00' > > > + if Section_Info.Header.Type == 0x02: > > > + Section_Info.DOffset = Section_Offset + > > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > > > + Section_Info.Data = > > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > > > Rel_Offset+Section_Info.Size] > > > + if Section_Info.Header.Type == 0x14: > > > + ParTree.Data.Version = > > > Section_Info.ExtHeader.GetVersionString() > > > + if Section_Info.Header.Type == 0x15: > > > + ParTree.Data.UiName = > > > Section_Info.ExtHeader.GetUiString() > > > + Section_Offset += Section_Info.Size + Pad_Size > > > + Rel_Offset += Section_Info.Size + Pad_Size > > > + Section_Tree.Data = Section_Info > > > + ParTree.insertChild(Section_Tree) > > > + > > > +class FfsProduct(BinaryProduct): > > > + # ParserFFs / GetSection > > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > > int=0) -> None: > > > + Rel_Offset = 0 > > > + Section_Offset = 0 > > > + # Get the Data from parent tree, if do not have the tree then > get > > it > > > from the whole_data. > > > + if ParTree.Data != None: > > > + Data_Size = len(ParTree.Data.Data) > > > + Section_Offset = ParTree.Data.DOffset > > > + Whole_Data = ParTree.Data.Data > > > + else: > > > + Data_Size = len(Whole_Data) > > > + # Parser all the data to collect all the Section recorded in Ffs. > > > + while Rel_Offset < Data_Size: > > > + # Create a SectionNode and set it as the SectionTree's > Data > > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:]) > > > + Section_Tree = BIOSTREE(Section_Info.Name) > > > + Section_Tree.type = SECTION_TREE > > > + Section_Info.Data = > > > Whole_Data[Rel_Offset+Section_Info.HeaderLength: > > > Rel_Offset+Section_Info.Size] > > > + Section_Info.DOffset = Section_Offset + > > > Section_Info.HeaderLength + Rel_Whole_Offset > > > + Section_Info.HOffset = Section_Offset + > Rel_Whole_Offset > > > + Section_Info.ROffset = Rel_Offset > > > + if Section_Info.Header.Type == 0: > > > + break > > > + # The final Section in Ffs does not need to add padding, > else > > > must be 4-bytes align with Ffs start offset > > > + Pad_Size = 0 > > > + if > > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != > > Data_Size): > > > + Pad_Size = GetPadSize(Section_Info.Size, 4) > > > + Section_Info.PadData = Pad_Size * b'\x00' > > > + if Section_Info.Header.Type == 0x02: > > > + Section_Info.DOffset = Section_Offset + > > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset > > > + Section_Info.Data = > > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: > > > Rel_Offset+Section_Info.Size] > > > + # If Section is Version or UI type, it saves the version and > > UI > > > info of its parent Ffs. > > > + if Section_Info.Header.Type == 0x14: > > > + ParTree.Data.Version = > > > Section_Info.ExtHeader.GetVersionString() > > > + if Section_Info.Header.Type == 0x15: > > > + ParTree.Data.UiName = > > > Section_Info.ExtHeader.GetUiString() > > > + Section_Offset += Section_Info.Size + Pad_Size > > > + Rel_Offset += Section_Info.Size + Pad_Size > > > + Section_Tree.Data = Section_Info > > > + ParTree.insertChild(Section_Tree) > > > + > > > +class FvProduct(BinaryProduct): > > > + ## ParserFv / GetFfs > > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: > > > int=0) -> None: > > > + Ffs_Offset = 0 > > > + Rel_Offset = 0 > > > + # Get the Data from parent tree, if do not have the tree then > get > > it > > > from the whole_data. > > > + if ParTree.Data != None: > > > + Data_Size = len(ParTree.Data.Data) > > > + Ffs_Offset = ParTree.Data.DOffset > > > + Whole_Data = ParTree.Data.Data > > > + else: > > > + Data_Size = len(Whole_Data) > > > + # Parser all the data to collect all the Ffs recorded in Fv. > > > + while Rel_Offset < Data_Size: > > > + # Create a FfsNode and set it as the FFsTree's Data > > > + if Data_Size - Rel_Offset < 24: > > > + Ffs_Tree = BIOSTREE('Free_Space') > > > + Ffs_Tree.type = FFS_FREE_SPACE > > > + Ffs_Tree.Data = > > > FreeSpaceNode(Whole_Data[Rel_Offset:]) > > > + Ffs_Tree.Data.HOffset = Ffs_Offset + > Rel_Whole_Offset > > > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset > > > + ParTree.Data.Free_Space = Data_Size - Rel_Offset > > > + ParTree.insertChild(Ffs_Tree) > > > + Rel_Offset = Data_Size > > > + else: > > > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:]) > > > + Ffs_Tree = BIOSTREE(Ffs_Info.Name) > > > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset > > > + Ffs_Info.DOffset = Ffs_Offset + > > > Ffs_Info.Header.HeaderLength + Rel_Whole_Offset > > > + Ffs_Info.ROffset = Rel_Offset > > > + if Ffs_Info.Name == PADVECTOR: > > > + Ffs_Tree.type = FFS_PAD > > > + Ffs_Info.Data = > > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > > > Rel_Offset+Ffs_Info.Size] > > > + Ffs_Info.Size = len(Ffs_Info.Data) + > > > Ffs_Info.Header.HeaderLength > > > + # if current Ffs is the final ffs of Fv and full of > > b'\xff', > > > define it with Free_Space > > > + if > struct2stream(Ffs_Info.Header).replace(b'\xff', > > b'') > > > == b'': > > > + Ffs_Tree.type = FFS_FREE_SPACE > > > + Ffs_Info.Data = Whole_Data[Rel_Offset:] > > > + Ffs_Info.Size = len(Ffs_Info.Data) > > > + ParTree.Data.Free_Space = Ffs_Info.Size > > > + else: > > > + Ffs_Tree.type = FFS_TREE > > > + Ffs_Info.Data = > > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: > > > Rel_Offset+Ffs_Info.Size] > > > + # The final Ffs in Fv does not need to add padding, > else > > > must be 8-bytes align with Fv start offset > > > + Pad_Size = 0 > > > + if Ffs_Tree.type != FFS_FREE_SPACE and > > > (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != > > Data_Size): > > > + Pad_Size = GetPadSize(Ffs_Info.Size, 8) > > > + Ffs_Info.PadData = Pad_Size * b'\xff' > > > + Ffs_Offset += Ffs_Info.Size + Pad_Size > > > + Rel_Offset += Ffs_Info.Size + Pad_Size > > > + Ffs_Tree.Data = Ffs_Info > > > + ParTree.insertChild(Ffs_Tree) > > > + > > > +class FdProduct(BinaryProduct): > > > + type = [ROOT_FV_TREE, ROOT_TREE] > > > + > > > + ## Create DataTree with first level /fv Info, then parser each Fv. > > > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: > > int=0) -> > > > None: > > > + # Get all Fv image in Fd with offset and length > > > + Fd_Struct = self.GetFvFromFd(whole_data) > > > + data_size = len(whole_data) > > > + Binary_count = 0 > > > + global Fv_count > > > + # If the first Fv image is the Binary Fv, add it into the tree. > > > + if Fd_Struct[0][1] != 0: > > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > > > + Binary_node.type = BINARY_DATA > > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]] > > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > > + Binary_node.Data.HOffset = 0 + offset > > > + WholeFvTree.insertChild(Binary_node) > > > + Binary_count += 1 > > > + # Add the first collected Fv image into the tree. > > > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count)) > > > + Cur_node.type = Fd_Struct[0][0] > > > + Cur_node.Data = FvNode(Fv_count, > > > whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]]) > > > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset > > > + Cur_node.Data.DOffset = > > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > > > + Cur_node.Data.Data = > > > > > > whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct > > > [0][1]+Cur_node.Data.Size] > > > + WholeFvTree.insertChild(Cur_node) > > > + Fv_count += 1 > > > + Fv_num = len(Fd_Struct) > > > + # Add all the collected Fv image and the Binary Fv image > between > > > them into the tree. > > > + for i in range(Fv_num-1): > > > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]: > > > + Binary_node = BIOSTREE('BINARY'+ > str(Binary_count)) > > > + Binary_node.type = BINARY_DATA > > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > > + Binary_node.Data.Data = > > > whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]] > > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > > + Binary_node.Data.HOffset = > > > Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset > > > + WholeFvTree.insertChild(Binary_node) > > > + Binary_count += 1 > > > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count)) > > > + Cur_node.type = Fd_Struct[i+1][0] > > > + Cur_node.Data = FvNode(Fv_count, > > > whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]]) > > > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset > > > + Cur_node.Data.DOffset = > > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength > > > + Cur_node.Data.Data = > > > > > > whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru > > > ct[i+1][1]+Cur_node.Data.Size] > > > + WholeFvTree.insertChild(Cur_node) > > > + Fv_count += 1 > > > + # If the final Fv image is the Binary Fv, add it into the tree > > > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size: > > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count)) > > > + Binary_node.type = BINARY_DATA > > > + Binary_node.Data = BinaryNode(str(Binary_count)) > > > + Binary_node.Data.Data = > > > whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:] > > > + Binary_node.Data.Size = len(Binary_node.Data.Data) > > > + Binary_node.Data.HOffset = > > > Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset > > > + WholeFvTree.insertChild(Binary_node) > > > + Binary_count += 1 > > > + > > > + ## Get the first level Fv from Fd file. > > > + def GetFvFromFd(self, whole_data: bytes=b'') -> list: > > > + Fd_Struct = [] > > > + data_size = len(whole_data) > > > + cur_index = 0 > > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV > > > image offset and length. > > > + while cur_index < data_size: > > > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in > > > whole_data[cur_index:]: > > > + target_index = > > > > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) > > + > > > cur_index > > > + if whole_data[target_index+24:target_index+28] == > > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > > ZEROVECTOR_BYTE: > > > + Fd_Struct.append([FV_TREE, target_index - 16, > > > unpack("Q", whole_data[target_index+16:target_index+24])]) > > > + cur_index = Fd_Struct[-1][1] + > Fd_Struct[-1][2][0] > > > + else: > > > + cur_index = target_index + 16 > > > + else: > > > + cur_index = data_size > > > + cur_index = 0 > > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV > > > image offset and length. > > > + while cur_index < data_size: > > > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in > > > whole_data[cur_index:]: > > > + target_index = > > > > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) > > + > > > cur_index > > > + if whole_data[target_index+24:target_index+28] == > > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > > ZEROVECTOR_BYTE: > > > + Fd_Struct.append([FV_TREE, target_index - 16, > > > unpack("Q", whole_data[target_index+16:target_index+24])]) > > > + cur_index = Fd_Struct[-1][1] + > Fd_Struct[-1][2][0] > > > + else: > > > + cur_index = target_index + 16 > > > + else: > > > + cur_index = data_size > > > + cur_index = 0 > > > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image > > > offset and length. > > > + while cur_index < data_size: > > > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in > > > whole_data[cur_index:]: > > > + target_index = > > > whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + > > > cur_index > > > + if whole_data[target_index+24:target_index+28] == > > > FVH_SIGNATURE and whole_data[target_index-16:target_index] == > > > ZEROVECTOR_BYTE: > > > + Fd_Struct.append([DATA_FV_TREE, > target_index - > > > 16, unpack("Q", whole_data[target_index+16:target_index+24])]) > > > + cur_index = Fd_Struct[-1][1] + > Fd_Struct[-1][2][0] > > > + else: > > > + cur_index = target_index + 16 > > > + else: > > > + cur_index = data_size > > > + # Sort all the collect Fv image with offset. > > > + Fd_Struct.sort(key=lambda x:x[1]) > > > + tmp_struct = copy.deepcopy(Fd_Struct) > > > + tmp_index = 0 > > > + Fv_num = len(Fd_Struct) > > > + # Remove the Fv image included in another Fv image. > > > + for i in range(1,Fv_num): > > > + if tmp_struct[i][1]+tmp_struct[i][2][0] < > > > tmp_struct[i-1][1]+tmp_struct[i-1][2][0]: > > > + Fd_Struct.remove(Fd_Struct[i-tmp_index]) > > > + tmp_index += 1 > > > + return Fd_Struct > > > + > > > +class ParserEntry(): > > > + FactoryTable:dict = { > > > + SECTION_TREE: SectionFactory, > > > + ROOT_SECTION_TREE: FfsFactory, > > > + FFS_TREE: FfsFactory, > > > + ROOT_FFS_TREE: FvFactory, > > > + FV_TREE: FvFactory, > > > + SEC_FV_TREE: FvFactory, > > > + ROOT_FV_TREE: FdFactory, > > > + ROOT_TREE: FdFactory, > > > + } > > > + > > > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory: > > > + if Tree_type in self.FactoryTable: > > > + return self.FactoryTable[Tree_type] > > > + > > > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: > > > bytes, Offset: int) -> None: > > > + New_Product = TargetFactory.Create_Product() > > > + New_Product.ParserData(Tree, Data, Offset) > > > + > > > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None: > > > + TargetFactory = self.GetTargetFactory(Tree.type) > > > + if TargetFactory: > > > + self.Generate_Product(TargetFactory, Tree, Data, Offset) > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py > > > b/BaseTools/Source/Python/FMMT/core/BiosTree.py > > > new file mode 100644 > > > index 000000000000..0b6252ecc1bb > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py > > > @@ -0,0 +1,198 @@ > > > +## @file > > > +# This file is used to define the Bios layout tree structure and related > > > operations. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +import collections > > > +from PI.Common import * > > > + > > > +ROOT_TREE = 'ROOT' > > > +ROOT_FV_TREE = 'ROOT_FV_TREE' > > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE' > > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE' > > > + > > > +FV_TREE = 'FV' > > > +DATA_FV_TREE = 'DATA_FV' > > > +FFS_TREE = 'FFS' > > > +FFS_PAD = 'FFS_PAD' > > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE' > > > +SECTION_TREE = 'SECTION' > > > +SEC_FV_TREE = 'SEC_FV_IMAGE' > > > +BINARY_DATA = 'BINARY' > > > + > > > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, > > > ROOT_SECTION_TREE] > > > +FvType = [FV_TREE, SEC_FV_TREE] > > > +FfsType = FFS_TREE > > > +SecType = SECTION_TREE > > > + > > > +class BIOSTREE: > > > + def __init__(self, NodeName: str) -> None: > > > + self.key = NodeName > > > + self.type = None > > > + self.Data = None > > > + self.Child = [] > > > + self.Findlist = [] > > > + self.Parent = None > > > + self.NextRel = None > > > + self.LastRel = None > > > + > > > + def HasChild(self) -> bool: > > > + if self.Child == []: > > > + return False > > > + else: > > > + return True > > > + > > > + def isFinalChild(self) -> bool: > > > + ParTree = self.Parent > > > + if ParTree: > > > + if ParTree.Child[-1] == self: > > > + return True > > > + return False > > > + > > > + # FvTree.insertChild() > > > + def insertChild(self, newNode, pos: int=None) -> None: > > > + if len(self.Child) == 0: > > > + self.Child.append(newNode) > > > + else: > > > + if not pos: > > > + LastTree = self.Child[-1] > > > + self.Child.append(newNode) > > > + LastTree.NextRel = newNode > > > + newNode.LastRel = LastTree > > > + else: > > > + newNode.NextRel = self.Child[pos-1].NextRel > > > + newNode.LastRel = self.Child[pos].LastRel > > > + self.Child[pos-1].NextRel = newNode > > > + self.Child[pos].LastRel = newNode > > > + self.Child.insert(pos, newNode) > > > + newNode.Parent = self > > > + > > > + # lastNode.insertRel(newNode) > > > + def insertRel(self, newNode) -> None: > > > + if self.Parent: > > > + parentTree = self.Parent > > > + new_index = parentTree.Child.index(self) + 1 > > > + parentTree.Child.insert(new_index, newNode) > > > + self.NextRel = newNode > > > + newNode.LastRel = self > > > + > > > + def deleteNode(self, deletekey: str) -> None: > > > + FindStatus, DeleteTree = self.FindNode(deletekey) > > > + if FindStatus: > > > + parentTree = DeleteTree.Parent > > > + lastTree = DeleteTree.LastRel > > > + nextTree = DeleteTree.NextRel > > > + if parentTree: > > > + index = parentTree.Child.index(DeleteTree) > > > + del parentTree.Child[index] > > > + if lastTree and nextTree: > > > + lastTree.NextRel = nextTree > > > + nextTree.LastRel = lastTree > > > + elif lastTree: > > > + lastTree.NextRel = None > > > + elif nextTree: > > > + nextTree.LastRel = None > > > + return DeleteTree > > > + else: > > > + print('Could not find the target tree') > > > + return None > > > + > > > + def FindNode(self, key: str, Findlist: list) -> None: > > > + if self.key == key or (self.Data and self.Data.Name == key) or > > > (self.type == FFS_TREE and self.Data.UiName == key): > > > + Findlist.append(self) > > > + else: > > > + for item in self.Child: > > > + item.FindNode(key, Findlist) > > > + > > > + def GetTreePath(self): > > > + BiosTreePath = [self] > > > + while self.Parent: > > > + BiosTreePath.insert(0, self.Parent) > > > + self = self.Parent > > > + return BiosTreePath > > > + > > > + def parserTree(self, TargetDict: dict=None, Info: list=None, space: > > int=0, > > > ParFvId="") -> None: > > > + Key = list(TargetDict.keys())[0] > > > + if TargetDict[Key]["Type"] in RootType: > > > + Info.append("Image File: {}".format(Key)) > > > + Info.append("FilesNum: > > > {}".format(TargetDict.get(Key).get('FilesNum'))) > > > + Info.append("\n") > > > + elif TargetDict[Key]["Type"] in FvType: > > > + space += 2 > > > + if TargetDict[Key]["Type"] == SEC_FV_TREE: > > > + Info.append("{}Child FV named {} of > {}".format(space*" ", > > > Key, ParFvId)) > > > + space += 2 > > > + else: > > > + Info.append("FvId: {}".format(Key)) > > > + ParFvId = Key > > > + Info.append("{}FvNameGuid: {}".format(space*" ", > > > TargetDict.get(Key).get('FvNameGuid'))) > > > + Info.append("{}Attributes: {}".format(space*" ", > > > TargetDict.get(Key).get('Attributes'))) > > > + Info.append("{}Total Volume Size: {}".format(space*" ", > > > TargetDict.get(Key).get('Size'))) > > > + Info.append("{}Free Volume Size: {}".format(space*" ", > > > TargetDict.get(Key).get('FreeSize'))) > > > + Info.append("{}Volume Offset: {}".format(space*" ", > > > TargetDict.get(Key).get('Offset'))) > > > + Info.append("{}FilesNum: {}".format(space*" ", > > > TargetDict.get(Key).get('FilesNum'))) > > > + elif TargetDict[Key]["Type"] in FfsType: > > > + space += 2 > > > + if TargetDict.get(Key).get('UiName') != "b''": > > > + Info.append("{}File: {} / {}".format(space*" ", Key, > > > TargetDict.get(Key).get('UiName'))) > > > + else: > > > + Info.append("{}File: {}".format(space*" ", Key)) > > > + if "Files" in list(TargetDict[Key].keys()): > > > + for item in TargetDict[Key]["Files"]: > > > + self.parserTree(item, Info, space, ParFvId) > > > + > > > + def ExportTree(self,TreeInfo: dict=None) -> dict: > > > + if TreeInfo is None: > > > + TreeInfo =collections.OrderedDict() > > > + > > > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or > > > self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE: > > > + key = str(self.key) > > > + TreeInfo[self.key] = collections.OrderedDict() > > > + TreeInfo[self.key]["Name"] = key > > > + TreeInfo[self.key]["Type"] = self.type > > > + TreeInfo[self.key]["FilesNum"] = len(self.Child) > > > + elif self.type == FV_TREE or self.type == SEC_FV_TREE: > > > + key = str(self.Data.FvId) > > > + TreeInfo[key] = collections.OrderedDict() > > > + TreeInfo[key]["Name"] = key > > > + if self.Data.FvId != self.Data.Name: > > > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name) > > > + TreeInfo[key]["Type"] = self.type > > > + TreeInfo[key]["Attributes"] = > > hex(self.Data.Header.Attributes) > > > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength) > > > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space) > > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > > + elif self.type == FFS_TREE: > > > + key = str(self.Data.Name) > > > + TreeInfo[key] = collections.OrderedDict() > > > + TreeInfo[key]["Name"] = key > > > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName) > > > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version) > > > + TreeInfo[key]["Type"] = self.type > > > + TreeInfo[key]["Size"] = hex(self.Data.Size) > > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > > + elif self.type == SECTION_TREE and self.Data.Type == 0x02: > > > + key = str(self.Data.Name) > > > + TreeInfo[key] = collections.OrderedDict() > > > + TreeInfo[key]["Name"] = key > > > + TreeInfo[key]["Type"] = self.type > > > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + > > > self.Data.HeaderLength) > > > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size) > > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > > + elif self is not None: > > > + key = str(self.Data.Name) > > > + TreeInfo[key] = collections.OrderedDict() > > > + TreeInfo[key]["Name"] = key > > > + TreeInfo[key]["Type"] = self.type > > > + TreeInfo[key]["Size"] = hex(self.Data.Size) > > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset) > > > + TreeInfo[key]["FilesNum"] = len(self.Child) > > > + > > > + for item in self.Child: > > > + TreeInfo[key].setdefault('Files',[]).append( > > item.ExportTree()) > > > + > > > + return TreeInfo > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > > b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > > new file mode 100644 > > > index 000000000000..cfb711eea5a2 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py > > > @@ -0,0 +1,191 @@ > > > +## @file > > > +# This file is used to define the BIOS Tree Node. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from PI.FvHeader import * > > > +from PI.FfsFileHeader import * > > > +from PI.SectionHeader import * > > > +from PI.Common import * > > > +import uuid > > > + > > > +SectionHeaderType = { > > > + 0x01:'EFI_COMPRESSION_SECTION', > > > + 0x02:'EFI_GUID_DEFINED_SECTION', > > > + 0x03:'EFI_SECTION_DISPOSABLE', > > > + 0x10:'EFI_SECTION_PE32', > > > + 0x11:'EFI_SECTION_PIC', > > > + 0x12:'EFI_SECTION_TE', > > > + 0x13:'EFI_SECTION_DXE_DEPEX', > > > + 0x14:'EFI_SECTION_VERSION', > > > + 0x15:'EFI_SECTION_USER_INTERFACE', > > > + 0x16:'EFI_SECTION_COMPATIBILITY16', > > > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', > > > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION', > > > + 0x19:'EFI_SECTION_RAW', > > > + 0x1B:'EFI_SECTION_PEI_DEPEX', > > > + 0x1C:'EFI_SECTION_MM_DEPEX' > > > +} > > > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18] > > > + > > > +class BinaryNode: > > > + def __init__(self, name: str) -> None: > > > + self.Size = 0 > > > + self.Name = "BINARY" + str(name) > > > + self.HOffset = 0 > > > + self.Data = b'' > > > + > > > +class FvNode: > > > + def __init__(self, name, buffer: bytes) -> None: > > > + self.Header = > > > EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer) > > > + Map_num = (self.Header.HeaderLength - 56)//8 > > > + self.Header = > > > Refine_FV_Header(Map_num).from_buffer_copy(buffer) > > > + self.FvId = "FV" + str(name) > > > + self.Name = "FV" + str(name) > > > + if self.Header.ExtHeaderOffset: > > > + self.ExtHeader = > > > > > > EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Heade > > r > > > .ExtHeaderOffset:]) > > > + self.Name = > > > uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName)) > > > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20 > > > + if self.ExtHeader.ExtHeaderSize != 20: > > > + self.ExtEntryExist = 1 > > > + self.ExtEntry = > > > > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry > > > Offset:]) > > > + self.ExtTypeExist = 1 > > > + if self.ExtEntry.ExtEntryType == 0x01: > > > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16 > > > + self.ExtEntry = > > > > > > Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[ > > s > > > elf.ExtEntryOffset:]) > > > + elif self.ExtEntry.ExtEntryType == 0x02: > > > + nums = self.ExtEntry.ExtEntrySize - 20 > > > + self.ExtEntry = > > > > > > Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer > > [ > > > self.ExtEntryOffset:]) > > > + elif self.ExtEntry.ExtEntryType == 0x03: > > > + self.ExtEntry = > > > > > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b > > > uffer[self.ExtEntryOffset:]) > > > + else: > > > + self.ExtTypeExist = 0 > > > + else: > > > + self.ExtEntryExist = 0 > > > + self.Size = self.Header.FvLength > > > + self.HeaderLength = self.Header.HeaderLength > > > + self.HOffset = 0 > > > + self.DOffset = 0 > > > + self.ROffset = 0 > > > + self.Data = b'' > > > + if self.Header.Signature != 1213613663: > > > + print('Invalid! Fv Header Signature {} is not > > > "_FVH".'.format(self.Header.Signature)) > > > + with open(str(self.Name)+'.fd', "wb") as f: > > > + f.write(struct2stream(self.Header)) > > > + assert False > > > + self.PadData = b'' > > > + self.Free_Space = 0 > > > + self.ModCheckSum() > > > + > > > + def ModCheckSum(self) -> None: > > > + # Fv Header Sums to 0. > > > + Header = struct2stream(self.Header)[::-1] > > > + Size = self.HeaderLength // 2 > > > + Sum = 0 > > > + for i in range(Size): > > > + Sum += int(Header[i*2: i*2 + 2].hex(), 16) > > > + if Sum & 0xffff: > > > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - > > > self.Header.Checksum)[-4:], 16)), 16) > > > + > > > + def ModFvExt(self) -> None: > > > + # If used space changes and self.ExtEntry.UsedSize exists, > > > self.ExtEntry.UsedSize need to be changed. > > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and > > > self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03: > > > + self.ExtEntry.UsedSize = self.Header.FvLength - > > > self.Free_Space > > > + > > > + def ModFvSize(self) -> None: > > > + # If Fv Size changed, self.Header.FvLength and > > > self.Header.BlockMap[i].NumBlocks need to be changed. > > > + BlockMapNum = len(self.Header.BlockMap) > > > + for i in range(BlockMapNum): > > > + if self.Header.BlockMap[i].Length: > > > + self.Header.BlockMap[i].NumBlocks = > > > self.Header.FvLength // self.Header.BlockMap[i].Length > > > + > > > + def ModExtHeaderData(self) -> None: > > > + if self.Header.ExtHeaderOffset: > > > + ExtHeaderData = struct2stream(self.ExtHeader) > > > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset - > > > self.HeaderLength > > > + self.Data = self.Data[:ExtHeaderDataOffset] + > ExtHeaderData > > > + self.Data[ExtHeaderDataOffset+20:] > > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist: > > > + ExtHeaderEntryData = struct2stream(self.ExtEntry) > > > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset > + > > > 20 - self.HeaderLength > > > + self.Data = self.Data[:ExtHeaderEntryDataOffset] + > > > ExtHeaderEntryData + > > > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):] > > > + > > > +class FfsNode: > > > + def __init__(self, buffer: bytes) -> None: > > > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer) > > > + # self.Attributes = unpack("<B", buffer[21:22])[0] > > > + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes != > > 0xff > > > and self.Header.Attributes & 0x01 == 1: > > > + print('Error Ffs Header! Ffs Header Size and Attributes is > > not > > > matched!') > > > + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes & > > > 0x01 == 1: > > > + self.Header = > > > EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer) > > > + self.Name = > > > uuid.UUID(bytes_le=struct2stream(self.Header.Name)) > > > + self.UiName = b'' > > > + self.Version = b'' > > > + self.Size = self.Header.FFS_FILE_SIZE > > > + self.HeaderLength = self.Header.HeaderLength > > > + self.HOffset = 0 > > > + self.DOffset = 0 > > > + self.ROffset = 0 > > > + self.Data = b'' > > > + self.PadData = b'' > > > + > > > + def ModCheckSum(self) -> None: > > > + HeaderData = struct2stream(self.Header) > > > + HeaderSum = 0 > > > + for item in HeaderData: > > > + HeaderSum += item > > > + HeaderSum -= self.Header.State > > > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File > > > + if HeaderSum & 0xff: > > > + Header = self.Header.IntegrityCheck.Checksum.Header + > > > 0x100 - int(hex(HeaderSum)[-2:], 16) > > > + self.Header.IntegrityCheck.Checksum.Header = > > > int(hex(Header)[-2:], 16) > > > + > > > +class SectionNode: > > > + def __init__(self, buffer: bytes) -> None: > > > + if buffer[0:3] != b'\xff\xff\xff': > > > + self.Header = > > > EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer) > > > + else: > > > + self.Header = > > > EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer) > > > + if self.Header.Type in SectionHeaderType: > > > + self.Name = SectionHeaderType[self.Header.Type] > > > + elif self.Header.Type == 0: > > > + self.Name = "EFI_SECTION_RAW" > > > + else: > > > + self.Name = "SECTION" > > > + if self.Header.Type in HeaderType: > > > + self.ExtHeader = self.GetExtHeader(self.Header.Type, > > > buffer[self.Header.Common_Header_Size():], > > > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size())) > > > + self.HeaderLength = self.Header.Common_Header_Size() > + > > > self.ExtHeader.ExtHeaderSize() > > > + else: > > > + self.ExtHeader = None > > > + self.HeaderLength = self.Header.Common_Header_Size() > > > + self.Size = self.Header.SECTION_SIZE > > > + self.Type = self.Header.Type > > > + self.HOffset = 0 > > > + self.DOffset = 0 > > > + self.ROffset = 0 > > > + self.Data = b'' > > > + self.OriData = b'' > > > + self.OriHeader = b'' > > > + self.PadData = b'' > > > + > > > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> > > None: > > > + if Type == 0x01: > > > + return > > > EFI_COMPRESSION_SECTION.from_buffer_copy(buffer) > > > + elif Type == 0x02: > > > + return > > > EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer) > > > + elif Type == 0x14: > > > + return Get_VERSION_Header((nums - > > > 2)//2).from_buffer_copy(buffer) > > > + elif Type == 0x15: > > > + return > > > Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer) > > > + elif Type == 0x18: > > > + return > > > EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer) > > > + > > > +class FreeSpaceNode: > > > + def __init__(self, buffer: bytes) -> None: > > > + self.Name = 'Free_Space' > > > + self.Data = buffer > > > + self.Size = len(buffer) > > > + self.HOffset = 0 > > > + self.DOffset = 0 > > > + self.ROffset = 0 > > > + self.PadData = b'' > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > > b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > > new file mode 100644 > > > index 000000000000..a0432c4093cf > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py > > > @@ -0,0 +1,140 @@ > > > +## @file > > > +# This file is used to define the functions to operate bios binary file. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from core.FMMTParser import * > > > +from core.FvHandler import * > > > +from utils.FvLayoutPrint import * > > > + > > > +global Fv_count > > > +Fv_count = 0 > > > + > > > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', > > 'ROOT_FFS_TREE', > > > 'ROOT_SECTION_TREE' > > > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, > > outputfile: > > > str=None) -> None: > > > + # 1. Data Prepare > > > + with open(inputfile, "rb") as f: > > > + whole_data = f.read() > > > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE) > > > + # 2. DataTree Create > > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, > whole_data) > > > + # 3. Log Output > > > + InfoDict = FmmtParser.WholeFvTree.ExportTree() > > > + FmmtParser.WholeFvTree.parserTree(InfoDict, > FmmtParser.BinaryInfo) > > > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo) > > > + if logfile: > > > + GetFormatter(logfile.lower()).dump(InfoDict, > > > > > > FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile > > ), > > > ".{}".format(logfile.lower()))) > > > + # 4. Data Encapsultion > > > + if outputfile: > > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > > + with open(outputfile, "wb") as f: > > > + f.write(FmmtParser.FinalData) > > > + > > > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, > > Fv_name: > > > str=None) -> None: > > > + # 1. Data Prepare > > > + with open(inputfile, "rb") as f: > > > + whole_data = f.read() > > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > > + # 2. DataTree Create > > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, > whole_data) > > > + # 3. Data Modify > > > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, > > > FmmtParser.WholeFvTree.Findlist) > > > + # Choose the Specfic DeleteFfs with Fv info > > > + if Fv_name: > > > + for item in FmmtParser.WholeFvTree.Findlist: > > > + if item.Parent.key != Fv_name and > > > item.Parent.Data.Name != Fv_name: > > > + FmmtParser.WholeFvTree.Findlist.remove(item) > > > + if FmmtParser.WholeFvTree.Findlist != []: > > > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: > > > + FfsMod = FvHandler(None, Delete_Ffs) > > > + Status = FfsMod.DeleteFfs() > > > + else: > > > + print('Target Ffs not found!!!') > > > + # 4. Data Encapsultion > > > + if Status: > > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > > + with open(outputfile, "wb") as f: > > > + f.write(FmmtParser.FinalData) > > > + > > > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: > > str) -> > > > None: > > > + # 1. Data Prepare > > > + with open(inputfile, "rb") as f: > > > + whole_data = f.read() > > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > > + # 2. DataTree Create > > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, > whole_data) > > > + # Get Target Fv and Target Ffs_Pad > > > + FmmtParser.WholeFvTree.FindNode(Fv_name, > > > FmmtParser.WholeFvTree.Findlist) > > > + # Create new ffs Tree > > > + with open(newffsfile, "rb") as f: > > > + new_ffs_data = f.read() > > > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE) > > > + Status = False > > > + # 3. Data Modify > > > + if FmmtParser.WholeFvTree.Findlist: > > > + for TargetFv in FmmtParser.WholeFvTree.Findlist: > > > + TargetFfsPad = TargetFv.Child[-1] > > > + if TargetFfsPad.type == FFS_FREE_SPACE: > > > + > > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > > > new_ffs_data, TargetFfsPad.Data.HOffset) > > > + else: > > > + > > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, > > > new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size) > > > + FfsMod = > FvHandler(NewFmmtParser.WholeFvTree.Child[0], > > > TargetFfsPad) > > > + Status = FfsMod.AddFfs() > > > + else: > > > + print('Target Fv not found!!!') > > > + # 4. Data Encapsultion > > > + if Status: > > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > > + with open(outputfile, "wb") as f: > > > + f.write(FmmtParser.FinalData) > > > + > > > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, > > outputfile: str, > > > Fv_name: str=None) -> None: > > > + # 1. Data Prepare > > > + with open(inputfile, "rb") as f: > > > + whole_data = f.read() > > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > > + # 2. DataTree Create > > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, > whole_data) > > > + with open(newffsfile, "rb") as f: > > > + new_ffs_data = f.read() > > > + newFmmtParser = FMMTParser(newffsfile, FV_TREE) > > > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, > > > new_ffs_data) > > > + Status = False > > > + # 3. Data Modify > > > + new_ffs = newFmmtParser.WholeFvTree.Child[0] > > > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff' > > > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > > > FmmtParser.WholeFvTree.Findlist) > > > + if Fv_name: > > > + for item in FmmtParser.WholeFvTree.Findlist: > > > + if item.Parent.key != Fv_name and > > > item.Parent.Data.Name != Fv_name: > > > + FmmtParser.WholeFvTree.Findlist.remove(item) > > > + if FmmtParser.WholeFvTree.Findlist != []: > > > + for TargetFfs in FmmtParser.WholeFvTree.Findlist: > > > + FfsMod = > FvHandler(newFmmtParser.WholeFvTree.Child[0], > > > TargetFfs) > > > + Status = FfsMod.ReplaceFfs() > > > + else: > > > + print('Target Ffs not found!!!') > > > + # 4. Data Encapsultion > > > + if Status: > > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) > > > + with open(outputfile, "wb") as f: > > > + f.write(FmmtParser.FinalData) > > > + > > > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None: > > > + with open(inputfile, "rb") as f: > > > + whole_data = f.read() > > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE) > > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, > whole_data) > > > + FmmtParser.WholeFvTree.FindNode(Ffs_name, > > > FmmtParser.WholeFvTree.Findlist) > > > + if FmmtParser.WholeFvTree.Findlist != []: > > > + TargetNode = FmmtParser.WholeFvTree.Findlist[0] > > > + TargetFv = TargetNode.Parent > > > + if TargetFv.Data.Header.Attributes & > EFI_FVB2_ERASE_POLARITY: > > > + TargetNode.Data.Header.State = c_uint8( > > > + ~TargetNode.Data.Header.State) > > > + FinalData = struct2stream(TargetNode.Data.Header) + > > > TargetNode.Data.Data > > > + with open(outputfile, "wb") as f: > > > + f.write(FinalData) > > > + else: > > > + print('Target Ffs not found!!!') > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > > b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > > new file mode 100644 > > > index 000000000000..6e54b860a9c9 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py > > > @@ -0,0 +1,86 @@ > > > +## @file > > > +# This file is used to define the interface of Bios Parser. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +from PI.Common import * > > > +from core.BinaryFactoryProduct import ParserEntry > > > +from core.BiosTreeNode import * > > > +from core.BiosTree import * > > > +from core.GuidTools import * > > > + > > > +class FMMTParser: > > > + def __init__(self, name: str, TYPE: str) -> None: > > > + self.WholeFvTree = BIOSTREE(name) > > > + self.WholeFvTree.type = TYPE > > > + self.FinalData = b'' > > > + self.BinaryInfo = [] > > > + > > > + ## Parser the nodes in WholeTree. > > > + def ParserFromRoot(self, WholeFvTree=None, whole_data: > bytes=b'', > > > Reloffset: int=0) -> None: > > > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == > > > ROOT_FV_TREE: > > > + ParserEntry().DataParser(self.WholeFvTree, whole_data, > > > Reloffset) > > > + else: > > > + ParserEntry().DataParser(WholeFvTree, whole_data, > > > Reloffset) > > > + for Child in WholeFvTree.Child: > > > + self.ParserFromRoot(Child, "") > > > + > > > + ## Encapuslation all the data in tree into self.FinalData > > > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None: > > > + # If current node is Root node, skip it. > > > + if rootTree.type == ROOT_TREE or rootTree.type == > > > ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == > > > ROOT_SECTION_TREE: > > > + print('Start at Root !') > > > + # If current node do not have Header, just add Data. > > > + elif rootTree.type == BINARY_DATA or rootTree.type == > > > FFS_FREE_SPACE: > > > + self.FinalData += rootTree.Data.Data > > > + rootTree.Child = [] > > > + # If current node do not have Child and ExtHeader, just add its > > > Header and Data. > > > + elif rootTree.type == DATA_FV_TREE or rootTree.type == > FFS_PAD: > > > + self.FinalData += struct2stream(rootTree.Data.Header) + > > > rootTree.Data.Data + rootTree.Data.PadData > > > + if rootTree.isFinalChild(): > > > + ParTree = rootTree.Parent > > > + if ParTree.type != 'ROOT': > > > + self.FinalData += ParTree.Data.PadData > > > + rootTree.Child = [] > > > + # If current node is not Section node and may have Child and > > > ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data. > > > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or > > > rootTree.type == SEC_FV_TREE: > > > + if rootTree.HasChild(): > > > + self.FinalData += > struct2stream(rootTree.Data.Header) > > > + else: > > > + self.FinalData += > struct2stream(rootTree.Data.Header) + > > > rootTree.Data.Data + rootTree.Data.PadData > > > + if rootTree.isFinalChild(): > > > + ParTree = rootTree.Parent > > > + if ParTree.type != 'ROOT': > > > + self.FinalData += ParTree.Data.PadData > > > + # If current node is Section, need to consider its ExtHeader, > > Child > > > and Compressed Status. > > > + elif rootTree.type == SECTION_TREE: > > > + # Not compressed section > > > + if rootTree.Data.OriData == b'' or > (rootTree.Data.OriData != > > > b'' and CompressStatus): > > > + if rootTree.HasChild(): > > > + if rootTree.Data.ExtHeader: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) + > > > struct2stream(rootTree.Data.ExtHeader) > > > + else: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) > > > + else: > > > + Data = rootTree.Data.Data > > > + if rootTree.Data.ExtHeader: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) + > > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > > > + else: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > > > + if rootTree.isFinalChild(): > > > + ParTree = rootTree.Parent > > > + self.FinalData += ParTree.Data.PadData > > > + # If compressed section > > > + else: > > > + Data = rootTree.Data.OriData > > > + rootTree.Child = [] > > > + if rootTree.Data.ExtHeader: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) + > > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData > > > + else: > > > + self.FinalData += > > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData > > > + if rootTree.isFinalChild(): > > > + ParTree = rootTree.Parent > > > + self.FinalData += ParTree.Data.PadData > > > + for Child in rootTree.Child: > > > + self.Encapsulation(Child, CompressStatus) > > > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py > > > b/BaseTools/Source/Python/FMMT/core/FvHandler.py > > > new file mode 100644 > > > index 000000000000..f73f1fd65c07 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py > > > @@ -0,0 +1,521 @@ > > > +## @file > > > +# This file is used to the implementation of Bios layout handler. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +import os > > > +from core.BiosTree import * > > > +from core.GuidTools import GUIDTools > > > +from core.BiosTreeNode import * > > > +from PI.Common import * > > > + > > > +EFI_FVB2_ERASE_POLARITY = 0x00000800 > > > + > > > +def ChangeSize(TargetTree, size_delta: int=0) -> None: > > > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) > or > > > type(TargetTree.Data.Header) == > > type(EFI_COMMON_SECTION_HEADER2()): > > > + TargetTree.Data.Size -= size_delta > > > + TargetTree.Data.Header.ExtendedSize -= size_delta > > > + elif TargetTree.type == SECTION_TREE and > TargetTree.Data.OriData: > > > + OriSize = TargetTree.Data.Header.SECTION_SIZE > > > + OriSize -= size_delta > > > + TargetTree.Data.Header.Size[0] = OriSize % (16**2) > > > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2) > > > + TargetTree.Data.Header.Size[2] = OriSize // (16**4) > > > + else: > > > + TargetTree.Data.Size -= size_delta > > > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % > (16**2) > > > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % > (16**4) > > > //(16**2) > > > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // > (16**4) > > > + > > > +def ModifyFfsType(TargetFfs) -> None: > > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and > > > TargetFfs.Data.Size > 0xFFFFFF: > > > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8 > > > + New_Header = EFI_FFS_FILE_HEADER2() > > > + New_Header.Name = TargetFfs.Data.Header.Name > > > + New_Header.IntegrityCheck = > > > TargetFfs.Data.Header.IntegrityCheck > > > + New_Header.Type = TargetFfs.Data.Header.Type > > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > > > + New_Header.Size = 0 > > > + New_Header.State = TargetFfs.Data.Header.State > > > + New_Header.ExtendedSize = ExtendSize > > > + TargetFfs.Data.Header = New_Header > > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > > > + TargetFfs.Data.HeaderLength = > > > TargetFfs.Data.Header.HeaderLength > > > + TargetFfs.Data.ModCheckSum() > > > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) > and > > > TargetFfs.Data.Size <= 0xFFFFFF: > > > + New_Header = EFI_FFS_FILE_HEADER() > > > + New_Header.Name = TargetFfs.Data.Header.Name > > > + New_Header.IntegrityCheck = > > > TargetFfs.Data.Header.IntegrityCheck > > > + New_Header.Type = TargetFfs.Data.Header.Type > > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes > > > + New_Header.Size = TargetFfs.Data.HeaderLength + > > > TargetFfs.Data.Size > > > + New_Header.State = TargetFfs.Data.Header.State > > > + TargetFfs.Data.Header = New_Header > > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE > > > + TargetFfs.Data.HeaderLength = > > > TargetFfs.Data.Header.HeaderLength > > > + TargetFfs.Data.ModCheckSum() > > > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) > == > > > EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE: > > > + NeedChange = True > > > + for item in TargetFfs.Parent.Child: > > > + if type(item.Data.Header) == > > > type(EFI_FFS_FILE_HEADER2()): > > > + NeedChange = False > > > + if NeedChange: > > > + TargetFfs.Parent.Data.Header.FileSystemGuid = > > > ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3") > > > + > > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()): > > > + TarParent = TargetFfs.Parent > > > + while TarParent: > > > + if TarParent.type == FV_TREE and > > > struct2stream(TarParent.Data.Header.FileSystemGuid) == > > > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE: > > > + TarParent.Data.Header.FileSystemGuid = > > > ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A") > > > + TarParent = TarParent.Parent > > > + > > > +class FvHandler: > > > + def __init__(self, NewFfs, TargetFfs) -> None: > > > + self.NewFfs = NewFfs > > > + self.TargetFfs = TargetFfs > > > + self.Status = False > > > + self.Remain_New_Free_Space = 0 > > > + > > > + ## Use for Compress the Section Data > > > + def CompressData(self, TargetTree) -> None: > > > + TreePath = TargetTree.GetTreePath() > > > + pos = len(TreePath) > > > + self.Status = True > > > + while pos: > > > + if self.Status: > > > + if TreePath[pos-1].type == SECTION_TREE and > > > TreePath[pos-1].Data.Type == 0x02: > > > + self.CompressSectionData(TreePath[pos-1], > None, > > > TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid) > > > + else: > > > + if pos == len(TreePath): > > > + > self.CompressSectionData(TreePath[pos-1], > > > pos) > > > + else: > > > + > self.CompressSectionData(TreePath[pos-1], > > > None) > > > + pos -= 1 > > > + > > > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) > -> > > > None: > > > + NewData = b'' > > > + temp_save_child = TargetTree.Child > > > + if TargetTree.Data: > > > + for item in temp_save_child: > > > + if item.type == SECTION_TREE and not > > > item.Data.OriData and item.Data.ExtHeader: > > > + NewData += struct2stream(item.Data.Header) > + > > > struct2stream(item.Data.ExtHeader) + item.Data.Data + > item.Data.PadData > > > + elif item.type == SECTION_TREE and > item.Data.OriData > > > and not item.Data.ExtHeader: > > > + NewData += struct2stream(item.Data.Header) > + > > > item.Data.OriData + item.Data.PadData > > > + elif item.type == SECTION_TREE and > item.Data.OriData > > > and item.Data.ExtHeader: > > > + NewData += struct2stream(item.Data.Header) > + > > > struct2stream(item.Data.ExtHeader) + item.Data.OriData + > > > item.Data.PadData > > > + elif item.type == FFS_FREE_SPACE: > > > + NewData += item.Data.Data + > item.Data.PadData > > > + else: > > > + NewData += struct2stream(item.Data.Header) > + > > > item.Data.Data + item.Data.PadData > > > + if TargetTree.type == FFS_TREE: > > > + New_Pad_Size = GetPadSize(len(NewData), 8) > > > + Size_delta = len(NewData) - > len(TargetTree.Data.Data) > > > + ChangeSize(TargetTree, -Size_delta) > > > + Delta_Pad_Size = len(TargetTree.Data.PadData) - > > > New_Pad_Size > > > + self.Remain_New_Free_Space += Delta_Pad_Size > > > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size > > > + TargetTree.Data.ModCheckSum() > > > + elif TargetTree.type == FV_TREE or TargetTree.type == > > > SEC_FV_TREE and not pos: > > > + if self.Remain_New_Free_Space: > > > + if TargetTree.Data.Free_Space: > > > + TargetTree.Data.Free_Space += > > > self.Remain_New_Free_Space > > > + NewData += > self.Remain_New_Free_Space * > > > b'\xff' > > > + TargetTree.Child[-1].Data.Data += > > > self.Remain_New_Free_Space * b'\xff' > > > + else: > > > + TargetTree.Data.Data += > > > self.Remain_New_Free_Space * b'\xff' > > > + New_Free_Space = > BIOSTREE('FREE_SPACE') > > > + New_Free_Space.type = FFS_FREE_SPACE > > > + New_Free_Space.Data = > > > FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space) > > > + TargetTree.insertChild(New_Free_Space) > > > + self.Remain_New_Free_Space = 0 > > > + if TargetTree.type == SEC_FV_TREE: > > > + Size_delta = len(NewData) + > > > self.Remain_New_Free_Space - len(TargetTree.Data.Data) > > > + TargetTree.Data.Header.FvLength += Size_delta > > > + TargetTree.Data.ModFvExt() > > > + TargetTree.Data.ModFvSize() > > > + TargetTree.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetTree) > > > + TargetTree.Data.ModCheckSum() > > > + elif TargetTree.type == SECTION_TREE and > > > TargetTree.Data.Type != 0x02: > > > + New_Pad_Size = GetPadSize(len(NewData), 4) > > > + Size_delta = len(NewData) - > len(TargetTree.Data.Data) > > > + ChangeSize(TargetTree, -Size_delta) > > > + if TargetTree.NextRel: > > > + Delta_Pad_Size = len(TargetTree.Data.PadData) > - > > > New_Pad_Size > > > + self.Remain_New_Free_Space += > Delta_Pad_Size > > > + TargetTree.Data.PadData = b'\x00' * > > > New_Pad_Size > > > + TargetTree.Data.Data = NewData > > > + if GuidTool: > > > + ParPath = > > > > > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+".. > > ") > > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini') > > > + guidtool = > > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool)) > > > + CompressedData = guidtool.pack(TargetTree.Data.Data) > > > + if len(CompressedData) < len(TargetTree.Data.OriData): > > > + New_Pad_Size = GetPadSize(len(CompressedData), > 4) > > > + Size_delta = len(CompressedData) - > > > len(TargetTree.Data.OriData) > > > + ChangeSize(TargetTree, -Size_delta) > > > + if TargetTree.NextRel: > > > + TargetTree.Data.PadData = b'\x00' * > > > New_Pad_Size > > > + self.Remain_New_Free_Space = > > > len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - > > > len(CompressedData) - New_Pad_Size > > > + else: > > > + TargetTree.Data.PadData = b'' > > > + self.Remain_New_Free_Space = > > > len(TargetTree.Data.OriData) - len(CompressedData) > > > + TargetTree.Data.OriData = CompressedData > > > + elif len(CompressedData) == > len(TargetTree.Data.OriData): > > > + TargetTree.Data.OriData = CompressedData > > > + elif len(CompressedData) > len(TargetTree.Data.OriData): > > > + New_Pad_Size = GetPadSize(CompressedData, 4) > > > + self.Remain_New_Free_Space = > len(CompressedData) + > > > New_Pad_Size - len(TargetTree.Data.OriData) - > > len(TargetTree.Data.PadData) > > > + Size_delta = len(TargetTree.Data.OriData) - > > > len(CompressedData) > > > + ChangeSize(TargetTree, -Size_delta) > > > + if TargetTree.NextRel: > > > + TargetTree.Data.PadData = b'\x00' * > > > New_Pad_Size > > > + TargetTree.Data.OriData = CompressedData > > > + self.ModifyTest(TargetTree, > > > self.Remain_New_Free_Space) > > > + self.Status = False > > > + > > > + def ModifyFvExtData(self, TreeNode) -> None: > > > + FvExtData = b'' > > > + if TreeNode.Data.Header.ExtHeaderOffset: > > > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader) > > > + FvExtData += FvExtHeader > > > + if TreeNode.Data.Header.ExtHeaderOffset and > > > TreeNode.Data.ExtEntryExist: > > > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry) > > > + FvExtData += FvExtEntry > > > + if FvExtData: > > > + InfoNode = TreeNode.Child[0] > > > + InfoNode.Data.Data = FvExtData + > > > InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:] > > > + InfoNode.Data.ModCheckSum() > > > + > > > + def ModifyTest(self, ParTree, Needed_Space: int) -> None: > > > + if Needed_Space > 0: > > > + if ParTree.type == FV_TREE or ParTree.type == > SEC_FV_TREE: > > > + ParTree.Data.Data = b'' > > > + Needed_Space = Needed_Space - > > > ParTree.Data.Free_Space > > > + if Needed_Space < 0: > > > + ParTree.Child[-1].Data.Data = b'\xff' * > > > (-Needed_Space) > > > + ParTree.Data.Free_Space = (-Needed_Space) > > > + self.Status = True > > > + else: > > > + if ParTree.type == FV_TREE: > > > + self.Status = False > > > + else: > > > + BlockSize = > > > ParTree.Data.Header.BlockMap[0].Length > > > + New_Add_Len = BlockSize - > > > Needed_Space%BlockSize > > > + if New_Add_Len % BlockSize: > > > + ParTree.Child[-1].Data.Data = b'\xff' * > > > New_Add_Len > > > + ParTree.Data.Free_Space = > > > New_Add_Len > > > + Needed_Space += New_Add_Len > > > + else: > > > + > ParTree.Child.remove(ParTree.Child[-1]) > > > + ParTree.Data.Free_Space = 0 > > > + ParTree.Data.Size += Needed_Space > > > + ParTree.Data.Header.Fvlength = > > > ParTree.Data.Size > > > + for item in ParTree.Child: > > > + if item.type == FFS_FREE_SPACE: > > > + ParTree.Data.Data += item.Data.Data + > > > item.Data.PadData > > > + else: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > > + ParTree.Data.ModFvExt() > > > + ParTree.Data.ModFvSize() > > > + ParTree.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(ParTree) > > > + ParTree.Data.ModCheckSum() > > > + elif ParTree.type == FFS_TREE: > > > + ParTree.Data.Data = b'' > > > + for item in ParTree.Child: > > > + if item.Data.OriData: > > > + if item.Data.ExtHeader: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) > + > > > item.Data.OriData + item.Data.PadData > > > + else: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.OriData + > item.Data.PadData > > > + else: > > > + if item.Data.ExtHeader: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) > + > > > item.Data.Data + item.Data.PadData > > > + else: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > > + ChangeSize(ParTree, -Needed_Space) > > > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8) > > > + Delta_Pad_Size = New_Pad_Size - > > > len(ParTree.Data.PadData) > > > + Needed_Space += Delta_Pad_Size > > > + ParTree.Data.PadData = b'\xff' * > > > GetPadSize(ParTree.Data.Size, 8) > > > + ParTree.Data.ModCheckSum() > > > + elif ParTree.type == SECTION_TREE: > > > + OriData = ParTree.Data.Data > > > + ParTree.Data.Data = b'' > > > + for item in ParTree.Child: > > > + if item.type == SECTION_TREE and > > > item.Data.ExtHeader and item.Data.Type != 0x02: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) > + > > > item.Data.Data + item.Data.PadData > > > + elif item.type == SECTION_TREE and > > > item.Data.ExtHeader and item.Data.Type == 0x02: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) > + > > > item.Data.OriData + item.Data.PadData > > > + else: > > > + ParTree.Data.Data += > > > struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData > > > + if ParTree.Data.Type == 0x02: > > > + ParTree.Data.Size += Needed_Space > > > + ParPath = > > > os.path.abspath(os.path.dirname(os.path.abspath(__file__))) > > > + ToolPath = > os.path.join(os.path.dirname(ParPath), > > > r'FMMTConfig.ini') > > > + guidtool = > > > > > > GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Se > > c > > > tionDefinitionGuid)) > > > + CompressedData = > > > guidtool.pack(ParTree.Data.Data) > > > + Needed_Space = len(CompressedData) - > > > len(ParTree.Data.OriData) > > > + ParTree.Data.OriData = CompressedData > > > + New_Size = ParTree.Data.HeaderLength + > > > len(CompressedData) > > > + ParTree.Data.Header.Size[0] = New_Size % > (16**2) > > > + ParTree.Data.Header.Size[1] = New_Size % > (16**4) > > > //(16**2) > > > + ParTree.Data.Header.Size[2] = New_Size // > (16**4) > > > + if ParTree.NextRel: > > > + New_Pad_Size = GetPadSize(New_Size, 4) > > > + Delta_Pad_Size = New_Pad_Size - > > > len(ParTree.Data.PadData) > > > + ParTree.Data.PadData = b'\x00' * > > > New_Pad_Size > > > + Needed_Space += Delta_Pad_Size > > > + else: > > > + ParTree.Data.PadData = b'' > > > + elif Needed_Space: > > > + ChangeSize(ParTree, -Needed_Space) > > > + New_Pad_Size = GetPadSize(ParTree.Data.Size, > 4) > > > + Delta_Pad_Size = New_Pad_Size - > > > len(ParTree.Data.PadData) > > > + Needed_Space += Delta_Pad_Size > > > + ParTree.Data.PadData = b'\x00' * > New_Pad_Size > > > + NewParTree = ParTree.Parent > > > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, > > > ROOT_SECTION_TREE, ROOT_TREE] > > > + if NewParTree and NewParTree.type not in ROOT_TYPE: > > > + self.ModifyTest(NewParTree, Needed_Space) > > > + else: > > > + self.Status = True > > > + > > > + def ReplaceFfs(self) -> bool: > > > + TargetFv = self.TargetFfs.Parent > > > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, > Child > > > Ffs Header State need be reversed. > > > + if TargetFv.Data.Header.Attributes & > EFI_FVB2_ERASE_POLARITY: > > > + self.NewFfs.Data.Header.State = c_uint8( > > > + ~self.NewFfs.Data.Header.State) > > > + # NewFfs parsing will not calculate the PadSize, thus > > recalculate. > > > + self.NewFfs.Data.PadData = b'\xff' * > > > GetPadSize(self.NewFfs.Data.Size, 8) > > > + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size: > > > + Needed_Space = self.NewFfs.Data.Size + > > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > > > len(self.TargetFfs.Data.PadData) > > > + # If TargetFv have enough free space, just move part of > the > > > free space to NewFfs. > > > + if TargetFv.Data.Free_Space >= Needed_Space: > > > + # Modify TargetFv Child info and BiosTree. > > > + TargetFv.Child[-1].Data.Data = b'\xff' * > > > (TargetFv.Data.Free_Space - Needed_Space) > > > + TargetFv.Data.Free_Space -= Needed_Space > > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.insertChild(self.NewFfs, Target_index) > > > + # Modify TargetFv Header and ExtHeader info. > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModFvSize() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + # return the Status > > > + self.Status = True > > > + # If TargetFv do not have enough free space, need move > part > > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > > + else: > > > + if TargetFv.type == FV_TREE: > > > + self.Status = False > > > + else: > > > + # Recalculate TargetFv needed space to keep it > > > match the BlockSize setting. > > > + Needed_Space -= TargetFv.Data.Free_Space > > > + BlockSize = > > > TargetFv.Data.Header.BlockMap[0].Length > > > + New_Add_Len = BlockSize - > > > Needed_Space%BlockSize > > > + Target_index = > TargetFv.Child.index(self.TargetFfs) > > > + if New_Add_Len % BlockSize: > > > + TargetFv.Child[-1].Data.Data = b'\xff' * > > > New_Add_Len > > > + TargetFv.Data.Free_Space = > New_Add_Len > > > + Needed_Space += New_Add_Len > > > + TargetFv.insertChild(self.NewFfs, > Target_index) > > > + TargetFv.Child.remove(self.TargetFfs) > > > + else: > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.Data.Free_Space = 0 > > > + TargetFv.insertChild(self.NewFfs) > > > + # Encapsulate the Fv Data for update. > > > + TargetFv.Data.Data = b'' > > > + for item in TargetFv.Child: > > > + if item.type == FFS_FREE_SPACE: > > > + TargetFv.Data.Data += > item.Data.Data + > > > item.Data.PadData > > > + else: > > > + TargetFv.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > > + TargetFv.Data.Size += Needed_Space > > > + # Modify TargetFv Data Header and ExtHeader > info. > > > + TargetFv.Data.Header.FvLength = > > > TargetFv.Data.Size > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModFvSize() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + # Start free space calculating and moving > process. > > > + self.ModifyTest(TargetFv.Parent, > Needed_Space) > > > + else: > > > + New_Free_Space = self.TargetFfs.Data.Size - > > > self.NewFfs.Data.Size > > > + # If TargetFv already have free space, move the new free > > > space into it. > > > + if TargetFv.Data.Free_Space: > > > + TargetFv.Child[-1].Data.Data += b'\xff' * > > > New_Free_Space > > > + TargetFv.Data.Free_Space += New_Free_Space > > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.insertChild(self.NewFfs, Target_index) > > > + self.Status = True > > > + # If TargetFv do not have free space, create free space for > > Fv. > > > + else: > > > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE') > > > + New_Free_Space_Tree.type = FFS_FREE_SPACE > > > + New_Free_Space_Tree.Data = FfsNode(b'\xff' * > > > New_Free_Space) > > > + TargetFv.Data.Free_Space = New_Free_Space > > > + TargetFv.insertChild(New_Free_Space) > > > + Target_index = TargetFv.Child.index(self.TargetFfs) > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.insertChild(self.NewFfs, Target_index) > > > + self.Status = True > > > + # Modify TargetFv Header and ExtHeader info. > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModFvSize() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + return self.Status > > > + > > > + def AddFfs(self) -> bool: > > > + # NewFfs parsing will not calculate the PadSize, thus > > recalculate. > > > + self.NewFfs.Data.PadData = b'\xff' * > > > GetPadSize(self.NewFfs.Data.Size, 8) > > > + if self.TargetFfs.type == FFS_FREE_SPACE: > > > + TargetLen = self.NewFfs.Data.Size + > > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - > > > len(self.TargetFfs.Data.PadData) > > > + TargetFv = self.TargetFfs.Parent > > > + # If the Fv Header Attributes is > EFI_FVB2_ERASE_POLARITY, > > > Child Ffs Header State need be reversed. > > > + if TargetFv.Data.Header.Attributes & > > > EFI_FVB2_ERASE_POLARITY: > > > + self.NewFfs.Data.Header.State = c_uint8( > > > + ~self.NewFfs.Data.Header.State) > > > + # If TargetFv have enough free space, just move part of > the > > > free space to NewFfs, split free space to NewFfs and new free space. > > > + if TargetLen < 0: > > > + self.Status = True > > > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen) > > > + TargetFv.Data.Free_Space = (-TargetLen) > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + TargetFv.insertChild(self.NewFfs, -1) > > > + ModifyFfsType(self.NewFfs) > > > + elif TargetLen == 0: > > > + self.Status = True > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.insertChild(self.NewFfs) > > > + ModifyFfsType(self.NewFfs) > > > + # If TargetFv do not have enough free space, need move > part > > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > > + else: > > > + if TargetFv.type == FV_TREE: > > > + self.Status = False > > > + elif TargetFv.type == SEC_FV_TREE: > > > + # Recalculate TargetFv needed space to keep it > > > match the BlockSize setting. > > > + BlockSize = > > > TargetFv.Data.Header.BlockMap[0].Length > > > + New_Add_Len = BlockSize - > TargetLen%BlockSize > > > + if New_Add_Len % BlockSize: > > > + self.TargetFfs.Data.Data = b'\xff' * > > > New_Add_Len > > > + self.TargetFfs.Data.Size = New_Add_Len > > > + TargetLen += New_Add_Len > > > + TargetFv.insertChild(self.NewFfs, -1) > > > + TargetFv.Data.Free_Space = > New_Add_Len > > > + else: > > > + TargetFv.Child.remove(self.TargetFfs) > > > + TargetFv.insertChild(self.NewFfs) > > > + TargetFv.Data.Free_Space = 0 > > > + ModifyFfsType(self.NewFfs) > > > + TargetFv.Data.Data = b'' > > > + for item in TargetFv.Child: > > > + if item.type == FFS_FREE_SPACE: > > > + TargetFv.Data.Data += > item.Data.Data + > > > item.Data.PadData > > > + else: > > > + TargetFv.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > > + # Encapsulate the Fv Data for update. > > > + TargetFv.Data.Size += TargetLen > > > + TargetFv.Data.Header.FvLength = > > > TargetFv.Data.Size > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModFvSize() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + # Start free space calculating and moving > process. > > > + self.ModifyTest(TargetFv.Parent, TargetLen) > > > + else: > > > + # If TargetFv do not have free space, need directly move > part > > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs. > > > + TargetLen = self.NewFfs.Data.Size + > > > len(self.NewFfs.Data.PadData) > > > + TargetFv = self.TargetFfs.Parent > > > + if TargetFv.Data.Header.Attributes & > > > EFI_FVB2_ERASE_POLARITY: > > > + self.NewFfs.Data.Header.State = c_uint8( > > > + ~self.NewFfs.Data.Header.State) > > > + if TargetFv.type == FV_TREE: > > > + self.Status = False > > > + elif TargetFv.type == SEC_FV_TREE: > > > + BlockSize = > TargetFv.Data.Header.BlockMap[0].Length > > > + New_Add_Len = BlockSize - TargetLen%BlockSize > > > + if New_Add_Len % BlockSize: > > > + New_Free_Space = BIOSTREE('FREE_SPACE') > > > + New_Free_Space.type = FFS_FREE_SPACE > > > + New_Free_Space.Data = FreeSpaceNode(b'\xff' > * > > > New_Add_Len) > > > + TargetLen += New_Add_Len > > > + TargetFv.Data.Free_Space = New_Add_Len > > > + TargetFv.insertChild(self.NewFfs) > > > + TargetFv.insertChild(New_Free_Space) > > > + else: > > > + TargetFv.insertChild(self.NewFfs) > > > + ModifyFfsType(self.NewFfs) > > > + TargetFv.Data.Data = b'' > > > + for item in TargetFv.Child: > > > + if item.type == FFS_FREE_SPACE: > > > + TargetFv.Data.Data += item.Data.Data + > > > item.Data.PadData > > > + else: > > > + TargetFv.Data.Data += > > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData > > > + TargetFv.Data.Size += TargetLen > > > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size > > > + TargetFv.Data.ModFvExt() > > > + TargetFv.Data.ModFvSize() > > > + TargetFv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(TargetFv) > > > + TargetFv.Data.ModCheckSum() > > > + self.ModifyTest(TargetFv.Parent, TargetLen) > > > + return self.Status > > > + > > > + def DeleteFfs(self) -> bool: > > > + Delete_Ffs = self.TargetFfs > > > + Delete_Fv = Delete_Ffs.Parent > > > + Add_Free_Space = Delete_Ffs.Data.Size + > > > len(Delete_Ffs.Data.PadData) > > > + if Delete_Fv.Data.Free_Space: > > > + if Delete_Fv.type == SEC_FV_TREE: > > > + Used_Size = Delete_Fv.Data.Size - > > > Delete_Fv.Data.Free_Space - Add_Free_Space > > > + BlockSize = > Delete_Fv.Data.Header.BlockMap[0].Length > > > + New_Free_Space = BlockSize - Used_Size % > BlockSize > > > + self.Remain_New_Free_Space += > > > Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space > > > + Delete_Fv.Child[-1].Data.Data = New_Free_Space * > > > b'\xff' > > > + Delete_Fv.Data.Free_Space = New_Free_Space > > > + else: > > > + Used_Size = Delete_Fv.Data.Size - > > > Delete_Fv.Data.Free_Space - Add_Free_Space > > > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * > > > b'\xff' > > > + Delete_Fv.Data.Free_Space += Add_Free_Space > > > + New_Free_Space = Delete_Fv.Data.Free_Space + > > > Add_Free_Space > > > + else: > > > + if Delete_Fv.type == SEC_FV_TREE: > > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > > > + BlockSize = > Delete_Fv.Data.Header.BlockMap[0].Length > > > + New_Free_Space = BlockSize - Used_Size % > BlockSize > > > + self.Remain_New_Free_Space += Add_Free_Space - > > > New_Free_Space > > > + Add_Free_Space = New_Free_Space > > > + else: > > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space > > > + New_Free_Space = Add_Free_Space > > > + New_Free_Space_Info = FfsNode(Add_Free_Space * > b'\xff') > > > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff' > > > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name) > > > + New_Ffs_Tree.type = FFS_FREE_SPACE > > > + New_Ffs_Tree.Data = New_Free_Space_Info > > > + Delete_Fv.insertChild(New_Ffs_Tree) > > > + Delete_Fv.Data.Free_Space = Add_Free_Space > > > + Delete_Fv.Child.remove(Delete_Ffs) > > > + Delete_Fv.Data.Header.FvLength = Used_Size + > New_Free_Space > > > + Delete_Fv.Data.ModFvExt() > > > + Delete_Fv.Data.ModFvSize() > > > + Delete_Fv.Data.ModExtHeaderData() > > > + self.ModifyFvExtData(Delete_Fv) > > > + Delete_Fv.Data.ModCheckSum() > > > + self.CompressData(Delete_Fv) > > > + self.Status = True > > > + return self.Status > > > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py > > > b/BaseTools/Source/Python/FMMT/core/GuidTools.py > > > new file mode 100644 > > > index 000000000000..e21d8e0406ae > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py > > > @@ -0,0 +1,152 @@ > > > +## @file > > > +# This file is used to define the FMMT dependent external tool > > management > > > class. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > +import glob > > > +import logging > > > +import os > > > +import shutil > > > +import sys > > > +import tempfile > > > +import uuid > > > +from PI.Common import * > > > +from utils.FmmtLogger import FmmtLogger as logger > > > +import subprocess > > > + > > > +def ExecuteCommand(cmd: list) -> None: > > > + subprocess.run(cmd,stdout=subprocess.DEVNULL) > > > + > > > +class GUIDTool: > > > + def __init__(self, guid: str, short_name: str, command: str) -> None: > > > + self.guid: str = guid > > > + self.short_name: str = short_name > > > + self.command: str = command > > > + > > > + def pack(self, buffer: bytes) -> bytes: > > > + """ > > > + compress file. > > > + """ > > > + tool = self.command > > > + if tool: > > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > > > + ToolInputFile = os.path.join(tmp, > > > "pack_uncompress_sec_file") > > > + ToolOuputFile = os.path.join(tmp, "pack_sec_file") > > > + try: > > > + file = open(ToolInputFile, "wb") > > > + file.write(buffer) > > > + file.close() > > > + command = [tool, '-e', '-o', ToolOuputFile, > > > + ToolInputFile] > > > + ExecuteCommand(command) > > > + buf = open(ToolOuputFile, "rb") > > > + res_buffer = buf.read() > > > + except Exception as msg: > > > + logger.error(msg) > > > + return "" > > > + else: > > > + buf.close() > > > + if os.path.exists(tmp): > > > + shutil.rmtree(tmp) > > > + return res_buffer > > > + else: > > > + logger.error( > > > + "Error parsing section: EFI_SECTION_GUID_DEFINED > > > cannot be parsed at this time.") > > > + logger.info("Its GUID is: %s" % self.guid) > > > + return "" > > > + > > > + > > > + def unpack(self, buffer: bytes) -> bytes: > > > + """ > > > + buffer: remove common header > > > + uncompress file > > > + """ > > > + tool = self.command > > > + if tool: > > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp')) > > > + ToolInputFile = os.path.join(tmp, "unpack_sec_file") > > > + ToolOuputFile = os.path.join(tmp, > > > "unpack_uncompress_sec_file") > > > + try: > > > + file = open(ToolInputFile, "wb") > > > + file.write(buffer) > > > + file.close() > > > + command = [tool, '-d', '-o', ToolOuputFile, > > ToolInputFile] > > > + ExecuteCommand(command) > > > + buf = open(ToolOuputFile, "rb") > > > + res_buffer = buf.read() > > > + except Exception as msg: > > > + logger.error(msg) > > > + return "" > > > + else: > > > + buf.close() > > > + if os.path.exists(tmp): > > > + shutil.rmtree(tmp) > > > + return res_buffer > > > + else: > > > + logger.error("Error parsing section: > > > EFI_SECTION_GUID_DEFINED cannot be parsed at this time.") > > > + logger.info("Its GUID is: %s" % self.guid) > > > + return "" > > > + > > > +class GUIDTools: > > > + ''' > > > + GUIDTools is responsible for reading FMMTConfig.ini, verify the > tools > > > and provide interfaces to access those tools. > > > + ''' > > > + default_tools = { > > > + > > > struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8- > > 127f4c984779 > > > ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", > > > "TianoCompress"), > > > + > > > struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e- > > dc7bd79403cf > > > ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", > > > "LzmaCompress"), > > > + > > > struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a- > > a4600d9dd083 > > > ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", > > > "GenCrc32"), > > > + > > > struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a- > > ca72a6eae889 > > > ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", > > > "LzmaF86Compress"), > > > + > > > struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e- > > 0f7f630d5afb") > > > ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", > > > "BrotliCompress"), > > > + } > > > + > > > + def __init__(self, tooldef_file: str=None) -> None: > > > + self.dir = os.path.dirname(__file__) > > > + self.tooldef_file = tooldef_file if tooldef_file else > > os.path.join( > > > + self.dir, "FMMTConfig.ini") > > > + self.tooldef = dict() > > > + self.load() > > > + > > > + def VerifyTools(self) -> None: > > > + """ > > > + Verify Tools and Update Tools path. > > > + """ > > > + path_env = os.environ.get("PATH") > > > + path_env_list = path_env.split(os.pathsep) > > > + path_env_list.append(os.path.dirname(__file__)) > > > + path_env_list = list(set(path_env_list)) > > > + for tool in self.tooldef.values(): > > > + cmd = tool.command > > > + if os.path.isabs(cmd): > > > + if not os.path.exists(cmd): > > > + print("Tool Not found %s" % cmd) > > > + else: > > > + for syspath in path_env_list: > > > + if glob.glob(os.path.join(syspath, cmd+"*")): > > > + break > > > + else: > > > + print("Tool Not found %s" % cmd) > > > + > > > + def load(self) -> None: > > > + if os.path.exists(self.tooldef_file): > > > + with open(self.tooldef_file, "r") as fd: > > > + config_data = fd.readlines() > > > + for line in config_data: > > > + try: > > > + guid, short_name, command = line.split() > > > + new_format_guid = > > > struct2stream(ModifyGuidFormat(guid.strip())) > > > + self.tooldef[new_format_guid] = GUIDTool( > > > + guid.strip(), short_name.strip(), > > > command.strip()) > > > + except: > > > + print("GuidTool load error!") > > > + continue > > > + else: > > > + self.tooldef.update(self.default_tools) > > > + > > > + self.VerifyTools() > > > + > > > + def __getitem__(self, guid) -> None: > > > + return self.tooldef.get(guid) > > > + > > > + > > > +guidtools = GUIDTools() > > > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > > b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > > new file mode 100644 > > > index 000000000000..18f0cff96e4b > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py > > > @@ -0,0 +1,18 @@ > > > +## @file > > > +# This file is used to define the Fmmt Logger. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > + > > > +## > > > + > > > +import logging > > > +import sys > > > + > > > +FmmtLogger = logging.getLogger('FMMT') > > > +FmmtLogger.setLevel(logging.INFO) > > > + > > > +lh=logging.StreamHandler(sys.stdout) > > > +lf=logging.Formatter("%(levelname)-8s: %(message)s") > > > +lh.setFormatter(lf) > > > +FmmtLogger.addHandler(lh) > > > \ No newline at end of file > > > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > > b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > > new file mode 100644 > > > index 000000000000..1a6c67056266 > > > --- /dev/null > > > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py > > > @@ -0,0 +1,54 @@ > > > +## @file > > > +# This file is used to define the printer for Bios layout. > > > +# > > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR> > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > +## > > > + > > > +def GetFormatter(layout_format: str): > > > + if layout_format == 'json': > > > + return JsonFormatter() > > > + elif layout_format == 'yaml': > > > + return YamlFormatter() > > > + elif layout_format == 'html': > > > + return HtmlFormatter() > > > + else: > > > + return TxtFormatter() > > > + > > > +class Formatter(object): > > > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None: > > > + raise NotImplemented > > > + > > > +class JsonFormatter(Formatter): > > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: > > str=None) -> > > > None: > > > + try: > > > + import json > > > + except: > > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > > + return > > > + print(outputfile) > > > + if outputfile: > > > + with open(outputfile,"w") as fw: > > > + json.dump(layoutdict, fw, indent=2) > > > + else: > > > + print(json.dumps(layoutdict,indent=2)) > > > + > > > +class TxtFormatter(Formatter): > > > + def LogPrint(self,layoutlist: list) -> None: > > > + for item in layoutlist: > > > + print(item) > > > + print('\n') > > > + > > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: > > str=None) -> > > > None: > > > + print(outputfile) > > > + with open(outputfile, "w") as f: > > > + for item in layoutlist: > > > + f.writelines(item + '\n') > > > + > > > +class YamlFormatter(Formatter): > > > + def dump(self,layoutdict, layoutlist, outputfile = None): > > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > > + > > > +class HtmlFormatter(Formatter): > > > + def dump(self,layoutdict, layoutlist, outputfile = None): > > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile) > > > \ No newline at end of file > > > -- > > > 2.27.0.windows.1 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-12-06 9:45 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-12-01 1:29 [PATCH 1/1] BaseTools: Add FMMT Tool Yuwei Chen 2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming 2021-12-06 8:34 ` Yuwei Chen 2021-12-06 9:44 ` 回复: " gaoliming
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox