diff --git a/src/Hl7.Fhir.Base/ElementModel/Adapters/ScopedNodeToTypedElementAdapter.cs b/src/Hl7.Fhir.Base/ElementModel/Adapters/ScopedNodeToTypedElementAdapter.cs deleted file mode 100644 index 3d0814c177..0000000000 --- a/src/Hl7.Fhir.Base/ElementModel/Adapters/ScopedNodeToTypedElementAdapter.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023, Firely (info@fire.ly) and contributors - * See the file CONTRIBUTORS for details. - * - * This file is licensed under the BSD 3-Clause license - * available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE - */ - -#nullable enable - -using Hl7.Fhir.Specification; -using System.Collections.Generic; -using System.Linq; - -namespace Hl7.Fhir.ElementModel -{ - /// - /// An adapter from to . - /// - /// Be careful, this adapter does not implement the and - /// property. - /// - internal class ScopedNodeToTypedElementAdapter : ITypedElement - { - private readonly IScopedNode _adaptee; - - public ScopedNodeToTypedElementAdapter(IScopedNode adaptee) - { - _adaptee = adaptee; - } - - public string Location => throw new System.NotImplementedException(); - - public IElementDefinitionSummary Definition => throw new System.NotImplementedException(); - - public string Name => _adaptee.Name; - - public string InstanceType => _adaptee.InstanceType; - - public object Value => _adaptee.Value; - - public IEnumerable Children(string? name = null) => - _adaptee.Children(name).Select(n => new ScopedNodeToTypedElementAdapter(n)); - } -} - -#nullable restore \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs b/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs index b228dcfb62..b133dbadb9 100644 --- a/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs +++ b/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs @@ -108,13 +108,6 @@ public static IReadOnlyCollection ChildDefinitions(th public static ScopedNode ToScopedNode(this ITypedElement node) => node as ScopedNode ?? new ScopedNode(node); - - /// - /// Convert a to a . - /// - /// An - /// - internal static IScopedNode AsScopedNode(this ITypedElement node) => ToScopedNode(node); } } diff --git a/src/Hl7.Fhir.Base/ElementModel/IBaseElementNavigator.cs b/src/Hl7.Fhir.Base/ElementModel/IBaseElementNavigator.cs index 988ca77f8d..bf8bf0b69b 100644 --- a/src/Hl7.Fhir.Base/ElementModel/IBaseElementNavigator.cs +++ b/src/Hl7.Fhir.Base/ElementModel/IBaseElementNavigator.cs @@ -14,7 +14,7 @@ namespace Hl7.Fhir.ElementModel { /// - /// The base interface for and ."/> + /// The base interface for ."/> /// /// [Obsolete("WARNING! Intended for internal API usage exclusively, this interface ideally should be kept internal. " + diff --git a/src/Hl7.Fhir.Base/ElementModel/IScopedNode.cs b/src/Hl7.Fhir.Base/ElementModel/IScopedNode.cs deleted file mode 100644 index fdd8fab486..0000000000 --- a/src/Hl7.Fhir.Base/ElementModel/IScopedNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023, Firely (info@fire.ly) and contributors - * See the file CONTRIBUTORS for details. - * - * This file is licensed under the BSD 3-Clause license - * available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE - */ - -#nullable enable - -namespace Hl7.Fhir.ElementModel -{ - /// - /// An element within a tree of typed FHIR data with also a parent element. - /// - /// - /// This interface represents FHIR data as a tree of elements, including type information either present in - /// the instance or derived from fully aware of the FHIR definitions and types - /// -#pragma warning disable CS0618 // Type or member is obsolete - internal interface IScopedNode : IBaseElementNavigator -#pragma warning restore CS0618 // Type or member is obsolete - { - /// - /// The parent node of this node, or null if this is the root node. - /// - IScopedNode? Parent { get; } - } -} - -#nullable restore \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/ElementModel/IScopedNodeExtensions.cs b/src/Hl7.Fhir.Base/ElementModel/IScopedNodeExtensions.cs deleted file mode 100644 index 09fa7e6641..0000000000 --- a/src/Hl7.Fhir.Base/ElementModel/IScopedNodeExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023, Firely (info@fire.ly) and contributors - * See the file CONTRIBUTORS for details. - * - * This file is licensed under the BSD 3-Clause license - * available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE - */ - -#nullable enable - - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Hl7.Fhir.ElementModel -{ - internal static class IScopedNodeExtensions - { - /// - /// Converts a to a . - /// - /// An node - /// An implementation of - /// Be careful when using this method, the returned does not implement - /// the methods and . - /// - [Obsolete("WARNING! For internal API use only. Turning an IScopedNode into an ITypedElement will cause problems for" + - "Location and Definitions. Those properties are not implemented using this method and can cause problems " + - "elsewhere. Please don't use this method unless you know what you are doing.")] - public static ITypedElement AsTypedElement(this IScopedNode node) => - node is ITypedElement ite ? ite : new ScopedNodeToTypedElementAdapter(node); - - /// - /// Returns the parent resource of this node, or null if this node is not part of a resource. - /// - /// - /// - /// - public static IEnumerable Children(this IEnumerable nodes, string? name = null) => - nodes.SelectMany(n => n.Children(name)); - } -} - -#nullable restore \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/ElementModel/ScopedNode.cs b/src/Hl7.Fhir.Base/ElementModel/ScopedNode.cs index 6373448fa9..7c7390a32e 100644 --- a/src/Hl7.Fhir.Base/ElementModel/ScopedNode.cs +++ b/src/Hl7.Fhir.Base/ElementModel/ScopedNode.cs @@ -16,7 +16,7 @@ namespace Hl7.Fhir.ElementModel { - public class ScopedNode : ITypedElement, IScopedNode, IAnnotated, IExceptionSource + public class ScopedNode : ITypedElement, IAnnotated, IExceptionSource { private class Cache { @@ -32,7 +32,6 @@ private class Cache private readonly Cache _cache = new(); public readonly ITypedElement Current; - private readonly ScopedNode? _parent; public ScopedNode(ITypedElement wrapped, string? instanceUri = null) { @@ -46,7 +45,6 @@ public ScopedNode(ITypedElement wrapped, string? instanceUri = null) private ScopedNode(ScopedNode parentNode, ScopedNode? parentResource, ITypedElement wrapped, string? fullUrl) { Current = wrapped; - _parent = parentNode; ExceptionHandler = parentNode.ExceptionHandler; ParentResource = parentNode.AtResource ? parentNode : parentResource; @@ -230,24 +228,11 @@ private set } } - /// - - - IScopedNode? IScopedNode.Parent => _parent; - /// public IEnumerable Annotations(Type type) => type == typeof(ScopedNode) ? (new[] { this }) : Current.Annotations(type); - private IEnumerable childrenInternal(string? name = null) => - Current.Children(name).Select(c => new ScopedNode(this, ParentResource, c, _fullUrl)); - /// public IEnumerable Children(string? name = null) => - childrenInternal(name); - - IEnumerable IBaseElementNavigator.Children(string? name) => - childrenInternal(name); + Current.Children(name).Select(c => new ScopedNode(this, ParentResource, c, _fullUrl)); } } - -#nullable restore \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/ElementModel/TypedElementParseExtensions.cs b/src/Hl7.Fhir.Base/ElementModel/TypedElementParseExtensions.cs index 495c2ef9ef..bf071e5e5c 100644 --- a/src/Hl7.Fhir.Base/ElementModel/TypedElementParseExtensions.cs +++ b/src/Hl7.Fhir.Base/ElementModel/TypedElementParseExtensions.cs @@ -8,6 +8,7 @@ using Hl7.Fhir.Model; using Hl7.Fhir.Support.Poco; +using System; using System.Collections.Generic; using System.Linq; @@ -15,7 +16,7 @@ namespace Hl7.Fhir.ElementModel { public static class TypedElementParseExtensions { - # region ParseBindable + #region ParseBindable /// /// Parses a bindeable type (code, Coding, CodeableConcept, Quantity, string, uri) into a FHIR coded datatype. /// Extensions will be parsed from the 'value' of the (simple) extension. @@ -32,37 +33,22 @@ public static class TypedElementParseExtensions /// 'string' => code /// 'uri' => code /// - public static Element ParseBindable(this ITypedElement instance) => instance.parseBindable(); - - /// - /// Parses a bindeable type (code, Coding, CodeableConcept, Quantity, string, uri) into a FHIR coded datatype. - /// Extensions will be parsed from the 'value' of the (simple) extension. - /// - /// - /// An Element of a coded type (code, Coding or CodeableConcept) dependin on the instance type, - /// or null if no bindable instance data was found - /// The instance type is mapped to a codable type as follows: - /// 'code' => code - /// 'Coding' => Coding - /// 'CodeableConcept' => CodeableConcept - /// 'Quantity' => Coding - /// 'Extension' => depends on value[x] - /// 'string' => code - /// 'uri' => code - /// - internal static Element ParseBindable(this IScopedNode instance) => instance.parseBindable(); - + public static Element ParseBindable(this ITypedElement instance) #pragma warning disable CS0618 // Type or member is obsolete - private static Element parseBindable(this IBaseElementNavigator instance) where T : IBaseElementNavigator + => instance.ParseBindableInternal(); #pragma warning restore CS0618 // Type or member is obsolete + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static Element ParseBindableInternal(this IBaseElementNavigator instance) where T : IBaseElementNavigator { return instance.InstanceType switch { - FhirTypeConstants.CODE => instance.parsePrimitive(), - FhirTypeConstants.STRING => new Code(instance.parsePrimitive()?.Value), - FhirTypeConstants.URI => new Code(instance.parsePrimitive()?.Value), - FhirTypeConstants.CODING => instance.parseCoding(), - FhirTypeConstants.CODEABLE_CONCEPT => instance.parseCodeableConcept(), + FhirTypeConstants.CODE => instance.ParsePrimitiveInternal(), + FhirTypeConstants.STRING => new Code(instance.ParsePrimitiveInternal()?.Value), + FhirTypeConstants.URI => new Code(instance.ParsePrimitiveInternal()?.Value), + FhirTypeConstants.CODING => instance.ParseCodingInternal(), + FhirTypeConstants.CODEABLE_CONCEPT => instance.ParseCodeableConceptInternal(), FhirTypeConstants.QUANTITY => parseQuantity(), FhirTypeConstants.EXTENSION => parseExtension(), _ => null, @@ -71,7 +57,7 @@ private static Element parseBindable(this IBaseElementNavigator instance) Coding parseQuantity() { var newCoding = new Coding(); - var q = instance.parseQuantity(); + var q = instance.ParseQuantityInternal(); newCoding.Code = q.Code; newCoding.System = q.System ?? "http://unitsofmeasure.org"; return newCoding; @@ -79,19 +65,20 @@ Coding parseQuantity() Element parseExtension() { var valueChild = instance.Children("value").FirstOrDefault(); - return valueChild?.parseBindable(); + return valueChild?.ParseBindableInternal(); } } #endregion #region ParseQuantity - public static Model.Quantity ParseQuantity(this ITypedElement instance) => parseQuantity(instance); - - internal static Model.Quantity ParseQuantity(this IScopedNode instance) => parseQuantity(instance); - + public static Model.Quantity ParseQuantity(this ITypedElement instance) #pragma warning disable CS0618 // Type or member is obsolete - private static Quantity parseQuantity(this IBaseElementNavigator instance) where T : IBaseElementNavigator + => ParseQuantityInternal(instance); #pragma warning restore CS0618 // Type or member is obsolete + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static Quantity ParseQuantityInternal(this IBaseElementNavigator instance) where T : IBaseElementNavigator { var newQuantity = new Quantity { @@ -111,26 +98,27 @@ private static Quantity parseQuantity(this IBaseElementNavigator instance) #region ParsePrimitive public static T ParsePrimitive(this ITypedElement instance) where T : PrimitiveType, new() - => parsePrimitive(instance); - - internal static T ParsePrimitive(this IScopedNode instance) where T : PrimitiveType, new() - => parsePrimitive(instance); - #pragma warning disable CS0618 // Type or member is obsolete - private static T parsePrimitive(this IBaseElementNavigator instance) where T : PrimitiveType, new() where U : IBaseElementNavigator + => ParsePrimitiveInternal(instance); #pragma warning restore CS0618 // Type or member is obsolete + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static T ParsePrimitiveInternal(this IBaseElementNavigator instance) where T : PrimitiveType, new() where U : IBaseElementNavigator => new() { ObjectValue = instance.Value }; #endregion #region ParseCoding - public static Coding ParseCoding(this ITypedElement instance) => parseCoding(instance); - - internal static Coding ParseCoding(this IScopedNode instance) => parseCoding(instance); - + public static Coding ParseCoding(this ITypedElement instance) #pragma warning disable CS0618 // Type or member is obsolete - private static Coding parseCoding(this IBaseElementNavigator instance) where T : IBaseElementNavigator + => ParseCodingInternal(instance); #pragma warning restore CS0618 // Type or member is obsolete + + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static Coding ParseCodingInternal(this IBaseElementNavigator instance) where T : IBaseElementNavigator { return new Coding() { @@ -144,13 +132,14 @@ private static Coding parseCoding(this IBaseElementNavigator instance) whe #endregion #region ParseResourceReference - public static ResourceReference ParseResourceReference(this ITypedElement instance) => instance.parseResourceReference(); - - internal static ResourceReference ParseResourceReference(this IScopedNode instance) => instance.parseResourceReference(); - + public static ResourceReference ParseResourceReference(this ITypedElement instance) #pragma warning disable CS0618 // Type or member is obsolete - private static ResourceReference parseResourceReference(this IBaseElementNavigator instance) where T : IBaseElementNavigator + => instance.ParseResourceReferenceInternal(); #pragma warning restore CS0618 // Type or member is obsolete + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static ResourceReference ParseResourceReferenceInternal(this IBaseElementNavigator instance) where T : IBaseElementNavigator { return new ResourceReference() { @@ -161,16 +150,19 @@ private static ResourceReference parseResourceReference(this IBaseElementNavi #endregion #region ParseCodeableConcept - public static CodeableConcept ParseCodeableConcept(this ITypedElement instance) => instance.parseCodeableConcept(); - internal static CodeableConcept ParseCodeableConcept(this IScopedNode instance) => instance.parseCodeableConcept(); + public static CodeableConcept ParseCodeableConcept(this ITypedElement instance) #pragma warning disable CS0618 // Type or member is obsolete - private static CodeableConcept parseCodeableConcept(this IBaseElementNavigator instance) where T : IBaseElementNavigator + => instance.ParseCodeableConceptInternal(); #pragma warning restore CS0618 // Type or member is obsolete + + [Obsolete("WARNING! Intended for internal API usage exclusively, interface IBaseElementNavigator can be changed in " + + "the near future.")] + public static CodeableConcept ParseCodeableConceptInternal(this IBaseElementNavigator instance) where T : IBaseElementNavigator { return new CodeableConcept() { Coding = - instance.Children("coding").Select(codingNav => codingNav.parseCoding()).ToList(), + instance.Children("coding").Select(codingNav => codingNav.ParseCodingInternal()).ToList(), Text = instance.Children("text").GetString() }; } diff --git a/src/Hl7.Fhir.Base/Properties/AssemblyInfo.cs b/src/Hl7.Fhir.Base/Properties/AssemblyInfo.cs index 7a39b60caf..744c396e65 100644 --- a/src/Hl7.Fhir.Base/Properties/AssemblyInfo.cs +++ b/src/Hl7.Fhir.Base/Properties/AssemblyInfo.cs @@ -33,15 +33,6 @@ [assembly: InternalsVisibleTo("Hl7.FhirPath.R4.Tests")] [assembly: InternalsVisibleTo("Hl7.Fhir.Support.Tests")] [assembly: InternalsVisibleTo("Hl7.Fhir.Support.Poco.Tests")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Enterprise")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Tests")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.STU3")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.R4")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.R5")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.STU3.Tests")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.R4.Tests")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.R5.Tests")] #endif #if RELEASE @@ -69,13 +60,4 @@ [assembly: InternalsVisibleTo("Hl7.FhirPath.R4.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001001717d77343870eca52515a2ff9ba7ef2ff314f2f1e651f4a069401e35193d4d5124b33379a6380d510239044f012f720d395064192157eae8f67b3e4d524b79daadebd4e65ce67db327949b77bf26ca6c0f97c4ca1a578811202a537e4d112fffb2e42e852afdd71c3295c694911cdf0535f709b72ba172c40a2b1f2b607ffdc")] [assembly: InternalsVisibleTo("Hl7.Fhir.Support.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001001717d77343870eca52515a2ff9ba7ef2ff314f2f1e651f4a069401e35193d4d5124b33379a6380d510239044f012f720d395064192157eae8f67b3e4d524b79daadebd4e65ce67db327949b77bf26ca6c0f97c4ca1a578811202a537e4d112fffb2e42e852afdd71c3295c694911cdf0535f709b72ba172c40a2b1f2b607ffdc")] [assembly: InternalsVisibleTo("Hl7.Fhir.Support.Poco.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001001717d77343870eca52515a2ff9ba7ef2ff314f2f1e651f4a069401e35193d4d5124b33379a6380d510239044f012f720d395064192157eae8f67b3e4d524b79daadebd4e65ce67db327949b77bf26ca6c0f97c4ca1a578811202a537e4d112fffb2e42e852afdd71c3295c694911cdf0535f709b72ba172c40a2b1f2b607ffdc")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Enterprise, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.STU3, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.R4, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.R5, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.STU3.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.R4.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] -[assembly: InternalsVisibleTo("Firely.Fhir.Validation.Compilation.R5.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c11eea5df3095844b027f018b356bc326a5a30b1f245010ad789589aa685569b2eb7f5f2ea5c49dafed338e3d9969eab21848c6c20a6b0a22c5ff7797d9a5062d7f3e42478e905d72a3dde344086a003f2df9deeb838e206d92c8cc59150c3151e9490381321f77a716e0a2b24a585b302ba2b3db37966a3da9abe4c601ba4c1")] #endif