From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: zhijux.fan@intel.com) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by groups.io with SMTP; Fri, 21 Jun 2019 03:03:47 -0700 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Jun 2019 03:03:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,400,1557212400"; d="dat'59?scan'59,208,59";a="171171628" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga002.jf.intel.com with ESMTP; 21 Jun 2019 03:03:46 -0700 Received: from fmsmsx116.amr.corp.intel.com (10.18.116.20) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 21 Jun 2019 03:03:45 -0700 Received: from shsmsx108.ccr.corp.intel.com (10.239.4.97) by fmsmsx116.amr.corp.intel.com (10.18.116.20) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 21 Jun 2019 03:03:45 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.87]) by SHSMSX108.ccr.corp.intel.com ([169.254.8.236]) with mapi id 14.03.0439.000; Fri, 21 Jun 2019 18:03:43 +0800 From: "Fan, ZhijuX" To: "devel@edk2.groups.io" CC: "Gao, Liming" , "Feng, Bob C" , Ard Biesheuvel , "Leif Lindholm" , "Kinney, Michael D" Subject: [edk2-platform patch 1/2 V2] Platform/Intel:Add GenBiosId into edk2-platforms/Platform/Intel/Tools Thread-Topic: [edk2-platform patch 1/2 V2] Platform/Intel:Add GenBiosId into edk2-platforms/Platform/Intel/Tools Thread-Index: AdUoGJn+YjvmyWetRSmruLKGzfC2cw== Date: Fri, 21 Jun 2019 10:03:42 +0000 Message-ID: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.600.7 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: zhijux.fan@intel.com X-Groupsio-MsgNum: 42696 Content-Type: multipart/mixed; boundary="_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF84271SHSMSX101ccrcor_" Content-Language: en-US --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF84271SHSMSX101ccrcor_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1855 GenBiosId is a tool to generate the BIOS ID binary file which uses the data from the configuration file. This tool can be run in both Py2 and Py3. This patch is going to add GenBiosId to Platform/Intel/Tools Cc: Liming Gao Cc: Bob Feng Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Michael D Kinney Signed-off-by: Zhiju.Fan --- Platform/Intel/Tools/GenBiosId/BiosId.env | 27 +++++ Platform/Intel/Tools/GenBiosId/GenBiosId.py | 180 ++++++++++++++++++++++++= ++++ 2 files changed, 207 insertions(+) create mode 100644 Platform/Intel/Tools/GenBiosId/BiosId.env create mode 100644 Platform/Intel/Tools/GenBiosId/GenBiosId.py diff --git a/Platform/Intel/Tools/GenBiosId/BiosId.env b/Platform/Intel/Too= ls/GenBiosId/BiosId.env new file mode 100644 index 0000000000..e1e913da76 --- /dev/null +++ b/Platform/Intel/Tools/GenBiosId/BiosId.env @@ -0,0 +1,27 @@ +## @file +# This file is used to define the BIOS ID parameters of the build. +# This file is processed by GenBiosId. +# Here, it is just a template and can be customized by user. +# +# BIOS ID string format: +# $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(= VERSION_MINOR).YYMMDDHHMM +# All fields must have a fixed length. YYMMDDHHMM is UTC time. +# Example: "EMLATOR1.000.0001.D01.1906141517" +# +# If DATE is specified for YYMMDD and TIME is specified for HHMM like bel= ow, +# GenBiosId will use the value of DATE and TIME to fill YYMMDDHHMM, +# otherwise GenBiosId will fill YYMMDDHHMM with current UTC time of the b= uild machine. +# DATE =3D 190614 +# TIME =3D 1517 +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[config] +BOARD_ID =3D KBLRVP3 +BOARD_REV =3D 1 +BOARD_EXT =3D 000 +BUILD_TYPE =3D D +VERSION_MAJOR =3D 0001 +VERSION_MINOR =3D 01 diff --git a/Platform/Intel/Tools/GenBiosId/GenBiosId.py b/Platform/Intel/T= ools/GenBiosId/GenBiosId.py new file mode 100644 index 0000000000..20fb7592b4 --- /dev/null +++ b/Platform/Intel/Tools/GenBiosId/GenBiosId.py @@ -0,0 +1,180 @@ +## @file +# Trim files preprocessed by compiler +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +import os +import sys +import time +import logging +import struct +import datetime +import argparse +import platform + +try: + from configparser import ConfigParser +except: + from ConfigParser import ConfigParser + +# Config message +_BIOS_Signature =3D "$IBIOSI$" +_SectionKeyName =3D '__name__' +_SectionName =3D 'config' + +_ConfigItem =3D { + "BOARD_ID": {'Value': '', 'Length': 7}, + "BOARD_REV": {'Value': '', 'Length': 1}, + "BOARD_EXT": {'Value': '', 'Length': 3}, + "BUILD_TYPE": {'Value': '', 'Length': 1}, + "VERSION_MAJOR": {'Value': '0000', 'Length': 4}, + "VERSION_MINOR": {'Value': '00', 'Length': 2}, +} + +# Version message +__prog__ =3D 'GenBiosld' +__description__ =3D 'Trim files preprocessed by compiler' +__copyright__ =3D 'Copyright (c) 2019, Intel Corporation. All rights reser= ved.
' +__version__ =3D '%s Version %s' % (__prog__, '0.1 ') + +# ExtraData message +_Usage =3D "Usage: GenBiosId -i Configfile -o OutputFile [-ot OutputTextFi= le]" +_ConfigSectionNotDefine =3D "Not support the config file format, need conf= ig section" +_ErrorMessageTemplate =3D '\n\n%(tool)s...\n : error: %(msg)s\n\t%(extra)s= ' +_ErrorLogger =3D logging.getLogger("tool_error") +_ErrorFormatter =3D logging.Formatter("%(message)s") +_ConfigLenInvalid =3D "Config item %s length is invalid" +_ConfigItemInvalid =3D "Item %s is invalid" + +# Error message +INFO =3D 20 +ERRORCODE =3D 50 +OPTION_MISSING =3D 'Missing option' +FORMAT_INVALID =3D 'Invalid syntax/format' +FILE_NOT_FOUND =3D 'File/directory not found in workspace' +FORMAT_UNKNOWN_ERROR =3D 'Unknown error in syntax/format' +FORMAT_NOT_SUPPORTED =3D 'Not supported syntax/format' + + +def SetEdkLogger(): + _ErrorLogger.setLevel(INFO) + _ErrorCh =3D logging.StreamHandler(sys.stderr) + _ErrorCh.setFormatter(_ErrorFormatter) + _ErrorLogger.addHandler(_ErrorCh) + return _ErrorLogger + + +# Output the error message and exit the tool +def EdkLogger(ToolName, Message, ExtraData): + _ErrorLogger =3D SetEdkLogger() + TemplateDict =3D {"tool": ToolName, "msg": Message, "extra": ExtraData= } + LogText =3D _ErrorMessageTemplate % TemplateDict + _ErrorLogger.log(ERRORCODE, LogText) + sys.exit(1) + + +# Open the file in the correct way +def FileOpen(FileName, Mode, Buffer=3D-1): + def LongFilePath(FileName): + FileName =3D os.path.normpath(FileName) + if platform.system() =3D=3D 'Windows': + if FileName.startswith('\\\\?\\'): + return FileName + if FileName.startswith('\\\\'): + return '\\\\?\\UNC\\' + FileName[2:] + if os.path.isabs(FileName): + return '\\\\?\\' + FileName + return FileName + + return open(LongFilePath(FileName), Mode, Buffer) + + +# Parse command line options +def MyOptionParser(): + parser =3D argparse.ArgumentParser(prog=3D__prog__, + description=3D__description__ + __cop= yright__ + _Usage, + conflict_handler=3D'resolve') + parser.add_argument('-v', '--version', action=3D'version', version=3D_= _version__, + help=3D"show program's version number and exit") + parser.add_argument('-i', '--int', metavar=3D'FILENAME', dest=3D'Input= File', help=3D"Input Config file") + parser.add_argument('-o', '--out', metavar=3D'FILENAME', dest=3D'Outpu= tFile', help=3D"Output file") + parser.add_argument('-ot', '--text', metavar=3D'FILENAME', dest=3D'Out= putTextFile', help=3D"Output Text file") + Options =3D parser.parse_args() + return Options + + +# Check the Tool for missing variables +def CheckOptions(Options): + if len(sys.argv) !=3D 5 and not (len(sys.argv) =3D=3D 7 and Options.Ou= tputTextFile): + EdkLogger("GenBiosId", OPTION_MISSING, ExtraData=3D_Usage) + elif not Options.InputFile or not Options.OutputFile: + EdkLogger("GenBiosId", OPTION_MISSING, ExtraData=3D_Usage) + InputFile =3D Options.InputFile + OutputFile =3D Options.OutputFile + OutputTextFile =3D Options.OutputTextFile + if not os.path.exists(InputFile): + EdkLogger("GenBiosId", FILE_NOT_FOUND, ExtraData=3D"Input file not= found") + return InputFile, OutputFile, OutputTextFile + + +# Parse the input file and extract the information +def ParserInputFile(InputFile): + cf =3D ConfigParser() + cf.optionxform =3D str + cf.read(InputFile) + if _SectionName not in cf._sections: + EdkLogger("GenBiosId", FORMAT_NOT_SUPPORTED, ExtraData=3D_ConfigSe= ctionNotDefine) + for Item in cf._sections[_SectionName]: + if Item =3D=3D _SectionKeyName: + continue + if Item not in _ConfigItem: + EdkLogger("GenBiosId", FORMAT_INVALID, ExtraData=3D_ConfigItem= Invalid % Item) + _ConfigItem[Item]['Value'] =3D cf._sections[_SectionName][Item] + if len(_ConfigItem[Item]['Value']) !=3D _ConfigItem[Item]['Length'= ]: + EdkLogger("GenBiosId", FORMAT_INVALID, ExtraData=3D_ConfigLenI= nvalid % Item) + for Item in _ConfigItem: + if not _ConfigItem[Item]['Value']: + EdkLogger("GenBiosId", FORMAT_UNKNOWN_ERROR, ExtraData=3D"Item= %s is missing" % Item) + utcnow =3D datetime.datetime.utcnow() + TimeStamp =3D time.strftime("%y%m%d%H%M", utcnow.timetuple()) + + Id_Str =3D _ConfigItem['BOARD_ID']['Value'] + _ConfigItem['BOARD_REV']= ['Value'] + '.' + _ConfigItem['BOARD_EXT'][ + 'Value'] + '.' + _ConfigItem['VERSION_MAJOR']['Value'] + \ + '.' + _ConfigItem["BUILD_TYPE"]['Value'] + _ConfigItem['VERSI= ON_MINOR']['Value'] + '.' + TimeStamp + return Id_Str + + +# Output information to a file +def PrintOutputFile(OutputFile, OutputTextFile, Id_Str): + with FileOpen(OutputFile, 'wb') as FdOut: + for i in _BIOS_Signature: + FdOut.write(struct.pack('B', ord(i))) + + for i in Id_Str: + FdOut.write(struct.pack('H', ord(i))) + + FdOut.write(struct.pack('H', 0x00)) + if OutputTextFile: + with FileOpen(OutputTextFile, 'w') as FdOut: + FdOut.write(Id_Str) + + +# Tool entrance method +def Main(): + Options =3D MyOptionParser() + InputFile, OutputFile, OutputTextFile =3D CheckOptions(Options) + Id_Str =3D ParserInputFile(InputFile) + PrintOutputFile(OutputFile, OutputTextFile, Id_Str) + return 0 + + +if __name__ =3D=3D '__main__': + r =3D Main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: r =3D 1 + sys.exit(r) --=20 2.14.1.windows.1 --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF84271SHSMSX101ccrcor_ Content-Disposition: attachment; filename="winmail.dat" Content-Transfer-Encoding: base64 Content-Type: application/ms-tnef; name="winmail.dat" eJ8+Igc1AQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAEJgAEAIQAAAEZBQTM0OUEx RTgyNjYxNDlCREYwMTlGODEyOTA3QUNCAEAHAQ2ABAACAAAAAgACAAEFgAMADgAAAOMHBgAVAAoA AwAqAAUAQQEBIIADAA4AAADjBwYAFQAKAAMAKgAFAEEBAQiABwAYAAAASVBNLk1pY3Jvc29mdCBN YWlsLk5vdGUAMQgBBIABAGMAAABbZWRrMi1wbGF0Zm9ybSBwYXRjaCAxLzIgVjJdIFBsYXRmb3Jt L0ludGVsOkFkZCBHZW5CaW9zSWQgaW50byBlZGsyLXBsYXRmb3Jtcy9QbGF0Zm9ybS9JbnRlbC9U b29scwDFIgELgAEAIQAAAEZBQTM0OUExRTgyNjYxNDlCREYwMTlGODEyOTA3QUNCAEAHAQOQBgD0 GgAANAAAAAIBfwABAAAASAAAADxGQUQwRDdFMEFFMEZBNTREOTg3RjZFNzI0MzVDQUZENTBBRjg0 MjcxQFNIU01TWDEwMS5jY3IuY29ycC5pbnRlbC5jb20+AAsAHw4BAAAAAgEJEAEAAACREAAAjRAA AOYpAABMWkZ1XNEvIGEACmZiaWQEAABjY8BwZzEyNTIA/gND8HRleHQB9wKkA+MCAARjaArAc2V0 MCDvB20CgwBQEU0yCoAGtAKAln0KgAjIOwliMTkOwL8JwxZyCjIWcQKAFWIqCbBzCfAEkGF0BbIO UANgc6JvAYAgRXgRwW4YMF0GUnYEkBe2AhByAMB0fQhQbhoxECAFwAWgG2RkmiADUiAQIheyXHYI kOR3awuAZDUdUwTwB0ANF3AwCnEX8mJrbWsGcwGQACAgQk1fQuBFR0lOfQr8AfEL8REfsFo6aAJA cHM6wC8vYnVnegMQC2AkLnQHMG5vBaFlLgEFsGcvc2hvd19BIlEuY2dpPw3QPagxODUd4GwLgGUK gaUlFEcJ8EJpGRBJHGBpBAAgYRzAbwbwJsEgExg1GeB0aBngQklPUQXwSUQgDcBuCsB5JxxwAxAZ 4HdoDlBoIN51EgAOACUUJ+JkGIAmsO8chCfxG+EpEGcIcBiAJiDrA6ApEi4lBVQpcAQgJtPLHlAD oGIZ4HJ1A6ALgIUokG8n4CBQeTImoLsdwC7xMyy2LMoKsHQpkSkmgWdvC4BnJxJhZHccYCXoJyFQ C2AAMBrxL8JJAjBlbC9UJuEp9sElBUNjOiBMB3AxojRHYScwPCUQNaIuZ702AEALgDPRJEADcD40 2WBCb2IgRgnwMcA85QbgYiRALmY4kTbvNTPfBxAcYCYQB5An8HUaMAMg2jwLES4NwDtGQCURCsDm byNyN4pMZQaQNXEdwN0j0GwcsDYwPkEuJRE+s788zzUkGNER0DuhKIBLC4DbGFAo8Dw1oEGDLjwA HaGfQjE5jxTAK9AYUGQtGTBQZi1ieTVgWilwakh1LkYDkTx6RaJ45zkwAHBDjwotSAAlBTMfVTQi LyXnLyYULgnwdgogS0B8S0AyNyArn0vSSD9JT0pTJecucCjw/0twJMASMEvTUA9QdEwmLyCnKRIE IBmUZCxLkDBLsA8LgBIAACAsMXMoKyl7TCYFAGUnogRiT3AeoDb8NDRMn0m/SsZUL1U/Vk/fTi9P MCUMDeABICBIACRguQVAYS9aH1bvStZiXm//X39X7RhQB+ApE1lZJQUdsS0QMCAeoGZGLksAMWVI OTEzKrA3NkeYIMIvAQB2L251IqAlBU9L0WEPYh9jL0BAXeAwcixPoTEsS6FssGjmI/4jbYApEm23 S0AtMykTJoG/KcEy0wEBJSEn2wqxYQeA/xuhBCAZMCfTIlADEDwAbr/1b8VwA2BjB5BwQkVQMkj1 c1pIBJBlUvBeISaBRcDzH2AmomVtC1EnsS9CLdVmY3fRA3BpenVUKcFyf3NYc2koJh9gBRAxsRrk OgNzaUtAJChCT0FSFERfKHApfhZSRVZEKS5+FkVYVH9yVghFUlMoME5fTUGISk9Sf3NVSUx+cPBU WVBFfrGAhyAggTIAWVlNTURESEi7g3BzaUEioCkBM+BkBCC+bXfSEdAaMCahKRB4HFFnHnAZwCfg LiCDWCZyVfxUQxzAB3FzWktAGXByEAULUGU1YCJFTUxBclSBMDEuZrJmQYpARAeKwRZwWcAxNDE1 Maw3InqvbzFJPmBEigDyRSZyc3AFkAaQCJAcYccFsYNULzNUSU2NjwXAu4dTJRBrcuEz4CPgLHNp 3yXoA/CEsSnBJ9N2B0AKUP9ygo1TjycnISkRAyCDWJG6/y7BBJAD8Rngkn2VjZMBLtH9eXByCXAC MIfHcotZQADQ3ylwGFCIXI1TnYc9T3CLQ/99S49jnZqLoYvvbzEIUE8whQUQZyHQIChjKVMBzxZw UvAzs6HhcnAFsCwT/4bQhKKiMwQgCXBTcRowPAAYPEJSN4Zz0lNQRNxYLTWAdRBTYS0mUJpRBY4S cjghU0QtMi3mQwtgKcEtUCehAjCgv+tuMGjmWyuUXWjmfjadxoBLQkxSVlAzq4z/f0Gd1quMgBGd 1WZBq4eBp/2d5ERo5oCLsFSu94JrsFL/rvZdr2n/W29PBGmft99cH59kL2U/ZkoB0A2wNzUWgP5i vhZoH2kvuk+7X1y2bLn3T4Jtn26pVAUQHLBSJHTg1mV06zdRcCkhcqlfxyD/of+jD6QfpS9zs6af p6+ov/d7GKnvc9FJeFAJEQXQBHB/wWAp53sYB3DVUxkQ1q1z3nnXrogS1q0JAGckYBnA89e+fHB1 Y9LX1yUqsRIQ/9nfJqAjkAqxEgDWrXhiGuL/0358cEVgwZZ90hyDK5TfQ/8FwNclG0ErwdKA49LB lhAw/3UQBTDiP+SL5B/lKcr6K7J7WUB1IWEYMMGWH+AoMV8fRKIYgAhwGeCeICIkSXkoIkkki9fs IAWQLCJLjUJATnIRnhEnX18owPsHgO9AJ+2e7sYrlO/H61dt6JRJeDGeEVwAAOJZIk1+NiI1YPOg J1aT8ifpNWAnJ1LwJz4whpL1wf2goH2Rt/RJf0H1H/YpAFD/9v9/1fh/9imtYPpegaf73//5j/qZ gIv/TWZC9gu+EAEvf4KJAu/2Cw7A+lj9oOlfIK5WclEsMuruX3ThZ+9A7+8CJeVzMO/IX3CwHkDL 0N/mECwxDHTIP8lPcg1pIzD/y7UMdMufzK/Nv87K7yALmHcaMQrSDHQlJpAKphhwJ98ZEBOADBb2 EWbQMe8gVBZn6cmJMHxwYUQqwuruVZ/rEuzCHWM1YCXoLWnohWMpE0UAIE91IfAgIEbdKSJbRQB3 8CAUVGYQIGPeXe2I6JTwZi7ARHDE7NHzI3F8UHVw2XQrZykEfNR/UvC84IZBJUWXoO5D7YhFe5ow joBN6vQhcHhV7xFcJFxuKdElKC2CKXP3ZuAssCngIDVgclAocTVgsSowbXNnKpAp03QqMN8hgRTg KpDvyChTTNsB5/GfniDa9TagcjAuBCgiKlLaXytDIhqXKERGfONyQf8uaTFnL6Arser0KpAwaeiU 9/ZBwvCT4WmGUOzR6nW2kP/zURhxhnR3gkAQNWMiDvMy/zVJ8zMYcTdfGwsoYhxegvC8Rk+eEb+w wZaAkFKBMFhDT0SPkJ4gNbCnT5ZQj2CCs1OAsE5H7wL+TYegCtB8oRMAJ3Lvxz2gClKBAFR+gE5W QUwfcbHvETVG2KCaYGF4L+d81EH4gbBFX4MAQtA9oNxVTkNTIHLBAGmaQNyQ246AdZBuIOGQgHV4 0b6Q+5hgjoBrj+CcAP/gQg1GMDpLgwBXgOA+k+8CVW76a0eQd3kgK0NIIkQvQjrhRdJTVVBQgTCN cENT/yRJhkFMH9OrwZZwsdAQcjBoRWRrL0Up5jstqi7vl6AvMMEghQAoPYIal1PoNkOZ8C54U3xw WQBtSNuPIcoxKNihVOB0cLCaMH9Vz1bSVOIyqDENWU9UZ2H8ZGRYJlaWXGuaQOyBeSD/LapQv3N3 IBRxE0uE6uWPE/9mELaRcSIqUlG6Uqhqou7C/xQQKKUUEBvHU08t2lJ8+nr9KRZE0IB38POCL7P/ QWbY7iIr0f9BZ3ciLKP/QRvH/wlon7IuASFy7MEoT3hzGWDvbApov1R2MiEoPpcUEHE151xrWKJk oigxGp9iOY/wf0tgm1Ifk0gxJQSaMWyhd95hvGZSIyByeiIoIHJnFTO9gRQQQnW2MBiwPS1/eGDm O1IyLgA3ACBy0oFo/31naJyfsn127MGYILlggLH+LkeQwsCDcoDogZ62IOB3v1Tg2LDzQVMw7MDv EVe+kf+RkBkwgY+FpX12WNHfEM6A7ZnCKCnBisQ/isIagIf//5+2YAV9dovPiR+KL4uPjJ93KbKK 6UYwQ5EzxfCCh1s8Mjqrd469g0Y6YGFi/nOA75IPkx+LRJT5gZ6NT//TnF/JEwB9QYAvmHN9/Hh/ /+nY5PMQwkTAZHG1skGF1gf5UjJNeXogJ3Lk9FM947XT7NDfFi5B3yB17uDSwPunJQwyPRmXmN+s b465Dhn/qsEOHPrgEeyv8R1jq1+yf0+OuuNStbDckF9oWDQ9fifOscNwF6AaiKg4XfJf598RqcOK oC129gLAwBel9/YBSMCuoye4mBelqsEXpwexf5leJRBscD0ic55oS0APwQxQFOBtJzpw9xelJnCp wGLn8WRmMGi2j/23l2m4NIeAROAUEO7gHDCHNWC1QUWCTkFNRfYB/Q4RdLVQNUAgRfYBvZTFA9/q Zg9ywF/Bb7gAb7g0R+D/wy/EOyAYxZdi1cb/yA/JFf/KArhhKXAb0Mofyy8hZ8yO/3FjzY96EaWT 7MHOpd9Dt2J/mBBfP2BB1eWir+noJRBjfmsk822SJfJj0EEl0TFp35fwD5FRutrz1eUo1eWYvK+P cTbhWJPXUXYTsCE/MdtkU0eSKOBMhzE3ZFPV5a4uIRyYv2YpIh5nIhQQ/z/8Z+mqwB1jXGsUYI9x R5L/43bFB0GAS8DqiiAY5O/l///nD+gf6S/rSDXA6s/VKyAo//NoIBj0nyFn9f8hdt9dR5L/g0Zk oVjgmBDFB+Tf7n/vhf9FjPDaxhUfk0eXzcxgBcUH/+/RICcEhvn+2d+kNSUCS+D/AYdkZBvhbKEI RCYEvyFRuu+nJMUH/I+75WPd0DXAxoTrpyYNXC5BlHiGUjWxWOD3YScPxVfhZAyZ311OECMVr4Li R5JL4RABXydFc/0///5P/1VNj06Q8NsiryOzXGvX2+I54xUtWxQaXRYfj3HHOeOHMRQWS2V5gtIf P/+0FSdwv2CcXyBGFOU4iSHv/xbvF/9C9RnfONxzMDjyhN+FKrlbOPJdWydWNXD5I5AnXTWxHZ8e py4EI7//4CQtXy5n4QMyny5gVSA3Av8u0CZfJ28ofymPGnc1sStv/xw/HUMlr4U8R5I0jy5nPl/f N084X0n7AJwggiXWQJfQ3dwWIjuvvIHGUGNLMU6x/mRsUblQkAFJR0i0ay1JkbtXwL6QcE6xSYMR EWZJggH+0CV5JW0lZCXYSCVN/4FItC5Jgppw+2wwDIApop/yg7dQV8FxooE/6SdCT0FSRDlQHkQu 0C5or/FRP19SRXJWUnwnLpTiU19SMEW8WFRScUGOVO9V+1ZFIPPwkPAyQUp2EFJ8isFBn2NYUllP IkJVxABSMFTwWVBFIlKPWd/wYAAA/1stXYRLpwLPA9FQowZPeZj31BQKOXsgb7/AeqMK67Bw/yNQ y+jesAS/0vZ2cFCU/SzHkJJ82GpaJ3dikXC/wLnWQEZky+FBf9viaT1j2kLwIFMZMMbAbgEQmoDn Id+CRG+SLnewcEZQ4HC9ANB1tLCDYdsgwmBCuQH72/ASYGlPME9PcG9QlHJve3N/dIpIdV92b3m/ essw+HgwMHv4haXSnHh/bV//a0tu8G8veN99uGwVZT9mR+fbk8IxAOBuYwkQ0PG+APpkpethhYCn jdXopq7yD/8ET/f/3e/e80/fqMILrxKfv7yCaV+Pz2t/Y6+/QDCH33uOVRPiX3IAFLCvweLhJ++q 0AqAhYCq0CeFW6jCi3SFjkojZrAwLTEy4xD/RsFoMPGwomBkVonxsVG/w34xoLUBILUA11C/8N2x Yfx1bOHQvvCqkBE7IEHcAG48f1Dr0twAPqJwoJA63Z7DMY5K4ILAEiiHt7hww1wAjlQyLjE0qUB9 4D2FgGS+EOsgpqaORX19A7vgq1AAAAAfAEIAAQAAABgAAABGAGEAbgAsACAAWgBoAGkAagB1AFgA AAAfAGUAAQAAACoAAAB6AGgAaQBqAHUAeAAuAGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAA AB8AZAABAAAACgAAAFMATQBUAFAAAAAAAAIBQQABAAAAZAAAAAAAAACBKx+kvqMQGZ1uAN0BD1QC AAAAgEYAYQBuACwAIABaAGgAaQBqAHUAWAAAAFMATQBUAFAAAAB6AGgAaQBqAHUAeAAuAGYAYQBu AEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAfAAJdAQAAACoAAAB6AGgAaQBqAHUAeAAuAGYAYQBuAEAA aQBuAHQAZQBsAC4AYwBvAG0AAAAAAB8A5V8BAAAAMgAAAHMAaQBwADoAegBoAGkAagB1AHgALgBm AGEAbgBAAGkAbgB0AGUAbAAuAGMAbwBtAAAAAAAfABoMAQAAABgAAABGAGEAbgAsACAAWgBoAGkA agB1AFgAAAAfAB8MAQAAACoAAAB6AGgAaQBqAHUAeAAuAGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBv AG0AAAAAAB8AHgwBAAAACgAAAFMATQBUAFAAAAAAAAIBGQwBAAAAZAAAAAAAAACBKx+kvqMQGZ1u AN0BD1QCAAAAgEYAYQBuACwAIABaAGgAaQBqAHUAWAAAAFMATQBUAFAAAAB6AGgAaQBqAHUAeAAu AGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAfAAFdAQAAACoAAAB6AGgAaQBqAHUAeAAuAGYA YQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAAAB8A+D8BAAAAGAAAAEYAYQBuACwAIABaAGgAaQBq AHUAWAAAAB8AI0ABAAAAKgAAAHoAaABpAGoAdQB4AC4AZgBhAG4AQABpAG4AdABlAGwALgBjAG8A bQAAAAAAHwAiQAEAAAAKAAAAUwBNAFQAUAAAAAAAAgH5PwEAAABkAAAAAAAAAIErH6S+oxAZnW4A 3QEPVAIAAACARgBhAG4ALAAgAFoAaABpAGoAdQBYAAAAUwBNAFQAUAAAAHoAaABpAGoAdQB4AC4A ZgBhAG4AQABpAG4AdABlAGwALgBjAG8AbQAAAB8ACV0BAAAAKgAAAHoAaABpAGoAdQB4AC4AZgBh AG4AQABpAG4AdABlAGwALgBjAG8AbQAAAAAACwBAOgEAAAAfABoAAQAAABIAAABJAFAATQAuAE4A bwB0AGUAAAAAAAMA8T8JBAAACwBAOgEAAAADAP0/5AQAAAIBCzABAAAAEAAAAPqjSaHoJmFJvfAZ +BKQessDABcAAQAAAEAAOQAAE+CaGCjVAUAACDBQcTybGCjVAR8AAICGAwIAAAAAAMAAAAAAAABG AQAAAB4AAABhAGMAYwBlAHAAdABsAGEAbgBnAHUAYQBnAGUAAAAAAAEAAAAMAAAAZQBuAC0AVQBT AAAAHwA3AAEAAADGAAAAWwBlAGQAawAyAC0AcABsAGEAdABmAG8AcgBtACAAcABhAHQAYwBoACAA MQAvADIAIABWADIAXQAgAFAAbABhAHQAZgBvAHIAbQAvAEkAbgB0AGUAbAA6AEEAZABkACAARwBl AG4AQgBpAG8AcwBJAGQAIABpAG4AdABvACAAZQBkAGsAMgAtAHAAbABhAHQAZgBvAHIAbQBzAC8A UABsAGEAdABmAG8AcgBtAC8ASQBuAHQAZQBsAC8AVABvAG8AbABzAAAAAAAfAD0AAQAAAAIAAAAA AAAAAwA2AAAAAAACAXEAAQAAABYAAAAB1SgYmf5iO+bJZ61FKau4sobN8LZzAAAfAHAAAQAAAMYA AABbAGUAZABrADIALQBwAGwAYQB0AGYAbwByAG0AIABwAGEAdABjAGgAIAAxAC8AMgAgAFYAMgBd ACAAUABsAGEAdABmAG8AcgBtAC8ASQBuAHQAZQBsADoAQQBkAGQAIABHAGUAbgBCAGkAbwBzAEkA ZAAgAGkAbgB0AG8AIABlAGQAawAyAC0AcABsAGEAdABmAG8AcgBtAHMALwBQAGwAYQB0AGYAbwBy AG0ALwBJAG4AdABlAGwALwBUAG8AbwBsAHMAAAAAAB8ANRABAAAAkAAAADwARgBBAEQAMABEADcA RQAwAEEARQAwAEYAQQA1ADQARAA5ADgANwBGADYARQA3ADIANAAzADUAQwBBAEYARAA1ADAAQQBG ADgANAAyADcAMQBAAFMASABTAE0AUwBYADEAMAAxAC4AYwBjAHIALgBjAG8AcgBwAC4AaQBuAHQA ZQBsAC4AYwBvAG0APgAAAAMA3j+fTgAAQAAHMBBkOZsYKNUBAgELAAEAAAAQAAAA+qNJoegmYUm9 8Bn4EpB6ywMAJgAAAAAAAgFHAAEAAAAyAAAAYz1VUzthPU1DSTtwPUludGVsO2w9U0hTTVNYMTAx LTE5MDYyMTEwMDM0MlotOTIyMQAAAAIBEDABAAAARgAAAAAAAAAmd705O+w4SaSmFT3LpXtCBwD6 0Nfgrg+lTZh/bnJDXK/VAAAARBFeAACmk2g2iHZsS6dK0+tHmkxkAAAJVI/CAAAAAB8A+j8BAAAA GAAAAEYAYQBuACwAIABaAGgAaQBqAHUAWAAAAAMACVkBAAAAQAAAgAggBgAAAAAAwAAAAAAAAEYA AAAAv4UAABDzWZoYKNUBCwAAgAggBgAAAAAAwAAAAAAAAEYAAAAAgoUAAAAAAAADAACACCAGAAAA AADAAAAAAAAARgAAAADrhQAACQQAAB8AAICGAwIAAAAAAMAAAAAAAABGAQAAABgAAABkAGwAcAAt AHAAcgBvAGQAdQBjAHQAAAABAAAAGgAAAGQAbABwAGUALQB3AGkAbgBkAG8AdwBzAAAAAAAfAACA hgMCAAAAAADAAAAAAAAARgEAAAAYAAAAZABsAHAALQB2AGUAcgBzAGkAbwBuAAAAAQAAABYAAAAx ADEALgAwAC4ANgAwADAALgA3AAAAAAAfAACAhgMCAAAAAADAAAAAAAAARgEAAAAaAAAAZABsAHAA LQByAGUAYQBjAHQAaQBvAG4AAAAAAAEAAAAUAAAAbgBvAC0AYQBjAHQAaQBvAG4AAAADAA00/T8A AB8AAICGAwIAAAAAAMAAAAAAAABGAQAAACAAAAB4AC0AbQBzAC0AaABhAHMALQBhAHQAdABhAGMA aAAAAAEAAAACAAAAAAAAAB8AAICGAwIAAAAAAMAAAAAAAABGAQAAACIAAAB4AC0AbwByAGkAZwBp AG4AYQB0AGkAbgBnAC0AaQBwAAAAAAABAAAAIAAAAFsAMQAwAC4AMgAzADkALgAxADIANwAuADQA MABdAAAA2L8= --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF84271SHSMSX101ccrcor_--