From nobody Mon Apr 29 11:55:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+40841+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+40841+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558054640; cv=none; d=zoho.com; s=zohoarc; b=FM4RS8TKm4+Bmmzz7k60iwgelvVyydILaffHS/oR7LNg5RXDmhx0wdVP/zoXoEVrkrA+bB90QKPNqs0uBacBkYvzqTOGKLOrazZDpsihJWKA8A5R1ASedIqR2fQDL8k03Cx1SKrrdPjrdBqNYbMxGQJQEOsWUuYHUFbwQOmgxgU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558054640; h=Content-Type:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To:ARC-Authentication-Results; bh=Uwq/QRcVoJOiTOfULlf0VyZRRCChNxdhipoAdGafu78=; b=frqYvilDsTti2kvGsdtMIzoqcn0XAJrVugGKZZNOTNeLDBiUqIGilXdyMFtVwSOGFS7uniN7+7TpMJIIq73iZvBqsgi6pUwePhs6XF9CJ5ouVwgkScnV2kJ0KfX6TTjXOwJAYMqlSxdYIPTKFyDBxUBZGaTIIz45oDUWfNqxtTU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+40841+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1558054640574723.6283311656829; Thu, 16 May 2019 17:57:20 -0700 (PDT) Return-Path: X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by groups.io with SMTP; Thu, 16 May 2019 17:57:19 -0700 X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False X-Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 May 2019 17:57:18 -0700 X-ExtLoop1: 1 X-Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga003.jf.intel.com with ESMTP; 16 May 2019 17:57:18 -0700 X-Received: from fmsmsx120.amr.corp.intel.com (10.18.124.208) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 16 May 2019 17:57:17 -0700 X-Received: from shsmsx105.ccr.corp.intel.com (10.239.4.158) by fmsmsx120.amr.corp.intel.com (10.18.124.208) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 16 May 2019 17:57:17 -0700 X-Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.129]) by SHSMSX105.ccr.corp.intel.com ([169.254.11.10]) with mapi id 14.03.0415.000; Fri, 17 May 2019 08:57:15 +0800 From: "Fan, ZhijuX" To: "devel@edk2.groups.io" CC: "Gao, Liming" , "Feng, Bob C" Subject: [edk2-devel] [PATCH] BaseTools:Add the FeatureFlagExpression usage to the InfBuildData Thread-Topic: [PATCH] BaseTools:Add the FeatureFlagExpression usage to the InfBuildData Thread-Index: AdUMS3aM6EBGVOuVTu2OsJP6QpeTAw== Date: Fri, 17 May 2019 00:57:14 +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 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,zhijux.fan@intel.com Content-Type: multipart/mixed; boundary="_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF610FDSHSMSX101ccrcor_" Content-Language: en-US DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1558054640; bh=J15/nwY02N0UkDQxi5TypCuOTXzxMS6L6/SUQIvMVEY=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=lt50XIL/68X4p0D55IlVSEQKxfBiRdCzZQxv/tJeNK0q+cigeH7k4YBxbDfnSWakZy4 huQj9VbbvQXcM+SiCl9dgYPwyWSAn49um/fQZdONyF+ANKi4rRbowyAkb/Yh5eEklhLRh Y+1zJbFu/IhG2fY8Q2lMEUUYfuEBa9Al0ws= X-Zoho-Virus-Status: 1 X-ZohoMail-DKIM: pass (identity @groups.io) --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF610FDSHSMSX101ccrcor_ Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1446 FeatureFlagExpression Support in LibraryClasses/Guids/Ppi/Protocols section of INF file. The Pcd value in the expression is from INF or DEC When a FeatureFlagExpression is present,if the expression evaluates to TRUE,then the entry is valid. If the expression evaluates to FALSE,=20 then the EDK II build tools must ignore the entry. This patch is going to add this feature. Cc: Bob Feng Cc: Liming Gao Signed-off-by: Zhiju.Fan --- BaseTools/Source/Python/Common/Expression.py | 2 +- BaseTools/Source/Python/Common/GlobalData.py | 1 + BaseTools/Source/Python/Workspace/InfBuildData.py | 69 ++++++++++++++++++= ++-- .../Source/Python/Workspace/WorkspaceCommon.py | 10 +++- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Sourc= e/Python/Common/Expression.py index 07ca039a9c..31bf0e4b6c 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -43,7 +43,7 @@ ERR_IN_OPERAND =3D 'Macro after IN operator can = only be: $(FAMILY), $(ARC __ValidString =3D re.compile(r'[_a-zA-Z][_0-9a-zA-Z]*$') _ReLabel =3D re.compile('LABEL\((\w+)\)') _ReOffset =3D re.compile('OFFSET_OF\((\w+)\)') -PcdPattern =3D re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*= $') +PcdPattern =3D re.compile(r'^[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]= *$') =20 ## SplitString # Split string to list according double quote diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Sourc= e/Python/Common/GlobalData.py index 79f23c892d..1404e5d7ac 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -18,6 +18,7 @@ gGlobalDefines =3D {} gPlatformDefines =3D {} # PCD name and value pair for fixed at build and feature flag gPlatformPcds =3D {} +gPlatformFinalPcds =3D {} # PCDs with type that are not fixed at build and feature flag gPlatformOtherPcds =3D {} gActivePlatform =3D None diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/= Source/Python/Workspace/InfBuildData.py index e66b7c9832..4b4644b60e 100644 --- a/BaseTools/Source/Python/Workspace/InfBuildData.py +++ b/BaseTools/Source/Python/Workspace/InfBuildData.py @@ -14,6 +14,7 @@ from types import * from .MetaFileParser import * from collections import OrderedDict from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClas= sObject, PcdClassObject +from Common.Expression import ValueExpressionEx, PcdPattern =20 ## Get Protocol value from given packages # @@ -561,6 +562,9 @@ class InfBuildData(ModuleBuildClassObject): Instance =3D Record[1] if Instance: Instance =3D NormPath(Instance, self._Macros) + FeaturePcdExpression =3D self.CheckFeatureFlagPcd(Instance) + if not FeaturePcdExpression: + continue RetVal[Lib] =3D Instance else: RetVal[Lib] =3D None @@ -591,6 +595,10 @@ class InfBuildData(ModuleBuildClassObject): self._ProtocolComments =3D OrderedDict() RecordList =3D self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self.= _Platform] for Record in RecordList: + if Record[1]: + FeaturePcdExpression =3D self.CheckFeatureFlagPcd(Record[1= ]) + if not FeaturePcdExpression: + continue CName =3D Record[0] Value =3D _ProtocolValue(CName, self.Packages, self.MetaFile.P= ath) if Value is None: @@ -615,6 +623,10 @@ class InfBuildData(ModuleBuildClassObject): self._PpiComments =3D OrderedDict() RecordList =3D self._RawData[MODEL_EFI_PPI, self._Arch, self._Plat= form] for Record in RecordList: + if Record[1]: + FeaturePcdExpression =3D self.CheckFeatureFlagPcd(Record[1= ]) + if not FeaturePcdExpression: + continue CName =3D Record[0] Value =3D _PpiValue(CName, self.Packages, self.MetaFile.Path) if Value is None: @@ -638,7 +650,12 @@ class InfBuildData(ModuleBuildClassObject): RetVal =3D OrderedDict() self._GuidComments =3D OrderedDict() RecordList =3D self._RawData[MODEL_EFI_GUID, self._Arch, self._Pla= tform] + RetVal.update(self.GetGuidsUsedByPcd()) for Record in RecordList: + if Record[1]: + FeaturePcdExpression =3D self.CheckFeatureFlagPcd(Record[1= ]) + if not FeaturePcdExpression: + continue CName =3D Record[0] Value =3D GuidValue(CName, self.Packages, self.MetaFile.Path) if Value is None: @@ -825,6 +842,13 @@ class InfBuildData(ModuleBuildClassObject): self.Pcds return self._GuidsUsedByPcd =20 + @cached_class_function + def GetGuidDict(self): + GuidDict =3D OrderedDict() + for Package in self.Packages: + GuidDict.update(Package.Guids) + return GuidDict + ## Retrieve PCD for given type def _GetPcd(self, Type): Pcds =3D OrderedDict() @@ -835,14 +859,13 @@ class InfBuildData(ModuleBuildClassObject): PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] =3D (Setting= , LineNo) PcdList.append((PcdCName, TokenSpaceGuid)) # get the guid value - if TokenSpaceGuid not in self.Guids: + if TokenSpaceGuid not in self._GuidsUsedByPcd: Value =3D GuidValue(TokenSpaceGuid, self.Packages, self.Me= taFile.Path) if Value is None: PackageList =3D "\n\t".join(str(P) for P in self.Packa= ges) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Value of Guid [%s] is not found under= [Guids] section in" % TokenSpaceGuid, ExtraData=3DPackageList, File=3Dself.M= etaFile, Line=3DLineNo) - self.Guids[TokenSpaceGuid] =3D Value self._GuidsUsedByPcd[TokenSpaceGuid] =3D Value CommentRecords =3D self._RawData[MODEL_META_DATA_COMMENT, self= ._Arch, self._Platform, Id] Comments =3D [] @@ -851,7 +874,6 @@ class InfBuildData(ModuleBuildClassObject): self._PcdComments[TokenSpaceGuid, PcdCName] =3D Comments =20 # resolve PCD type, value, datum info, etc. by getting its definit= ion from package - _GuidDict =3D self.Guids.copy() for PcdCName, TokenSpaceGuid in PcdList: PcdRealName =3D PcdCName Setting, LineNo =3D PcdDict[self._Arch, self.Platform, PcdCNam= e, TokenSpaceGuid] @@ -869,7 +891,7 @@ class InfBuildData(ModuleBuildClassObject): '', {}, False, - self.Guids[TokenSpaceGuid] + self.GetGuidDict()[TokenSpaceGuid] ) if Type =3D=3D MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]: # Patch PCD: TokenSpace.PcdCName|Value|Offset @@ -905,7 +927,6 @@ class InfBuildData(ModuleBuildClassObject): # # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE,= TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX # - _GuidDict.update(Package.Guids) PcdType =3D self._PCD_TYPE_STRING_[Type] if Type =3D=3D MODEL_PCD_DYNAMIC: Pcd.Pending =3D True @@ -997,7 +1018,7 @@ class InfBuildData(ModuleBuildClassObject): Pcd.DefaultValue =3D PcdInPackage.DefaultValue else: try: - Pcd.DefaultValue =3D ValueExpressionEx(Pcd.Def= aultValue, Pcd.DatumType, _GuidDict)(True) + Pcd.DefaultValue =3D ValueExpressionEx(Pcd.Def= aultValue, Pcd.DatumType, self.GetGuidDict())(True) except BadExpression as Value: EdkLogger.error('Parser', FORMAT_INVALID, 'PCD= [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, V= alue), File=3Dself.MetaFile, Line=3DL= ineNo) @@ -1020,3 +1041,39 @@ class InfBuildData(ModuleBuildClassObject): if (self.Binaries and not self.Sources) or GlobalData.gIgnoreSourc= e: return True return False + + def CheckFeatureFlagPcd(self,Instance): + Pcds =3D GlobalData.gPlatformFinalPcds[self.Arch].copy() + if PcdPattern.search(Instance): + PcdTuple =3D tuple(Instance.split('.')[::-1]) + if PcdTuple in self.Pcds: + if not (self.Pcds[PcdTuple].Type =3D=3D 'FeatureFlag' or s= elf.Pcds[PcdTuple].Type =3D=3D 'FixedAtBuild') and Instance not in Pcds: + EdkLogger.error('build', FORMAT_INVALID, + "\nit must be defined in a [PcdsFeatur= eFlag] or [PcdsFixedAtBuild] section of Dsc or Dec file or [FeaturePcd] or = [FixedPcd] of Inf file", + File=3Dstr(self), ExtraData=3DInstance) + Pcds[Instance] =3D self.Pcds[PcdTuple].DefaultValue + if Instance in Pcds: + if Pcds[Instance] =3D=3D '0': + return False + elif Pcds[Instance] =3D=3D '1': + return True + try: + Value =3D ValueExpression(Instance, Pcds)() + if Value =3D=3D True: + return True + return False + except: + EdkLogger.warn('build', FORMAT_INVALID,"The FeatureFlagExp= ression cannot be evaluated", File=3Dstr(self), ExtraData=3DInstance) + return False + else: + for Name, Guid in self.Pcds: + if self.Pcds[(Name, Guid)].Type =3D=3D 'FeatureFlag' or se= lf.Pcds[(Name, Guid)].Type =3D=3D 'FixedAtBuild': + Pcds['%s.%s' % (Guid, Name)] =3D self.Pcds[(Name, Guid= )].DefaultValue + try: + Value =3D ValueExpression(Instance, Pcds)() + if Value =3D=3D True: + return True + return False + except: + EdkLogger.warn('build', FORMAT_INVALID, "The FeatureFlagEx= pression cannot be evaluated", File=3Dstr(self), ExtraData=3DInstance) + return False diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseToo= ls/Source/Python/Workspace/WorkspaceCommon.py index 0cc83110ef..3ca142bc19 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py @@ -38,8 +38,9 @@ def GetPackageList(Platform, BuildDatabase, Arch, Target,= Toolchain): for ModuleFile in Platform.Modules: Data =3D BuildDatabase[ModuleFile, Arch, Target, Toolchain] PkgSet.update(Data.Packages) - for Lib in GetLiabraryInstances(Data, Platform, BuildDatabase, Arc= h, Target, Toolchain): - PkgSet.update(Lib.Packages) + for ModuleFile in Platform.LibraryInstances: + Data =3D BuildDatabase[ModuleFile, Arch, Target, Toolchain] + PkgSet.update(Data.Packages) return list(PkgSet) =20 ## Get all declared PCD from platform for specified arch, target and toolc= hain @@ -71,6 +72,11 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target= , Toolchain, additionalP break if (PcdCName, PcdTokenName) not in DecPcds: DecPcds[PcdCName, PcdTokenName] =3D Pkg.Pcds[Pcd] + if not GlobalData.gPlatformFinalPcds.get(Arch): + GlobalData.gPlatformFinalPcds[Arch] =3D OrderedDict() + for Name,Guid in DecPcds: + if DecPcds[Name,Guid].Type =3D=3D 'FeatureFlag' or DecPcds[Name,Gu= id].Type =3D=3D 'FixedAtBuild': + GlobalData.gPlatformFinalPcds[Arch]['%s.%s'%(Guid,Name)]=3DDec= Pcds[Name,Guid].DefaultValue return DecPcds, GuidDict =20 ## Get all dependent libraries for a module --=20 2.14.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#40841): https://edk2.groups.io/g/devel/message/40841 Mute This Topic: https://groups.io/mt/31650344/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF610FDSHSMSX101ccrcor_ Content-Disposition: attachment; filename="winmail.dat" Content-Transfer-Encoding: base64 Content-Type: application/ms-tnef; name="winmail.dat" eJ8+It89AQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAEJgAEAIQAAAEU1NDYwMDY2 NjI4Qzc4NDVBRjhBQzQ1RjhGNDIyMTk2ABMHAQ2ABAACAAAAAgACAAEFgAMADgAAAOMHBQARAAAA OQAOAAUATAEBIIADAA4AAADjBwUAEQAAADkADgAFAEwBAQiABwAYAAAASVBNLk1pY3Jvc29mdCBN YWlsLk5vdGUAMQgBBIABAEoAAABbUEFUQ0hdIEJhc2VUb29sczpBZGQgdGhlIEZlYXR1cmVGbGFn RXhwcmVzc2lvbiB1c2FnZSB0byB0aGUgSW5mQnVpbGREYXRhAE4aAQuAAQAhAAAARTU0NjAwNjY2 MjhDNzg0NUFGOEFDNDVGOEY0MjIxOTYAEwcBA5AGACwcAAAzAAAAAgF/AAEAAABIAAAAPEZBRDBE N0UwQUUwRkE1NEQ5ODdGNkU3MjQzNUNBRkQ1MEFGNjEwRkRAU0hTTVNYMTAxLmNjci5jb3JwLmlu dGVsLmNvbT4ACwAfDgEAAAACAQkQAQAAAFQSAABQEgAACTYAAExaRnUWEpF2YQAKZmJpZAQAAGNj wHBnMTI1MgD+A0PwdGV4dAH3AqQD4wIABGNoCsBzZXQwIO8HbQKDAFARTTIKgAa0AoCWfQqACMg7 CWIxOQ7AvwnDFnIKMhZxAoAVYioJsHMJ8ASQYXQFsg5QA2Bzom8BgCBFeBHBbhgwXQZSdgSQF7YC EHIAwHR9CFBuGjEQIAXABaAbZGSaIANSIBAiF7JcdgiQ5HdrC4BkNR1TBPAHQA0XcDAKcRfyYmtt awZzAZAAICBCTV9C4EVHSU59CvwB8QvxER+wWjpoAkBwczrALy9idWd6AxALYCQudAcwbm8FoWUu AQWwZy9zaG93X0EiUS5jZ2k/DdA9QDE0NDZcbAuAZTMKgSUURmUYgAhwZUa1C2BnGXBwCXAEEGkC IFEGAHVwcAkRIAuAIIhMaWIYcHJ5QwtgYwQQB5AvR3UN0CjAUPxwaSkwA2AYkAjhDgAlFF0SAGMi 4CcRGTAgICBGLxxwAxAjYBJAaBngUGPdHGB2B0AKUCeydCvhEDAfJrcEABx0KzIFsURFQ80lBVcr 4AOgYSAl7y2GsyayCfB0LAaQLN5lLFIfGIAHkCUFGJASQFJVRf4sLOEsxQIwKEAtwixRDdA9K7BJ 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 AQAAABgAAABGAGEAbgAsACAAWgBoAGkAagB1AFgAAAAfAB8MAQAAACoAAAB6AGgAaQBqAHUAeAAu AGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAAAB8AHgwBAAAACgAAAFMATQBUAFAAAAAAAAIB GQwBAAAAZAAAAAAAAACBKx+kvqMQGZ1uAN0BD1QCAAAAgEYAYQBuACwAIABaAGgAaQBqAHUAWAAA AFMATQBUAFAAAAB6AGgAaQBqAHUAeAAuAGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAfAAFd AQAAACoAAAB6AGgAaQBqAHUAeAAuAGYAYQBuAEAAaQBuAHQAZQBsAC4AYwBvAG0AAAAAAB8A+D8B AAAAGAAAAEYAYQBuACwAIABaAGgAaQBqAHUAWAAAAB8AI0ABAAAAKgAAAHoAaABpAGoAdQB4AC4A ZgBhAG4AQABpAG4AdABlAGwALgBjAG8AbQAAAAAAHwAiQAEAAAAKAAAAUwBNAFQAUAAAAAAAAgH5 PwEAAABkAAAAAAAAAIErH6S+oxAZnW4A3QEPVAIAAACARgBhAG4ALAAgAFoAaABpAGoAdQBYAAAA UwBNAFQAUAAAAHoAaABpAGoAdQB4AC4AZgBhAG4AQABpAG4AdABlAGwALgBjAG8AbQAAAB8ACV0B AAAAKgAAAHoAaABpAGoAdQB4AC4AZgBhAG4AQABpAG4AdABlAGwALgBjAG8AbQAAAAAACwBAOgEA AAAfABoAAQAAABIAAABJAFAATQAuAE4AbwB0AGUAAAAAAAMA8T8JBAAACwBAOgEAAAADAP0/5AQA AAIBCzABAAAAEAAAAOVGAGZijHhFr4rEX49CIZYDABcAAQAAAEAAOQAAET93SwzVAUAACDAo6qR3 SwzVAR8AAICGAwIAAAAAAMAAAAAAAABGAQAAAB4AAABhAGMAYwBlAHAAdABsAGEAbgBnAHUAYQBn AGUAAAAAAAEAAAAMAAAAZQBuAC0AVQBTAAAAHwA3AAEAAACUAAAAWwBQAEEAVABDAEgAXQAgAEIA YQBzAGUAVABvAG8AbABzADoAQQBkAGQAIAB0AGgAZQAgAEYAZQBhAHQAdQByAGUARgBsAGEAZwBF AHgAcAByAGUAcwBzAGkAbwBuACAAdQBzAGEAZwBlACAAdABvACAAdABoAGUAIABJAG4AZgBCAHUA aQBsAGQARABhAHQAYQAAAB8APQABAAAAAgAAAAAAAAADADYAAAAAAAIBcQABAAAAFgAAAAHVDEt2 jOhARlTrlU7tjrCT+kKXkwMAAB8AcAABAAAAlAAAAFsAUABBAFQAQwBIAF0AIABCAGEAcwBlAFQA bwBvAGwAcwA6AEEAZABkACAAdABoAGUAIABGAGUAYQB0AHUAcgBlAEYAbABhAGcARQB4AHAAcgBl AHMAcwBpAG8AbgAgAHUAcwBhAGcAZQAgAHQAbwAgAHQAaABlACAASQBuAGYAQgB1AGkAbABkAEQA YQB0AGEAAAAfADUQAQAAAJAAAAA8AEYAQQBEADAARAA3AEUAMABBAEUAMABGAEEANQA0AEQAOQA4 ADcARgA2AEUANwAyADQAMwA1AEMAQQBGAEQANQAwAEEARgA2ADEAMABGAEQAQABTAEgAUwBNAFMA WAAxADAAMQAuAGMAYwByAC4AYwBvAHIAcAAuAGkAbgB0AGUAbAAuAGMAbwBtAD4AAAADAN4/n04A AEAABzDuE5F3SwzVAQIBCwABAAAAEAAAAOVGAGZijHhFr4rEX49CIZYDACYAAAAAAAIBRwABAAAA MwAAAGM9VVM7YT1NQ0k7cD1JbnRlbDtsPVNIU01TWDEwMS0xOTA1MTcwMDU3MTRaLTE1OTA1AAAC ARAwAQAAAEYAAAAAAAAAJne9OTvsOEmkphU9y6V7QgcA+tDX4K4PpU2Yf25yQ1yv1QAAAEQRXgAA ppNoNoh2bEunStPrR5pMZAAACVSPdwAAAAAfAPo/AQAAABgAAABGAGEAbgAsACAAWgBoAGkAagB1 AFgAAAADAAlZAQAAAEAAAIAIIAYAAAAAAMAAAAAAAABGAAAAAL+FAABAVpJ2SwzVAQsAAIAIIAYA AAAAAMAAAAAAAABGAAAAAIKFAAAAAAAAHwAAgIYDAgAAAAAAwAAAAAAAAEYBAAAAGAAAAGQAbABw AC0AcAByAG8AZAB1AGMAdAAAAAEAAAAaAAAAZABsAHAAZQAtAHcAaQBuAGQAbwB3AHMAAAAAAB8A AICGAwIAAAAAAMAAAAAAAABGAQAAABgAAABkAGwAcAAtAHYAZQByAHMAaQBvAG4AAAABAAAAFgAA ADEAMQAuADAALgA2ADAAMAAuADcAAAAAAB8AAICGAwIAAAAAAMAAAAAAAABGAQAAABoAAABkAGwA cAAtAHIAZQBhAGMAdABpAG8AbgAAAAAAAQAAABQAAABuAG8ALQBhAGMAdABpAG8AbgAAAAMADTT9 PwAAHwAAgIYDAgAAAAAAwAAAAAAAAEYBAAAAIAAAAHgALQBtAHMALQBoAGEAcwAtAGEAdAB0AGEA YwBoAAAAAQAAAAIAAAAAAAAAHwAAgIYDAgAAAAAAwAAAAAAAAEYBAAAAIgAAAHgALQBvAHIAaQBn AGkAbgBhAHQAaQBuAGcALQBpAHAAAAAAAAEAAAAgAAAAWwAxADAALgAyADMAOQAuADEAMgA3AC4A NAAwAF0AAADagA== --_000_FAD0D7E0AE0FA54D987F6E72435CAFD50AF610FDSHSMSX101ccrcor_--