diff --git a/FemDesign.Core/AdvancedFem/Cover.cs b/FemDesign.Core/AdvancedFem/Cover.cs
index f0ceb8764..d3eac3092 100644
--- a/FemDesign.Core/AdvancedFem/Cover.cs
+++ b/FemDesign.Core/AdvancedFem/Cover.cs
@@ -11,32 +11,14 @@ namespace FemDesign
/// cover_type
///
[System.Serializable]
- public partial class Cover: EntityBase, IStructureElement
+ public partial class Cover: NamedEntityBase, IStructureElement
{
///
/// Cover instance number
///
private static int _coverInstance = 0;
-
- ///
- /// Identifier
- ///
- [XmlAttribute("name")]
- public string _name;
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- Cover._coverInstance++;
- this._name = value + "." + Cover._coverInstance.ToString();
- }
- }
-
+ protected override int GetUniqueInstanceCount() => ++_coverInstance;
+
///
/// Load bearing direction (point_type_3d)
///
@@ -69,10 +51,11 @@ private Cover()
/// Region of cover.
/// Guidlist of supporting structure.
/// Vector, if null a TwoWay cover is defined.
+ /// Name.
public Cover(Geometry.Region region, CoverReferenceList supportingStructures, Geometry.Vector3d loadBearingDirection, string identifier)
{
this.EntityCreated();
- this.Name = identifier;
+ this.Identifier = identifier;
this.Region = region;
this.SupportingStructures = supportingStructures;
this.LoadBearingDirection = loadBearingDirection;
diff --git a/FemDesign.Core/AuxiliaryResults/LabelledSection.cs b/FemDesign.Core/AuxiliaryResults/LabelledSection.cs
index 2f6820d3e..c2672b104 100644
--- a/FemDesign.Core/AuxiliaryResults/LabelledSection.cs
+++ b/FemDesign.Core/AuxiliaryResults/LabelledSection.cs
@@ -12,11 +12,13 @@ namespace FemDesign.AuxiliaryResults
/// Labelled section. Used for extracting detailed results along a section line or polyline.
///
[System.Serializable]
- public partial class LabelledSection : EntityBase, IStructureElement
+ public partial class LabelledSection : NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int instances = 0;
- public static void ResetInstanceCount() => instances = 0;
+ private static int _labelledSectioninstances = 0;
+ public static void ResetInstanceCount() => _labelledSectioninstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_labelledSectioninstances;
+
[XmlElement("line_segment")]
public LineSegment _lineSegment;
[XmlElement("polyline")]
@@ -51,12 +53,6 @@ public List Verticies {
throw new ArgumentException($"LabelledSection must have at least 2 verticies.");
}
}
-
- ///
- /// Identifier
- ///
- [XmlAttribute("name")]
- public string Name { get; set; }
///
/// Parameterless contructor for serialization
@@ -81,11 +77,10 @@ public LabelledSection(string identifier = "LS", params Point3d[] verticies)
private void Initialize(List verticies, string identifier)
{
- instances++;
this.EntityCreated();
Verticies = verticies;
- Name = $"{identifier}.{instances}";
+ Identifier = identifier;
}
}
}
diff --git a/FemDesign.Core/Bars/Bar.cs b/FemDesign.Core/Bars/Bar.cs
index 409229265..866ab4ea3 100644
--- a/FemDesign.Core/Bars/Bar.cs
+++ b/FemDesign.Core/Bars/Bar.cs
@@ -1,6 +1,8 @@
// https://strusoft.com/
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Xml.Serialization;
using FemDesign.GenericClasses;
@@ -17,15 +19,8 @@ namespace FemDesign.Bars
[XmlInclude(typeof(Truss))]
[XmlRoot("database", Namespace = "urn:strusoft")]
[System.Serializable]
- public partial class Bar : EntityBase, IStructureElement, IStageElement
+ public partial class Bar : EntityBase, INamedEntity, IStructureElement, IStageElement
{
- [XmlIgnore]
- private static int _barInstance = 0; // used for counter of name)
- [XmlIgnore]
- private static int _columnInstance = 0; // used for counter of name
- [XmlIgnore]
- private static int _trussInstance = 0; // used for counter of name
-
///
/// Truss only.
/// enum
@@ -63,86 +58,10 @@ public double MaxTension
[XmlAttribute("tensions_plasticity")]
public bool TensionPlasticity { get; set; } // bool
- [XmlAttribute("name")]
- public string _name { get; set; } // identifier
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- if (this.Type == BarType.Beam)
- {
- Bar._barInstance++;
- this._name = value + "." + Bar._barInstance.ToString();
-
- // update barpart identifier
- if (this.BarPart != null)
- {
- this.BarPart.Name = this._name;
- }
- }
- else if (this.Type == BarType.Column)
- {
- Bar._columnInstance++;
- this._name = value + "." + Bar._columnInstance.ToString();
-
- // update barpart identifier
- if (this.BarPart != null)
- {
- this.BarPart.Name = this._name;
- }
- }
- else if (this.Type == BarType.Truss)
- {
- Bar._trussInstance++;
- this._name = value + "." + Bar._trussInstance.ToString();
-
- // update barpart identifier
- if (this.BarPart != null)
- {
- this.BarPart.Name = this._name;
- }
- }
- else
- {
- throw new System.ArgumentException($"Incorrect type of bar: {this.Type}");
- }
- }
- }
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this._name.IndexOf(".");
- return this._name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
[XmlAttribute("type")]
- public BarType _type; // beamtype
-
- [XmlIgnore]
- public BarType Type
- {
- get
- {
- return this._type;
- }
- set
- {
- this._type = value;
- }
- // get {return this._type;}
- // set {this._type = RestrictedString.BeamType(value);}
- }
+ public BarType Type { get; set; }
[XmlAttribute("stage")]
public int StageId { get; set; } = 1;
@@ -150,7 +69,10 @@ public BarType Type
[XmlElement("bar_part", Order = 1)]
public BarPart BarPart { get; set; } // bar_part_type
- [XmlElement("end", Order = 2)]
+ [XmlElement("truss_behaviour", Order = 2)]
+ public StruSoft.Interop.StruXml.Data.Truss_chr_type TrussBehaviour { get; set; }
+
+ [XmlElement("end", Order = 3)]
public string End = "";
[XmlIgnore]
@@ -176,10 +98,26 @@ public List LongitudinalBars
}
}
+ public string Name => this.BarPart.Name.Substring(0, this.BarPart.Name.Length - 2); // Remove trailing ".1" from barpart name
+ public int Instance => this.BarPart.Instance;
+
+ [XmlIgnore]
+ public string Identifier
+ {
+ get => this.BarPart.Identifier;
+ set => this.BarPart.Identifier = value;
+ }
+ [XmlIgnore]
+ public bool LockedIdentifier
+ {
+ get => this.BarPart.LockedIdentifier;
+ set => this.BarPart.LockedIdentifier = value;
+ }
+
///
/// Parameterless constructor for serialization.
///
- internal Bar()
+ protected Bar()
{
}
@@ -194,17 +132,17 @@ internal Bar()
/// Analytical eccentricity, same at start. Eccentricity set to 0,0 if null/end
/// Connectivity, same at start/end. Connectivity set to Rigid if null
/// Identifier
- public Bar(Geometry.Edge edge, Materials.Material material, Sections.Section section, BarType type = BarType.Beam, Eccentricity eccentricity = null, Connectivity connectivity = null, string identifier = "B")
+ public Bar(Geometry.Edge edge, Materials.Material material, Sections.Section section, BarType type, Eccentricity eccentricity = null, Connectivity connectivity = null, string identifier = "B")
{
- if(type == BarType.Truss) { throw new System.Exception("Truss is not a valid type"); }
-
+ if (type == BarType.Truss) { throw new System.Exception("Truss is not a valid type"); }
+
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
+ //this.Identifier = identifier;
- if(eccentricity == null) { eccentricity = Eccentricity.Default; }
- if(connectivity == null) { connectivity = Connectivity.Default; }
- this.BarPart = new BarPart(edge, this.Type, material, section, eccentricity, connectivity, this.Name);
+ if (eccentricity == null) { eccentricity = Eccentricity.Default; }
+ if (connectivity == null) { connectivity = Connectivity.Default; }
+ this.BarPart = new BarPart(edge, this.Type, material, section, eccentricity, connectivity, identifier);
}
///
@@ -221,7 +159,7 @@ public Bar(Geometry.Edge edge, Materials.Material material, Sections.Section sec
/// Connectivity. Connectivity set to Rigid if null/end
/// Connectivity. Connectivity set to Rigid if null
/// Identifier
- public Bar(FemDesign.Geometry.Point3d startPoint, FemDesign.Geometry.Point3d endPoint, Materials.Material material, Sections.Section section, BarType type = BarType.Beam, Geometry.Vector3d localY = null, Eccentricity startEccentricity = null, Eccentricity endEccentricity = null, Connectivity startConnectivity = null, Connectivity endConnectivity = null, string identifier = "B")
+ public Bar(FemDesign.Geometry.Point3d startPoint, FemDesign.Geometry.Point3d endPoint, Materials.Material material, Sections.Section section, BarType type, Geometry.Vector3d localY = null, Eccentricity startEccentricity = null, Eccentricity endEccentricity = null, Connectivity startConnectivity = null, Connectivity endConnectivity = null, string identifier = "B")
{
var orientY = localY ?? (endPoint - startPoint).Cross(Geometry.Vector3d.UnitZ);
Geometry.Edge edge = new Geometry.Edge(startPoint, endPoint, orientY);
@@ -229,14 +167,14 @@ public Bar(FemDesign.Geometry.Point3d startPoint, FemDesign.Geometry.Point3d end
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
+ //this.Identifier = identifier;
if (startEccentricity == null) { startEccentricity = Eccentricity.Default; }
if (endEccentricity == null) { endEccentricity = Eccentricity.Default; }
if (startConnectivity == null) { startConnectivity = Connectivity.Default; }
if (endConnectivity == null) { endConnectivity = Connectivity.Default; }
- this.BarPart = new BarPart(edge, this.Type, material, section, startEccentricity, endEccentricity, startConnectivity, endConnectivity, this.Name);
+ this.BarPart = new BarPart(edge, this.Type, material, section, startEccentricity, endEccentricity, startConnectivity, endConnectivity, identifier);
}
@@ -264,10 +202,10 @@ public Bar(Geometry.Edge edge, BarType type, Materials.Material material, Sectio
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
+ //this.Identifier = identifier;
- this.BarPart = new BarPart(edge, this.Type, material, section, startEccentricity, endEccentricity, startConnectivity, endConnectivity, this.Name);
+ this.BarPart = new BarPart(edge, this.Type, material, section, startEccentricity, endEccentricity, startConnectivity, endConnectivity, identifier);
}
///
@@ -289,8 +227,8 @@ public Bar(Geometry.Edge edge, BarType type, Materials.Material material, Sectio
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
- this.BarPart = new BarPart(edge, this.Type, material, startSection, endSection, startEccentricity, endEccentricity, startConnectivity, endConnectivity, this.Name);
+ //this.Identifier = identifier;
+ this.BarPart = new BarPart(edge, this.Type, material, startSection, endSection, startEccentricity, endEccentricity, startConnectivity, endConnectivity, identifier);
}
@@ -310,8 +248,8 @@ public Bar(Geometry.Edge edge, BarType type, Materials.Material material, Sectio
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
- this.BarPart = new BarPart(edge, this.Type, material, sections, eccentricities, connectivities, this.Name);
+ //this.Identifier = identifier;
+ this.BarPart = new BarPart(edge, this.Type, material, sections, eccentricities, connectivities, identifier);
}
///
@@ -332,8 +270,8 @@ public Bar(Geometry.Edge edge, BarType type, Materials.Material material, Sectio
this.EntityCreated();
this.Type = type;
- this.Name = identifier;
- this.BarPart = new BarPart(edge, this.Type, material, sections, positions, eccentricities, startConnectivity, endConnectivity, this.Name);
+ //this.Identifier = identifier;
+ this.BarPart = new BarPart(edge, this.Type, material, sections, positions, eccentricities, startConnectivity, endConnectivity, identifier);
}
@@ -349,10 +287,34 @@ public Bar(Geometry.Edge edge, Materials.Material material, Sections.Section sec
{
this.EntityCreated();
this.Type = BarType.Truss;
- this.Name = identifier;
+ //this.Identifier = identifier;
this.BarPart = new BarPart(edge, this.Type, material, section, identifier);
}
+
+
+ ///
+ /// Construct a truss element.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Bar Truss(Geometry.Edge edge, Materials.Material material, Sections.Section section, string identifier)
+ {
+ var truss = new Bar();
+
+ truss.EntityCreated();
+ truss.Type = BarType.Truss;
+ //truss.Identifier = identifier;
+ truss.BarPart = new BarPart(edge, truss.Type, material, section, identifier);
+ return truss;
+ }
+
+
+
+
/// Update entities if this bar should be "reconstructed"
public void UpdateEntities()
{
@@ -371,10 +333,10 @@ public void UpdateEntities()
public override string ToString()
{
- if(this.Type == BarType.Beam || this.Type == BarType.Column)
+ if (this.Type == BarType.Beam || this.Type == BarType.Column)
return $"{this.Type} Start: {this.BarPart.Edge.Points.First()}, End: {this.BarPart.Edge.Points.Last()}, Length: {this.BarPart.Edge.Length} m, Sections: ({this.BarPart.ComplexSectionObj.Sections.First()._sectionName}, {this.BarPart.ComplexSectionObj.Sections.Last()._sectionName}), Material: {this.BarPart.ComplexMaterialObj}";
- else if(this.Type == BarType.Truss)
+ else if (this.Type == BarType.Truss)
{
return $"{this.Type} Start: {this.BarPart.Edge.Points.First()}, End: {this.BarPart.Edge.Points.Last()}, Length: {this.BarPart.Edge.Length} m, Section: {this.BarPart.TrussUniformSectionObj._sectionName}, Material: {this.BarPart.ComplexMaterialObj}";
}
diff --git a/FemDesign.Core/Bars/BarPart.cs b/FemDesign.Core/Bars/BarPart.cs
index d154e2c42..0f7c85a85 100644
--- a/FemDesign.Core/Bars/BarPart.cs
+++ b/FemDesign.Core/Bars/BarPart.cs
@@ -2,7 +2,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Xml;
using System.Xml.Serialization;
+using System.ComponentModel;
using FemDesign.GenericClasses;
@@ -14,8 +16,28 @@ namespace FemDesign.Bars
/// Underlying representation of a Bar-element.
///
[System.Serializable]
- public partial class BarPart : EntityBase, IStageElement
+ public partial class BarPart : NamedEntityPartBase, IStageElement
{
+ [XmlIgnore]
+ private static int _barInstance = 0; // Number of bar/beam instances created
+ [XmlIgnore]
+ private static int _columnInstance = 0; // Number of column instances created
+ [XmlIgnore]
+ private static int _trussInstance = 0; // Number of truss instances created
+ protected override int GetUniqueInstanceCount()
+ {
+ switch (this.Type)
+ {
+ case BarType.Beam:
+ return ++_barInstance;
+ case BarType.Column:
+ return ++_columnInstance;
+ case BarType.Truss:
+ return ++_trussInstance;
+ default:
+ throw new System.ArgumentException($"Incorrect type of bar: {this.Type}");
+ }
+ }
///
/// Edge field
///
@@ -158,47 +180,15 @@ public Geometry.Vector3d LocalZ
}
}
- ///
- /// Identifier field
- ///
- [XmlAttribute("name")]
- public string _name;
-
- ///
- /// Identifier property
- ///
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- this._name = value + ".1";
- }
- }
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this._name.IndexOf(".");
- return this._name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
-
[XmlIgnore]
- public BarType Type { get; set; }
+ public BarType Type;
[XmlIgnore]
public SectionType SectionType
{
get
{
- if(this.Type == BarType.Truss)
+ if (this.Type == BarType.Truss)
{
return SectionType.Truss;
}
@@ -206,11 +196,11 @@ public SectionType SectionType
{
return SectionType.RegularBeamColumn;
}
- else if(this.Type != BarType.Truss && this.HasComplexCompositeRef)
+ else if (this.Type != BarType.Truss && this.HasComplexCompositeRef)
{
return SectionType.CompositeBeamColumn;
}
- else if(this.Type != BarType.Truss && this.HasComplexSectionRef && this.HasDeltaBeamComplexSectionRef)
+ else if (this.Type != BarType.Truss && this.HasComplexSectionRef && this.HasDeltaBeamComplexSectionRef)
{
return SectionType.DeltaBeamColumn;
}
@@ -306,7 +296,7 @@ public string ComplexSectionRef
this._complexSectionRef = r;
return r;
}
-
+
}
}
set
@@ -455,9 +445,36 @@ public Eccentricity[] AnalyticalEccentricity
}
[XmlElement("buckling_data", Order = 5)]
public Buckling.BucklingData BucklingData { get; set; } // buckling_data_type
- [XmlElement("end", Order = 6)]
+
+ [XmlElement("camber_type_2d", Order = 6)]
+ public StruSoft.Interop.StruXml.Data.Camber_type_2d CamberType2d { get; set; }
+
+ [XmlElement("stiffness_modifiers", Order = 7)]
+ public BarStiffnessFactors BarStiffnessFactors { get; set; }
+
+ [XmlElement("end", Order = 8)]
public string End = "";
+ [XmlAttribute("ecc_crack")]
+ [DefaultValue(false)]
+ public bool EccCrack { get; set; }
+
+ [XmlAttribute("first_order_analysis_U")]
+ [DefaultValue(false)]
+ public bool FirstOrderAnalysisU { get; set; }
+
+ [XmlAttribute("first_order_analysis_Sq")]
+ [DefaultValue(false)]
+ public bool FirstOrderAnalysisSq { get; set; }
+
+ [XmlAttribute("first_order_analysis_Sf")]
+ [DefaultValue(false)]
+ public bool FirstOrderAnalysisSf { get; set; }
+
+ [XmlAttribute("first_order_analysis_Sc")]
+ [DefaultValue(false)]
+ public bool FirstOrderAnalysisSc { get; set; }
+
///
/// Parameterless constructor for serialization.
///
@@ -484,7 +501,7 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.ComplexSectionObj = new Sections.ComplexSection(section, eccentricity);
this.Connectivity = new Connectivity[1] { connectivity };
this.EccentricityCalc = true;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
@@ -506,7 +523,7 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.ComplexSectionObj = new Sections.ComplexSection(section, section, startEccentricity, endEccentricity);
this.Connectivity = new Connectivity[2] { startConnectivity, endConnectivity };
this.EccentricityCalc = true;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
@@ -528,7 +545,7 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.ComplexSectionObj = new Sections.ComplexSection(startSection, endSection, startEccentricity, endEccentricity);
this.Connectivity = new Connectivity[2] { startConnectivity, endConnectivity };
this.EccentricityCalc = true;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
@@ -550,7 +567,7 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.ComplexSectionObj = new Sections.ComplexSection(sections, eccentricities);
this.Connectivity = connectivities;
this.EccentricityCalc = true;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
@@ -572,13 +589,13 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.ComplexSectionObj = new Sections.ComplexSection(sections, positions, eccentricities);
this.Connectivity = new Connectivity[2] { startConnectivity, endConnectivity };
this.EccentricityCalc = true;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
///
/// Construct BarPart (truss)
- ///
+ ///
public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Sections.Section section, string identifier)
{
if (type != BarType.Truss)
@@ -592,13 +609,13 @@ public BarPart(Geometry.Edge edge, BarType type, Materials.Material material, Se
this.Edge = edge;
this.ComplexMaterialObj = material;
this.TrussUniformSectionObj = section;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
///
/// Orient this object's coordinate system to GCS
- ///
+ ///
public void OrientCoordinateSystemToGCS()
{
var cs = this.CoordinateSystem;
diff --git a/FemDesign.Core/Bars/BarStiffnessFactors.cs b/FemDesign.Core/Bars/BarStiffnessFactors.cs
new file mode 100644
index 000000000..6e169ce1c
--- /dev/null
+++ b/FemDesign.Core/Bars/BarStiffnessFactors.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Xml.Serialization;
+
+namespace FemDesign.Bars
+{
+ public partial class BarStiffnessFactors
+ {
+ //[XmlElement("stiffness_modifiers", Order = 1)]
+ //public List Stiffness_modifiers
+ //{
+ // get
+ // {
+ // if (_stiffness_modifiers == null)
+ // return null;
+ // else if (_stiffness_modifiers.Count == 0)
+ // return null;
+ // else
+ // return _stiffness_modifiers;
+ // }
+ // set
+ // {
+ // if (value == null)
+ // _stiffness_modifiers = null;
+ // else if (value.Count == 0)
+ // _stiffness_modifiers = null;
+ // else
+ // _stiffness_modifiers = value;
+ // }
+ //}
+
+ //[XmlIgnore]
+ //public List _stiffness_modifiers;
+
+
+ [XmlElement("factors", Order = 1)]
+ public List StiffnessModifiers { get; set; }
+
+ }
+}
diff --git a/FemDesign.Core/Bars/Connectivity.cs b/FemDesign.Core/Bars/Connectivity.cs
index 99363daf3..9ca9a0ea0 100644
--- a/FemDesign.Core/Bars/Connectivity.cs
+++ b/FemDesign.Core/Bars/Connectivity.cs
@@ -19,7 +19,7 @@ public partial class Connectivity
// binary-rigid
/// Translation local-x axis.
[XmlAttribute("m_x")]
- public bool Mx
+ public bool Tx
{
get
{
@@ -35,7 +35,7 @@ public bool Mx
/// Translation local-y axis.
[XmlAttribute("m_y")]
- public bool My
+ public bool Ty
{
get
{
@@ -52,7 +52,7 @@ public bool My
/// Translation local-z axis.
[XmlAttribute("m_z")]
- public bool Mz
+ public bool Tz
{
get
{
@@ -119,7 +119,7 @@ public bool Rz
[XmlAttribute("m_x_release")]
public double _mxRelease; // non_neg_max_1e10. Default = 0. Valid only if m_x is false.
[XmlIgnore]
- public double MxRelease
+ public double TxRelease
{
get
{
@@ -133,7 +133,7 @@ public double MxRelease
[XmlAttribute("m_y_release")]
public double _myRelease; // non_neg_max_1e10. Default = 0. Valid only if m_y is false.
[XmlIgnore]
- public double MyRelease
+ public double TyRelease
{
get
{
@@ -147,7 +147,7 @@ public double MyRelease
[XmlAttribute("m_z_release")]
public double _mzRelease; // non_neg_max_1e10. Default = 0. Valid only if m_z is false.
[XmlIgnore]
- public double MzRelease
+ public double TzRelease
{
get
{
@@ -205,7 +205,7 @@ public bool IsRigid
{
get
{
- if(this.Mx && this.My && this.Mz && this.Rx && this.Ry && this.Rz)
+ if(this.Tx && this.Ty && this.Tz && this.Rx && this.Ry && this.Rz)
return true;
else
return false;
@@ -216,7 +216,7 @@ public bool IsHinged
{
get
{
- if (this.Mx && this.My && this.Mz && this.Rx && this.Ry == false && this.Rz == false)
+ if (this.Tx && this.Ty && this.Tz && this.Rx && this.Ry == false && this.Rz == false)
return true;
else
return false;
@@ -234,17 +234,17 @@ private Connectivity()
///
/// Private constructor for binary-rigid definition.
///
- ///
- ///
- ///
+ ///
+ ///
+ ///
///
///
///
- public Connectivity(bool mx, bool my, bool mz, bool rx, bool ry, bool rz)
+ public Connectivity(bool tx, bool ty, bool tz, bool rx, bool ry, bool rz)
{
- this.Mx = mx;
- this.My = my;
- this.Mz = mz;
+ this.Tx = tx;
+ this.Ty = ty;
+ this.Tz = tz;
this.Rx = rx;
this.Ry = ry;
this.Rz = rz;
@@ -253,29 +253,29 @@ public Connectivity(bool mx, bool my, bool mz, bool rx, bool ry, bool rz)
///
/// Private constructor for semi-rigid definition.
///
- ///
- ///
- ///
+ ///
+ ///
+ ///
///
///
///
- ///
- ///
- ///
+ ///
+ ///
+ ///
///
///
///
- public Connectivity(bool mx, bool my, bool mz, bool rx, bool ry, bool rz, double mxRelease, double myRelease, double mzRelease, double rxRelease, double ryRelease, double rzRelease)
+ public Connectivity(bool tx, bool ty, bool tz, bool rx, bool ry, bool rz, double txRelease, double tyRelease, double tzRelease, double rxRelease, double ryRelease, double rzRelease)
{
- this.Mx = mx;
- this.My = my;
- this.Mz = mz;
+ this.Tx = tx;
+ this.Ty = ty;
+ this.Tz = tz;
this.Rx = rx;
this.Ry = ry;
this.Rz = rz;
- this.MxRelease = mxRelease;
- this.MyRelease = myRelease;
- this.MzRelease = mzRelease;
+ this.TxRelease = txRelease;
+ this.TyRelease = tyRelease;
+ this.TzRelease = tzRelease;
this.RxRelease = rxRelease;
this.RyRelease = ryRelease;
this.RzRelease = rzRelease;
@@ -321,7 +321,7 @@ public override string ToString()
else if(IsHinged)
return $"{this.GetType().Name} Hinged";
else
- return $"{this.GetType().Name} Tx: {this.MxRelease} kN/m, Ty: {this.MyRelease} kN/m, Tz: {this.MzRelease} kN/m, Rx: {this.RxRelease} kNm/rad, Ry: {this.RyRelease} kNm/rad, Rz: {this.RzRelease} kNm/rad";
+ return $"{this.GetType().Name} Tx: {this.TxRelease} kN/m, Ty: {this.TyRelease} kN/m, Tz: {this.TzRelease} kN/m, Rx: {this.RxRelease} kNm/rad, Ry: {this.RyRelease} kNm/rad, Rz: {this.RzRelease} kNm/rad";
}
}
}
\ No newline at end of file
diff --git a/FemDesign.Core/Bars/Eccentricity.cs b/FemDesign.Core/Bars/Eccentricity.cs
index e85245d77..f42853305 100644
--- a/FemDesign.Core/Bars/Eccentricity.cs
+++ b/FemDesign.Core/Bars/Eccentricity.cs
@@ -14,7 +14,7 @@ public partial class Eccentricity
{
///
/// Private field for eccentricity of local-x.
- ///
+ ///
[XmlAttribute("x")]
public double _x;
@@ -138,8 +138,7 @@ public override int GetHashCode()
public static Eccentricity Default => new Eccentricity(0, 0);
public override string ToString()
{
- return $"{this.GetType().Name} Local-X: 0.00, Local-Y: {this.Y.ToString(FemDesign.TextFormatting.decimalRounding)}, Local-Z: {this.Z.ToString(FemDesign.TextFormatting.decimalRounding)}";
+ return $"{this.GetType().Name} Local-Y: {this.Y.ToString(FemDesign.TextFormatting.decimalRounding)}, Local-Z: {this.Z.ToString(FemDesign.TextFormatting.decimalRounding)}";
}
-
}
}
\ No newline at end of file
diff --git a/FemDesign.Core/Calculate/Analysis.cs b/FemDesign.Core/Calculate/Analysis.cs
index eae4874a9..99d089d52 100644
--- a/FemDesign.Core/Calculate/Analysis.cs
+++ b/FemDesign.Core/Calculate/Analysis.cs
@@ -259,7 +259,7 @@ public static Analysis StaticAnalysis(Comb comb = null, bool calcCase = true, bo
/// Consider masses in global x-direction.
/// Consider masses in global y-direction.
/// Consider masses in global z-direction.
- /// Top of substructure. Masses on this level and below are not considered in Eigenfrequency
+ /// Top of substructure. Masses on this level and below are not considered in Eigenfrequency
///
public static Analysis Eigenfrequencies(int numShapes = 3, int maxSturm = 0, bool x = true, bool y = true, bool z = true, double top = -0.01)
{
diff --git a/FemDesign.Core/Calculate/Application.cs b/FemDesign.Core/Calculate/Application.cs
index 384850927..1867ffc7d 100644
--- a/FemDesign.Core/Calculate/Application.cs
+++ b/FemDesign.Core/Calculate/Application.cs
@@ -163,6 +163,7 @@ public void OpenStruxml(string struxmlPath, bool killProcess)
///
///
///
+ ///
///
public bool RunFdScript(FdScript fdScript, bool killProcess, bool endSession, bool checkOpenFiles = true)
{
diff --git a/FemDesign.Core/Calculate/FdScript.cs b/FemDesign.Core/Calculate/FdScript.cs
index 86fdca28d..ee2d42a31 100644
--- a/FemDesign.Core/Calculate/FdScript.cs
+++ b/FemDesign.Core/Calculate/FdScript.cs
@@ -245,6 +245,7 @@ public static FdScript CreateDocumentation(string strPath, string docxTemplatePa
return fdScript;
}
+ ///
/// Create fdscript to open and extract results from a FEM-Design .str model.
///
/// Path to model with results to be extracted.
diff --git a/FemDesign.Core/Calculate/Stage.cs b/FemDesign.Core/Calculate/Stage.cs
index b37612eaa..1b5963765 100644
--- a/FemDesign.Core/Calculate/Stage.cs
+++ b/FemDesign.Core/Calculate/Stage.cs
@@ -16,12 +16,12 @@ public partial class Stage
///
/// Parameterless constructor for serialization.
///
- private Stage()
+ public Stage()
{
}
- private Stage(bool ghost = false)
+ public Stage(bool ghost = false)
{
this._ghost = Convert.ToInt32(ghost);
}
diff --git a/FemDesign.Core/FemDesign.Core.csproj b/FemDesign.Core/FemDesign.Core.csproj
index b5e5ae197..5fd5dd1e7 100644
--- a/FemDesign.Core/FemDesign.Core.csproj
+++ b/FemDesign.Core/FemDesign.Core.csproj
@@ -20,6 +20,7 @@
4
false
bin\Debug\FemDesign.Core.xml
+ CS1591
pdbonly
@@ -46,17 +47,22 @@
+
+
+
+
+
@@ -175,6 +181,7 @@
+
@@ -185,12 +192,13 @@
+
-
+
@@ -318,6 +326,7 @@
+
diff --git a/FemDesign.Core/GenericClasses/INamedEntity.cs b/FemDesign.Core/GenericClasses/INamedEntity.cs
new file mode 100644
index 000000000..b32b62cfa
--- /dev/null
+++ b/FemDesign.Core/GenericClasses/INamedEntity.cs
@@ -0,0 +1,32 @@
+// https://strusoft.com/
+
+namespace FemDesign
+{
+ ///
+ /// Entities with a name/identifier. E.g "B.42" or "@MyLockedName.1"
+ ///
+ public interface INamedEntity
+ {
+ ///
+ /// Name of the entity. E.g. "B.42"
+ ///
+ string Name { get; }
+
+ ///
+ /// Instance number.
+ ///
+ int Instance { get; }
+
+ ///
+ /// Identifier part of the name.
+ ///
+ string Identifier { get; set; }
+
+ ///
+ /// When true, FEM-Design will not modify the Instance number of the Name. Note that this might not always be possible.
+ ///
+ /// See https://github.com/strusoft/femdesign-api/issues/81#issuecomment-1250848165 for more info.
+ ///
+ bool LockedIdentifier { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Core/GenericClasses/NamedEntityBase.cs b/FemDesign.Core/GenericClasses/NamedEntityBase.cs
new file mode 100644
index 000000000..4b5aaa76b
--- /dev/null
+++ b/FemDesign.Core/GenericClasses/NamedEntityBase.cs
@@ -0,0 +1,74 @@
+// https://strusoft.com/
+using System;
+using System.Xml.Serialization;
+using System.Text.RegularExpressions;
+using FemDesign.GenericClasses;
+
+namespace FemDesign
+{
+ public abstract partial class NamedEntityBase : EntityBase, INamedEntity
+ {
+ [XmlAttribute("name")]
+ public string _name; // identifier
+ [XmlIgnore]
+ public virtual string Name => _namePattern.Match(this._name).Groups["name"].Value;
+ [XmlIgnore]
+ public virtual int Instance => int.Parse(_namePattern.Match(this._name).Groups["instance"].Value);
+
+ [XmlIgnore]
+ public virtual string Identifier
+ {
+ get => _namePattern.Match(this._name).Groups["identifier"].Value;
+ set
+ {
+ this._name = $"{value}.{GetUniqueInstanceCount()}";
+
+ if (string .IsNullOrEmpty(value) || _namePattern.IsMatch(this._name) == false)
+ throw new ArgumentException($"'{value}' is not a valid Identifier.");
+ }
+ }
+
+ [XmlIgnore]
+ public virtual bool LockedIdentifier
+ {
+ get => _name.StartsWith("@");
+ set
+ {
+ if (value && !LockedIdentifier)
+ _name = "@" + _name;
+ else if (!value && LockedIdentifier)
+ _name = _name.Substring(1);
+ }
+ }
+
+ protected static readonly Regex _namePattern = new Regex(@"^@{0,1}(?'name'(?'identifier'[ -#%'-;=?A-\ufffd;]{0,50})\.(?'instance'[0-9]{1,6}){1})$");
+
+ protected NamedEntityBase()
+ {
+ this._name = "";
+ }
+
+ ///
+ /// This value will be used to set number (like ".1") part of the entity name (like "B.1"). Typically this is a counter starting at 1 and incrementing for each new instance of this class that has been created.
+ ///
+ /// A unique number.
+ protected abstract int GetUniqueInstanceCount();
+ }
+
+ public abstract partial class NamedEntityPartBase : NamedEntityBase
+ {
+ public override string Name => _namePattern.Match(base._name).Groups["name"].Value;
+ public override int Instance => int.Parse(_namePattern.Match(base._name).Groups["instance"].Value);
+ [XmlIgnore]
+ public override string Identifier
+ {
+ get => _namePattern.Match(base._name).Groups["identifier"].Value;
+ set
+ {
+ base.Identifier = value;
+ base._name += ".1";
+ }
+ }
+ protected new static readonly Regex _namePattern = new Regex(@"@{0,1}(?'name'(?'identifier'[ -#%'-;=?A-\ufffd;]{0,50})\.(?'instance'[0-9]{1,6}){1}\.1)");
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Core/GenericClasses/RestrictedDouble.cs b/FemDesign.Core/GenericClasses/RestrictedDouble.cs
index 3f2bfe72f..0cd91f467 100644
--- a/FemDesign.Core/GenericClasses/RestrictedDouble.cs
+++ b/FemDesign.Core/GenericClasses/RestrictedDouble.cs
@@ -56,7 +56,7 @@ internal static double AbsMax_10000(double val)
}
///
- // abs_max_1e20
+ /// abs_max_1e20
///
internal static double AbsMax_1e20(double val)
{
@@ -83,7 +83,7 @@ internal static double NonNegMax_10(double val)
}
///
- // non_neg_max_100
+ /// non_neg_max_100
///
internal static double NonNegMax_100(double val)
{
diff --git a/FemDesign.Core/Geometry/Face.cs b/FemDesign.Core/Geometry/Face.cs
index f2c8573ad..3d6bd0ac1 100644
--- a/FemDesign.Core/Geometry/Face.cs
+++ b/FemDesign.Core/Geometry/Face.cs
@@ -47,7 +47,6 @@ public Face(int node1, int node2, int node3, int node4)
///
///
///
- ///
public Face(int node1, int node2, int node3)
{
this.Node1 = node1;
diff --git a/FemDesign.Core/Geometry/LineSegment.cs b/FemDesign.Core/Geometry/LineSegment.cs
index b399e6567..6b693e617 100644
--- a/FemDesign.Core/Geometry/LineSegment.cs
+++ b/FemDesign.Core/Geometry/LineSegment.cs
@@ -36,7 +36,8 @@ public LineSegment()
///
/// Construct LineSegment from start and endpoint.
///
- ///
+ ///
+ ///
public LineSegment(Point3d start, Point3d end)
{
this.StartPoint = start;
diff --git a/FemDesign.Core/Geometry/Region.cs b/FemDesign.Core/Geometry/Region.cs
index 05232acd2..e20628327 100644
--- a/FemDesign.Core/Geometry/Region.cs
+++ b/FemDesign.Core/Geometry/Region.cs
@@ -128,12 +128,12 @@ public static Region RectangleXZ(double width, double height)
return region;
}
- public static Region RectangleXY(double width, double length)
+ public static Region RectangleXY(Point3d corner, double widthX, double widthY)
{
- var points0 = new Point3d(0, 0, 0);
- var points1 = new Point3d(width, 0, 0);
- var points2 = new Point3d(width, length, 0);
- var points3 = new Point3d(0, length, 0);
+ var points0 = corner + new Vector3d(0, 0, 0);
+ var points1 = corner + new Vector3d(widthX, 0, 0);
+ var points2 = corner + new Vector3d(widthX, widthY, 0);
+ var points3 = corner + new Vector3d(0, widthY, 0);
var points = new List() { points0, points1, points2, points3 };
@@ -186,8 +186,9 @@ public void SetEdgeConnection(Shells.EdgeConnection edgeConnection, int index)
edge.EdgeConnection = null;
}
else
- {
- string name = "CE." + cInstance.ToString();
+ {
+ string name = edgeConnection.Name == null ? "CE." + cInstance.ToString() : edgeConnection.Name;
+
Shells.EdgeConnection ec = Shells.EdgeConnection.CopyExisting(edgeConnection, name);
edge.EdgeConnection = ec;
}
diff --git a/FemDesign.Core/Geometry/RegionGroup.cs b/FemDesign.Core/Geometry/RegionGroup.cs
index 41f036df3..9c67f897d 100644
--- a/FemDesign.Core/Geometry/RegionGroup.cs
+++ b/FemDesign.Core/Geometry/RegionGroup.cs
@@ -16,7 +16,7 @@ public partial class RegionGroup
///
/// Parameterless constructor for serialization
- ///
+ ///
private RegionGroup()
{
@@ -24,7 +24,7 @@ private RegionGroup()
///
/// Construct region group from single region
- ///
+ ///
public RegionGroup(Region region)
{
this.Regions.Add(region);
@@ -32,7 +32,7 @@ public RegionGroup(Region region)
///
/// Construct region group from list of regions
- ///
+ ///
public RegionGroup(List regions)
{
this.Regions = regions;
diff --git a/FemDesign.Core/Loads/LineStressLoad.cs b/FemDesign.Core/Loads/LineStressLoad.cs
index 9e67cebdf..bb627c8fd 100644
--- a/FemDesign.Core/Loads/LineStressLoad.cs
+++ b/FemDesign.Core/Loads/LineStressLoad.cs
@@ -1,5 +1,6 @@
// https://strusoft.com/
+using FemDesign.Geometry;
using System.Collections.Generic;
using System.Xml.Serialization;
@@ -9,7 +10,7 @@ namespace FemDesign.Loads
/// line_stress_load_type
///
[System.Serializable]
- public partial class LineStressLoad: LoadBase
+ public partial class LineStressLoad : LoadBase
{
///
/// Edge defining the geometry of the load
@@ -68,21 +69,90 @@ private LineStressLoad()
}
+ ///
+ /// Construct a line stress load
+ ///
+ ///
+ /// Force (n1 and n2)
+ /// Load case
+ /// Comment
+ public LineStressLoad(Edge edge, double force, LoadCase loadCase, string comment = "")
+ : this(edge, edge.CoordinateSystem.LocalY, force, force, 0.0, 0.0, loadCase, comment)
+ { }
+
+ ///
+ /// Construct a line stress load
+ ///
+ /// Underlying edge of line load. Line or Arc.
+ /// Force (n1 and n2)
+ /// Moment (m1 and m2)
+ /// Load case
+ /// Comment
+ public LineStressLoad(Edge edge, double force, double moment, LoadCase loadCase, string comment = "")
+ : this(edge, edge.CoordinateSystem.LocalY, force, force, moment, moment, loadCase, comment)
+ { }
+
+ ///
+ /// Construct a uniform or variable line stress load
+ ///
+ /// Underlying edge of line load. Line or Arc.
+ /// Force at start.
+ /// Force at end.
+ /// Moment at start.
+ /// Moment at end.
+ /// Load case
+ /// Comment
+ public LineStressLoad(Edge edge, double n1, double n2, double m1, double m2, LoadCase loadCase, string comment = "")
+ : this(edge, edge.CoordinateSystem.LocalY, n1, n2, m1, m2, loadCase, comment)
+ { }
+
///
/// Construct a uniform or variable line stress load
///
/// Underlying edge of line load. Line or Arc.
/// Direction of load.
- /// List of 2 top bottom location values
- public LineStressLoad(Geometry.Edge edge, Geometry.Vector3d direction, List topBotLocVals, LoadCase loadCase, string comment)
+ /// Force at start.
+ /// Force at end.
+ /// Moment at start.
+ /// Moment at end.
+ /// Load case
+ /// Comment
+ public LineStressLoad(Edge edge, Vector3d direction, double n1, double n2, double m1, double m2, LoadCase loadCase, string comment = "")
+ {
+ var topBotLocVals = new List {
+ new TopBotLocationValue(edge.Points[0], n1, m1),
+ new TopBotLocationValue(edge.Points[0], n2, m2)
+ };
+ Initialize(edge, direction, topBotLocVals, loadCase, comment);
+ }
+
+ ///
+ /// Construct a uniform or variable line stress load
+ ///
+ /// Underlying edge of line load. Line or Arc.
+ /// Direction of load.
+ /// List of 2 top bottom location values
+ /// Load case
+ /// Comment
+ public LineStressLoad(Edge edge, Vector3d direction, List topBotLocVals, LoadCase loadCase, string comment = "")
+ {
+ Initialize(edge, direction, topBotLocVals, loadCase, comment);
+ }
+
+ private void Initialize(Edge edge, Vector3d direction, List topBotLocVals, LoadCase loadCase, string comment)
{
this.EntityCreated();
this.Edge = edge;
this.Direction = direction;
this.TopBotLocVal = topBotLocVals;
this.LoadCaseGuid = loadCase.Guid;
+ this.LoadCaseName = loadCase.Name;
this.Comment = comment;
}
+ public override string ToString()
+ {
+ return $"{this.GetType().Name}, Force: {TopBotLocVal[0].TopVal:0.0}/{TopBotLocVal[1].TopVal:0.0}kN, Moment: {TopBotLocVal[0].BottomVal:0.0}/{TopBotLocVal[1].BottomVal:0.0}kNm, LoadCase: {this.LoadCaseName}";
+ }
}
}
\ No newline at end of file
diff --git a/FemDesign.Core/Loads/LineTemperatureLoad.cs b/FemDesign.Core/Loads/LineTemperatureLoad.cs
index aa5cd0f12..01f3f87fe 100644
--- a/FemDesign.Core/Loads/LineTemperatureLoad.cs
+++ b/FemDesign.Core/Loads/LineTemperatureLoad.cs
@@ -70,7 +70,9 @@ private LineTemperatureLoad()
///
/// Underlying edge of line load. Line or Arc.
/// Directio of load.
- /// 1 or 2 top bottom location values
+ /// 1 or 2 top bottom location values
+ ///
+ ///
public LineTemperatureLoad(Geometry.Edge edge, Geometry.Vector3d direction, List topBotLocVals, LoadCase loadCase, string comment)
{
this.EntityCreated();
diff --git a/FemDesign.Core/Loads/LoadCombination.cs b/FemDesign.Core/Loads/LoadCombination.cs
index 0e48866a1..8d5f4e249 100644
--- a/FemDesign.Core/Loads/LoadCombination.cs
+++ b/FemDesign.Core/Loads/LoadCombination.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Xml.Serialization;
+using System.Linq;
namespace FemDesign.Loads
{
@@ -14,9 +15,59 @@ public partial class LoadCombination : EntityBase
[XmlAttribute("name")]
public string Name { get; set; } // name159
[XmlAttribute("type")]
- public LoadCombType Type { get; set; } // loadcombtype
+ public LoadCombType Type { get; set; } // loadcombtype
+
+ // CASES: Xml elements sequence in order
+ //
+ // load_case (sequence)
+ // seismic_max
+ // seismic_res_fx_plus_mx
+ // seismic_res_fx_minus_mx
+ // seismic_res_fy_plus_my
+ // seismic_res_fy_minus_my
+ // seismic_res_fz
+ // ptc_t0
+ // ptc_t8
+ // ldcase_pile
+ // cs_case
+
[XmlElement("load_case")]
- public List ModelLoadCase = new List(); // sequence: ModelLoadCase
+ public List ModelLoadCase { get; set; } = new List();
+
+ // Special load cases of the combination, from FD18
+ [XmlElement("seismic_max")]
+ public LoadCombinationCaseBase SeismicMax { get; set; }
+
+ [XmlElement("seismic_res_fx_plus_mx")]
+ public LoadCombinationCaseBase SeismicResFxPlusMx { get; set; }
+
+ [XmlElement("seismic_res_fx_minus_mx")]
+ public LoadCombinationCaseBase SeismicResFxMinusMx { get; set; }
+
+ [XmlElement("seismic_res_fy_plus_my")]
+ public LoadCombinationCaseBase SeismicResFyPlusMy { get; set; }
+
+ [XmlElement("seismic_res_fy_minus_my")]
+ public LoadCombinationCaseBase SeismicResFyMinusMy { get; set; }
+
+ [XmlElement("seismic_res_fz")]
+ public LoadCombinationCaseBase SeismicResFz { get; set; }
+
+ // Special load cases of the combination, from FD19
+ [XmlElement("ptc_t0")]
+ public LoadCombinationCaseBase PtcT0 { get; set; }
+
+ [XmlElement("ptc_t8")]
+ public LoadCombinationCaseBase PtcT8 { get; set; }
+
+ // Special load cases of the combination, from FD20
+ [XmlElement("ldcase_pile")]
+ public LoadCombinationCaseBase PileLoadCase { get; set; }
+
+ // Special load cases of the combination, from FD21.0003
+ [XmlElement("cs_case")]
+ public StageLoadCase StageLoadCase { get; set; }
+
[XmlIgnore]
public Calculate.CombItem CombItem { get; set; }
@@ -28,9 +79,6 @@ private LoadCombination()
}
- ///
- /// Internal constructor. Used for GH components and Dynamo nodes.
- ///
public LoadCombination(string name, LoadCombType type, List loadCases, List gammas, Calculate.CombItem combItem = null)
{
Initialize(name, type, combItem);
@@ -95,18 +143,133 @@ public List GetGammas()
}
///
- /// Add LoadCase to LoadCombination.
+ ///
///
- private void AddLoadCase(LoadCase loadCase, double gamma)
+ /// List of pairs of CaseId and gamma values. CaseId may be LoadCase guid, construction stage index description or special case name.
+ public List<(string CaseId, double Gamma)> GetCaseDescriptionAndGammas()
{
- if (this.LoadCaseInLoadCombination(loadCase))
+ var pairs = new List<(string CaseId, double Gamma)>();
+ for (int i = 0; i < ModelLoadCase.Count; i++)
{
- // pass
+ pairs.Add((ModelLoadCase[i].Guid.ToString(), ModelLoadCase[i].Gamma));
}
- else
+
+ if (SeismicMax != null)
+ pairs.Add(("Seismic max.", SeismicMax.Gamma));
+ if (SeismicResFxMinusMx != null)
+ pairs.Add(("Seismic fx-mx", SeismicResFxMinusMx.Gamma));
+ if (SeismicResFxPlusMx != null)
+ pairs.Add(("Seismic fx+mx", SeismicResFxPlusMx.Gamma));
+ if (SeismicResFyMinusMy != null)
+ pairs.Add(("Seismic fy-my", SeismicResFyMinusMy.Gamma));
+ if (SeismicResFyPlusMy != null)
+ pairs.Add(("Seismic fy+my", SeismicResFyPlusMy.Gamma));
+ if (SeismicResFz != null)
+ pairs.Add(("Seismic fz", SeismicResFz.Gamma));
+
+ if (PtcT0 != null)
+ pairs.Add(("Ptc T0", PtcT0.Gamma));
+ if (PtcT8 != null)
+ pairs.Add(("Ptc T8", PtcT8.Gamma));
+
+ if (PileLoadCase != null)
+ pairs.Add(("pile loadcase", PileLoadCase.Gamma));
+
+ if (StageLoadCase != null)
+ pairs.Add((StageLoadCase._stageType, StageLoadCase.Gamma));
+
+ return pairs;
+ }
+
+
+
+ public List<(LoadCase Case, double Gamma, string CaseType)> GetLoadCasesAndGammas()
+ {
+ var pairs = new List<(LoadCase Case, double Gamma, string CaseType)>();
+ for (int i = 0; i < ModelLoadCase.Count; i++)
{
- this.ModelLoadCase.Add(new ModelLoadCase(loadCase, gamma));
+ pairs.Add((
+ ModelLoadCase[i].LoadCase,
+ ModelLoadCase[i].Gamma,
+ ModelLoadCase[i].IsMovingLoadLoadCase ? "Moving load case" : "Load case"
+ ));
}
+ return pairs;
+ }
+ public List<(string Case, double Gamma)> GetSpecialCasesAndGammas()
+ {
+ var pairs = new List<(string Case, double Gamma)>();
+
+ if (SeismicMax != null)
+ pairs.Add(("Seismic max.", SeismicMax.Gamma));
+ if (SeismicResFxMinusMx != null)
+ pairs.Add(("Seis res, Fx-Mx", SeismicResFxMinusMx.Gamma));
+ if (SeismicResFxPlusMx != null)
+ pairs.Add(("Seis res, Fx+Mx", SeismicResFxPlusMx.Gamma));
+ if (SeismicResFyMinusMy != null)
+ pairs.Add(("Seis res, Fy-My", SeismicResFyMinusMy.Gamma));
+ if (SeismicResFyPlusMy != null)
+ pairs.Add(("Seis res, Fy+My", SeismicResFyPlusMy.Gamma));
+ if (SeismicResFz != null)
+ pairs.Add(("Seis res, Fz", SeismicResFz.Gamma));
+
+ if (PtcT0 != null)
+ pairs.Add(("PTC T0", PtcT0.Gamma));
+ if (PtcT8 != null)
+ pairs.Add(("PTC T8", PtcT8.Gamma));
+
+ if (PileLoadCase != null)
+ pairs.Add(("Neg. Shaft friction", PileLoadCase.Gamma));
+
+ return pairs;
+ }
+
+ public List<(object Case, double Gamma, string CaseType)> GetCaseAndGammas()
+ {
+ var pairs = new List<(object, double, string)>();
+ pairs.AddRange(
+ GetLoadCasesAndGammas()
+ .Select((t) => { return ((object)t.Case, t.Gamma, t.CaseType); })
+ .ToList());
+ pairs.AddRange(
+ GetSpecialCasesAndGammas()
+ .Select((t) => { return ((object)t.Case, t.Gamma, "Special load case"); })
+ .ToList());
+
+ if (StageLoadCase is null) return pairs;
+
+ if (StageLoadCase.IsFinalStage)
+ pairs.Add(("Final construction stage", StageLoadCase.Gamma, "Special load case"));
+ else
+ pairs.Add((StageLoadCase.Stage, StageLoadCase.Gamma, "Stage"));
+
+ return pairs;
+ }
+
+ ///
+ /// Add LoadCase to LoadCombination.
+ ///
+ public void AddLoadCase(LoadCase loadCase, double gamma)
+ {
+ if (this.LoadCaseInLoadCombination(loadCase))
+ return;
+
+ this.ModelLoadCase.Add(new ModelLoadCase(loadCase, gamma));
+ }
+
+ public void SetStageLoadCase(Stage stage, double gamma)
+ {
+ this.StageLoadCase = new StageLoadCase(stage, gamma);
+ }
+
+ public void SetFinalStageLoadCase(double gamma)
+ {
+ this.StageLoadCase = StageLoadCase.FinalStage(gamma);
+ }
+
+ public void RemoveStageLoadCase()
+ {
+ this.StageLoadCase = null;
}
///
@@ -114,14 +277,7 @@ private void AddLoadCase(LoadCase loadCase, double gamma)
///
private bool LoadCaseInLoadCombination(LoadCase loadCase)
{
- foreach (ModelLoadCase elem in this.ModelLoadCase)
- {
- if (elem.Guid == loadCase.Guid)
- {
- return true;
- }
- }
- return false;
+ return this.ModelLoadCase.Any(elem => elem.Guid == loadCase.Guid);
}
public override string ToString()
@@ -131,14 +287,23 @@ public override string ToString()
const int gammaSpace = -3;
var repr = "";
repr += $"{this.Name,space} {this.Type}\n";
- foreach (var item in this.ModelLoadCase)
+
+ var casesAndGammas = GetCaseAndGammas();
+
+ foreach (var (@case, gamma, type) in casesAndGammas)
{
- if(item.LoadCase == null) { return base.ToString(); } // Deserialisation can not get the loadcase name from the object. Only the GUID
+ if (@case is null) { return base.ToString(); } // Deserialisation can not get the loadcase name from the object.
+
+ if (@case.GetType() == typeof(LoadCase))
+ {
+ var lc = (LoadCase)@case;
+ repr += $"{"",space - 1}{gamma,gammaSpace} {lc.Name,caseNameSpace}\n";
+ }
else
- repr += $"{"",space - 1}{item.LoadCase.Name,caseNameSpace} {item.Gamma,gammaSpace}\n";
+ repr += $"{"",space - 1}{gamma,gammaSpace} {@case,caseNameSpace}\n";
}
-
+
return repr;
}
}
-}
\ No newline at end of file
+}
diff --git a/FemDesign.Core/Loads/LoadCombinationCaseBase.cs b/FemDesign.Core/Loads/LoadCombinationCaseBase.cs
new file mode 100644
index 000000000..1ab0d12b0
--- /dev/null
+++ b/FemDesign.Core/Loads/LoadCombinationCaseBase.cs
@@ -0,0 +1,21 @@
+// https://strusoft.com/
+
+using System.Xml.Serialization;
+
+namespace FemDesign.Loads
+{
+ public class LoadCombinationCaseBase // spec_load_case_item
+ {
+ [XmlAttribute("gamma")]
+ public double Gamma;
+
+ ///
+ /// Parameterless constructor for serialization
+ ///
+ protected LoadCombinationCaseBase() { }
+ public LoadCombinationCaseBase(double gamma)
+ {
+ Gamma = gamma;
+ }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Core/Loads/LoadGroupPermanent.cs b/FemDesign.Core/Loads/LoadGroupPermanent.cs
index d9481b317..3cc9c6551 100644
--- a/FemDesign.Core/Loads/LoadGroupPermanent.cs
+++ b/FemDesign.Core/Loads/LoadGroupPermanent.cs
@@ -50,6 +50,7 @@ private LoadGroupPermanent() { }
/// List of load cases in the load group
/// Specifies how to condider the load cases in combinations
/// Xi-factor used in the combinations, see EN 1990.
+ ///
public LoadGroupPermanent(double standardFavourable,
double standardUnfavourable, double accidentalFavourable,
double accidentalUnfavourable, List loadCases,
diff --git a/FemDesign.Core/Loads/ModelLoadCase.cs b/FemDesign.Core/Loads/ModelLoadCase.cs
index f43419ae9..a2ec18f39 100644
--- a/FemDesign.Core/Loads/ModelLoadCase.cs
+++ b/FemDesign.Core/Loads/ModelLoadCase.cs
@@ -10,7 +10,7 @@ namespace FemDesign.Loads
/// load_case (child of load_combination_type)
///
[Serializable]
- public partial class ModelLoadCase
+ public partial class ModelLoadCase : LoadCombinationCaseBase
{
[XmlAttribute("guid")]
public string _guid = string.Empty;
@@ -25,8 +25,9 @@ public Guid Guid
else
return new Guid(_guid);
}
- set {
- _guid = IsMovingLoadLoadCase ? _guid = $"{value}#{Index}": _guid = value.ToString();
+ set
+ {
+ _guid = IsMovingLoadLoadCase ? _guid = $"{value}#{Index}" : _guid = value.ToString();
}
}
[XmlIgnore]
@@ -53,8 +54,6 @@ public int Index
public bool IsMovingLoadLoadCase { get { return _guid.IndexOf('#') != -1; } }
[XmlIgnore]
public string IndexedGuid => _guid;
- [XmlAttribute("gamma")]
- public double Gamma { get; set; } // double
[XmlIgnore]
public LoadCase LoadCase { get; set; }
public ModelLoadCase()
diff --git a/FemDesign.Core/Loads/ModelLoadCaseInGroup.cs b/FemDesign.Core/Loads/ModelLoadCaseInGroup.cs
index 085704e8b..5bfcafe09 100644
--- a/FemDesign.Core/Loads/ModelLoadCaseInGroup.cs
+++ b/FemDesign.Core/Loads/ModelLoadCaseInGroup.cs
@@ -23,6 +23,7 @@ private ModelLoadCaseInGroup() { }
/// Public constructor.
///
/// LoadCase guid reference.
+ ///
public ModelLoadCaseInGroup(System.Guid guid, LoadGroupBase parentLoadGroup)
{
this.Guid = guid;
diff --git a/FemDesign.Core/Loads/PointLoad.cs b/FemDesign.Core/Loads/PointLoad.cs
index 0d1533075..04b38d2b2 100644
--- a/FemDesign.Core/Loads/PointLoad.cs
+++ b/FemDesign.Core/Loads/PointLoad.cs
@@ -27,7 +27,7 @@ private PointLoad()
///
/// Internal constructor accessed by static methods.
///
- public PointLoad(Geometry.Point3d point, Geometry.Vector3d force, LoadCase loadCase, string comment = "", ForceLoadType type = ForceLoadType.Force)
+ public PointLoad(Geometry.Point3d point, Geometry.Vector3d force, LoadCase loadCase, string comment, ForceLoadType type)
{
this.EntityCreated();
this.LoadCaseGuid = loadCase.Guid;
diff --git a/FemDesign.Core/Loads/StageLoadCase.cs b/FemDesign.Core/Loads/StageLoadCase.cs
new file mode 100644
index 000000000..61ce4d7c4
--- /dev/null
+++ b/FemDesign.Core/Loads/StageLoadCase.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace FemDesign.Loads
+{
+ public class StageLoadCase : LoadCombinationCaseBase
+ {
+ [XmlAttribute("type")]
+ public string _stageType;
+
+ private Stage _stage;
+ [XmlIgnore]
+ public Stage Stage { get { return _stage; } set { _stage = value; _stageType = $"cs.{value.Id}"; } }
+
+ private const string _finalStage = "final_cs";
+ public bool IsFinalStage => _stageType == _finalStage;
+ public int StageIndex => IsFinalStage ? -1 : int.Parse(_stageType.Substring(3));
+
+ ///
+ /// Parameterless constructor for serialization
+ ///
+ private StageLoadCase()
+ {
+ }
+
+ public StageLoadCase(Stage stage, double gamma)
+ {
+ Gamma = gamma;
+ Stage = stage;
+ }
+
+ public static StageLoadCase FinalStage(double gamma)
+ {
+ return new StageLoadCase()
+ {
+ _stageType = _finalStage,
+ Gamma = gamma
+ };
+ }
+ }
+}
diff --git a/FemDesign.Core/Materials/Material.cs b/FemDesign.Core/Materials/Material.cs
index 17b71a9c4..b1346d43b 100644
--- a/FemDesign.Core/Materials/Material.cs
+++ b/FemDesign.Core/Materials/Material.cs
@@ -68,7 +68,7 @@ public static Material GetMaterialByNameOrIndex(List materials, dynami
}
catch (Exception ex)
{
- throw new Exception($"{materialInput} does not exist!");
+ throw new Exception($"{materialInput} does not exist!", ex);
}
}
else
@@ -79,7 +79,7 @@ public static Material GetMaterialByNameOrIndex(List materials, dynami
}
catch (Exception ex)
{
- throw new System.Exception($"Materials List only contains {materials.Count} item. {materialInput} is out of range!");
+ throw new System.Exception($"Materials List only contains {materials.Count} item. {materialInput} is out of range!", ex);
}
}
return material;
diff --git a/FemDesign.Core/Materials/MaterialDatabase.cs b/FemDesign.Core/Materials/MaterialDatabase.cs
index 287f23b71..2252d280d 100644
--- a/FemDesign.Core/Materials/MaterialDatabase.cs
+++ b/FemDesign.Core/Materials/MaterialDatabase.cs
@@ -230,7 +230,13 @@ public static MaterialDatabase GetDefault(string countryCode = "S")
public (List steel, List concrete, List timber, List reinforcement, List stratum, List custom) ByType()
{
- var materialDataBaseList = this.Materials.Material.Concat(this.ReinforcingMaterials.Material);
+ var materialDataBaseList = new List();
+ if (this.ReinforcingMaterials != null)
+ {
+ materialDataBaseList = this.Materials.Material.Concat(this.ReinforcingMaterials.Material).ToList();
+ }
+ else
+ materialDataBaseList.AddRange(this.Materials.Material);
var steel = new List();
var timber = new List();
diff --git a/FemDesign.Core/Model/Model.cs b/FemDesign.Core/Model/Model.cs
index 6e63ff6a5..a41f0b2ba 100644
--- a/FemDesign.Core/Model/Model.cs
+++ b/FemDesign.Core/Model/Model.cs
@@ -125,6 +125,7 @@ private Model()
/// Load cases
/// Load combinations
/// Load groups
+ /// Construction stages object instance.
public Model(Country country, List elements = null, List loads = null, List loadCases = null, List loadCombinations = null, List loadGroups = null, ConstructionStages constructionStage = null)
{
Initialize(country);
@@ -248,6 +249,8 @@ public static Model DeserializeFromFilePath(string filePath)
model.GetLineConnections();
if (model.ConstructionStages != null && model.ConstructionStages.Stages.Any())
model.GetConstructionStages();
+ if (model.Entities?.Loads?.LoadCombinations != null && model.Entities.Loads.LoadCombinations.Any())
+ model.GetLoadCombinations();
return model;
}
@@ -263,13 +266,20 @@ public void SerializeModel(string filePath)
filePath = System.IO.Path.Combine(currentDirectory, "myModel.struxml");
}
- // check file extension
+ // Relavive paths will be converted to full paths
+ filePath = System.IO.Path.GetFullPath(filePath);
+
+ // If path has no file extension "struxml" will be used
+ if (Path.GetExtension(filePath) == "")
+ filePath = Path.ChangeExtension(filePath, "struxml");
+
+ // Check file extension
if (Path.GetExtension(filePath) != ".struxml")
{
throw new System.ArgumentException("File extension must be .struxml! Model.SerializeModel failed.");
}
- // serialize
+ // Serialize
XmlSerializer serializer = new XmlSerializer(typeof(Model));
using (TextWriter writer = new StreamWriter(filePath))
{
@@ -287,12 +297,12 @@ public void SerializeModel(string filePath)
///
public static (Model fdModel, IEnumerable results) ReadStr(string strPath, IEnumerable resultTypes, bool killProcess = false, bool endSession = true, bool checkOpenFiles = true)
{
- if(resultTypes != null)
- {
+ if (resultTypes != null)
+ {
var notAResultType = resultTypes.Where(r => !typeof(Results.IResult).IsAssignableFrom(r)).FirstOrDefault();
if (notAResultType != null)
throw new ArgumentException($"{notAResultType.Name} is not a result type. (It does not inherit from {typeof(FemDesign.Results.IResult).FullName})");
- }
+ }
var fdScript = Calculate.FdScript.ExtractResults(strPath, resultTypes);
@@ -337,7 +347,7 @@ public void Open(string filePath = null, bool closeOpenWindows = false)
this.FdApp.OpenStruxml(filePath, closeOpenWindows);
}
- public void RunAnalysis(Calculate.Analysis analysis, IEnumerable resultTypes = null, Results.UnitResults units = null, string struxmlPath = null, string docxTemplatePath = null, bool endSession = false, bool closeOpenWindows = false, Calculate.CmdGlobalCfg cmdGlobalCfg = null)
+ public bool RunAnalysis(Calculate.Analysis analysis, IEnumerable resultTypes = null, Results.UnitResults units = null, string struxmlPath = null, string docxTemplatePath = null, bool endSession = false, bool closeOpenWindows = false, Calculate.CmdGlobalCfg cmdGlobalCfg = null)
{
if (struxmlPath == null)
{
@@ -353,10 +363,10 @@ public void RunAnalysis(Calculate.Analysis analysis, IEnumerable resultTyp
this.SerializeModel(struxmlPath);
analysis.SetLoadCombinationCalculationParameters(this);
- this.FdApp.RunAnalysis(struxmlPath, analysis, bscPath, docxTemplatePath, endSession, closeOpenWindows, cmdGlobalCfg);
+ return this.FdApp.RunAnalysis(struxmlPath, analysis, bscPath, docxTemplatePath, endSession, closeOpenWindows, cmdGlobalCfg);
}
- public void RunDesign(Calculate.CmdUserModule mode, Calculate.Analysis analysis, Calculate.Design design, IEnumerable resultTypes = null, Results.UnitResults units = null, string struxmlPath = null, string docxTemplatePath = null, bool endSession = false, bool closeOpenWindows = false, Calculate.CmdGlobalCfg cmdGlobalCfg = null)
+ public bool RunDesign(Calculate.CmdUserModule mode, Calculate.Analysis analysis, Calculate.Design design, IEnumerable resultTypes = null, Results.UnitResults units = null, string struxmlPath = null, string docxTemplatePath = null, bool endSession = false, bool closeOpenWindows = false, Calculate.CmdGlobalCfg cmdGlobalCfg = null)
{
if (struxmlPath == null)
{
@@ -375,7 +385,7 @@ public void RunDesign(Calculate.CmdUserModule mode, Calculate.Analysis analysis,
this.SerializeModel(struxmlPath);
analysis.SetLoadCombinationCalculationParameters(this);
- this.FdApp.RunDesign(mode.ToString(), struxmlPath, analysis, design, bscPath, docxTemplatePath, endSession, closeOpenWindows, cmdGlobalCfg);
+ return this.FdApp.RunDesign(mode.ToString(), struxmlPath, analysis, design, bscPath, docxTemplatePath, endSession, closeOpenWindows, cmdGlobalCfg);
}
///
@@ -1082,6 +1092,7 @@ private bool DiaphragmInModel(ModellingTools.Diaphragm obj)
/// Add Load to Model.
///
/// PointLoad, LineLoad, PressureLoad, SurfaceLoad
+ ///
private void AddLoad(object obj, bool overwrite)
{
if (obj == null)
@@ -1547,29 +1558,32 @@ public void AddLoadCases(List loadCases, bool overwrite = true)
///
/// Add LoadCase to Model.
///
- private void AddLoadCase(Loads.LoadCase obj, bool overwrite)
+ private void AddLoadCase(Loads.LoadCase loadCase, bool overwrite)
{
+ if (loadCase is null)
+ throw new ArgumentNullException("loadCase");
+
// in model?
- bool inModel = this.LoadCaseInModel(obj);
+ bool inModel = this.LoadCaseInModel(loadCase);
// in model, don't overwrite?
if (inModel && !overwrite)
{
- throw new System.ArgumentException($"{obj.GetType().FullName} with guid: {obj.Guid} has already been added to model. Are you adding the same element twice?");
+ throw new System.ArgumentException($"{loadCase.GetType().FullName} with guid: {loadCase.Guid} has already been added to model. Are you adding the same element twice?");
}
// in model, overwrite
else if (inModel && overwrite)
{
- this.Entities.Loads.LoadCases.RemoveAll(x => x.Guid == obj.Guid);
+ this.Entities.Loads.LoadCases.RemoveAll(x => x.Guid == loadCase.Guid);
}
// add load case
- if (this.LoadCaseNameTaken(obj))
+ if (this.LoadCaseNameTaken(loadCase))
{
- obj.Name = obj.Name + " (1)";
+ loadCase.Name = loadCase.Name + " (1)";
}
- this.Entities.Loads.LoadCases.Add(obj);
+ this.Entities.Loads.LoadCases.Add(loadCase);
}
///
@@ -1659,29 +1673,32 @@ public void AddLoadGroupTable(List generalLoadGroup
///
/// Add LoadCombination to Model.
///
- private void AddLoadCombination(Loads.LoadCombination obj, bool overwrite)
+ private void AddLoadCombination(Loads.LoadCombination loadCombination, bool overwrite)
{
+ if (loadCombination is null)
+ throw new ArgumentNullException("loadCombination");
+
// in model?
- bool inModel = this.LoadCombinationInModel(obj);
+ bool inModel = this.LoadCombinationInModel(loadCombination);
// in model, don't overwrite
if (inModel && !overwrite)
{
- throw new System.ArgumentException($"{obj.GetType().FullName} with guid: {obj.Guid} has already been added to model. Are you adding the same element twice?");
+ throw new System.ArgumentException($"{loadCombination.GetType().FullName} with guid: {loadCombination.Guid} has already been added to model. Are you adding the same element twice?");
}
// in model, overwrite
else if (inModel && overwrite)
{
- this.Entities.Loads.LoadCombinations.RemoveAll(x => x.Guid == obj.Guid);
+ this.Entities.Loads.LoadCombinations.RemoveAll(x => x.Guid == loadCombination.Guid);
}
// add load combination
- if (this.LoadCombinationNameTaken(obj))
+ if (this.LoadCombinationNameTaken(loadCombination))
{
- obj.Name = obj.Name + " (1)";
+ loadCombination.Name = loadCombination.Name + " (1)";
}
- this.Entities.Loads.LoadCombinations.Add(obj);
+ this.Entities.Loads.LoadCombinations.Add(loadCombination);
}
///
@@ -1868,6 +1885,7 @@ private bool PredefRigidityInModel(Releases.RigidityDataLibType3 obj)
/// Add StructureGrid (axis or storey) to model.
///
/// Axis, Storey
+ ///
private void AddStructureGrid(object obj, bool overwrite)
{
if (obj == null)
@@ -1892,6 +1910,7 @@ private void AddStructureGrid(object obj, bool overwrite)
/// Add axis to entities.
///
/// Axis.
+ ///
private void AddAxis(StructureGrid.Axis obj, bool overwrite)
{
// check if axes in entities
@@ -1940,6 +1959,7 @@ private bool AxisInModel(StructureGrid.Axis obj)
/// Add Storey to Model.
///
/// Storey.
+ ///
private void AddStorey(StructureGrid.Storey obj, bool overwrite)
{
// check if storeys in entities
@@ -2064,6 +2084,7 @@ private bool BarReinforcementInModel(Reinforcement.BarReinforcement obj)
/// Add SurfaceReinforcement(s) from Slab to Model.
///
///
+ ///
private void AddSurfaceReinforcements(Shells.Slab obj, bool overwrite)
{
foreach (Reinforcement.SurfaceReinforcement surfaceReinforcement in obj.SurfaceReinforcement)
@@ -2166,6 +2187,7 @@ private bool SurfaceReinforcementParametersInModel(Reinforcement.SurfaceReinforc
/// Add Support to Model
///
/// PointSupport, LineSupport or SurfaceSupport
+ ///
private void AddSupport(ISupportElement obj, bool overwrite)
{
if (obj == null)
@@ -2420,6 +2442,48 @@ private void AddSurfaceSupportLibItem(Releases.RigidityDataLibType1 obj, bool ov
this.SurfaceSupportTypes.PredefinedTypes.Add(obj);
}
+
+ ///
+ /// Add SurfaceSupport to Model.
+ ///
+ private void AddStiffnessPoint(Supports.StiffnessPoint obj, bool overwrite)
+ {
+ // in model?
+ bool inModel = this.StiffnessPointInModel(obj);
+
+ // in model, don't overwrite
+ if (inModel && !overwrite)
+ {
+ throw new System.ArgumentException($"{obj.GetType().FullName} with guid: {obj.Guid} has already been added to model. Are you adding the same element twice?");
+ }
+
+ // in model, overwrite
+ else if (inModel && overwrite)
+ {
+ this.Entities.Supports.StiffnessPoint.RemoveAll(x => x.Guid == obj.Guid);
+ }
+
+ // add obj
+ this.Entities.Supports.StiffnessPoint.Add(obj);
+ }
+
+
+ ///
+ /// Check if StiffnessPoint in Model.
+ ///
+ private bool StiffnessPointInModel(Supports.StiffnessPoint obj)
+ {
+ foreach (Supports.StiffnessPoint elem in this.Entities.Supports.StiffnessPoint)
+ {
+ if (elem.Guid == obj.Guid)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
///
/// Add Material to Model.
///
@@ -2797,6 +2861,8 @@ public Model AddElements(IEnumerable elements, bool overwrite = true) wher
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exeption)
{
+ if (item == null)
+ throw new ArgumentNullException("Can not add null element to model.", exeption);
throw new System.NotImplementedException($"Class Model don't have a method AddEntity that accepts {item.GetType()}. ", exeption);
}
}
@@ -2819,7 +2885,16 @@ public Model AddLoads(IEnumerable elements, bool overwrite = true) where T
foreach (var item in elements)
{
- AddEntity(item as dynamic, overwrite);
+ try
+ {
+ AddEntity(item as dynamic, overwrite);
+ }
+ catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exeption)
+ {
+ if (item == null)
+ throw new ArgumentNullException("Can not add null load to model.", exeption);
+ throw new System.NotImplementedException($"Class Model don't have a method AddEntity that accepts {item.GetType()}. ", exeption);
+ }
}
return this;
@@ -2842,7 +2917,16 @@ public Model AddSupports(IEnumerable elements, bool overwrite = true) wher
foreach (var item in elements)
{
- AddEntity(item as dynamic, overwrite);
+ try
+ {
+ AddEntity(item as dynamic, overwrite);
+ }
+ catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exeption)
+ {
+ if (item == null)
+ throw new ArgumentNullException("Can not add null support to model.", exeption);
+ throw new System.NotImplementedException($"Class Model don't have a method AddEntity that accepts {item.GetType()}. ", exeption);
+ }
}
return this;
@@ -2868,6 +2952,7 @@ public Model AddSupports(IEnumerable elements, bool overwrite = true) wher
private void AddEntity(Supports.PointSupport obj, bool overwrite) => AddPointSupport(obj, overwrite);
private void AddEntity(Supports.LineSupport obj, bool overwrite) => AddLineSupport(obj, overwrite);
private void AddEntity(Supports.SurfaceSupport obj, bool overwrite) => AddSurfaceSupport(obj, overwrite);
+ private void AddEntity(Supports.StiffnessPoint obj, bool overwrite) => AddStiffnessPoint(obj, overwrite);
private void AddEntity(StructureGrid.Axis axis, bool overwrite) => AddAxis(axis, overwrite);
private void AddEntity(StructureGrid.Storey storey, bool overwrite) => AddStorey(storey, overwrite);
@@ -3355,7 +3440,9 @@ internal void GetConstructionStages()
{
i++; // Starts at 1
stage.Id = i;
- stage.Elements = elementsPerStage[i];
+
+ if (elementsPerStage.ContainsKey(i))
+ stage.Elements = elementsPerStage[i];
if (stage.ActivatedLoadCases != null)
{
@@ -3372,6 +3459,27 @@ internal void GetConstructionStages()
}
}
}
+ internal void GetLoadCombinations()
+ {
+ var loadCasesMap = this.Entities.Loads.LoadCases?.ToDictionary(lc => lc.Guid);
+ var stageMap = this.ConstructionStages?.Stages?.ToDictionary(s => s.Id);
+
+ foreach (var lComb in this.Entities.Loads.LoadCombinations)
+ {
+ foreach (Loads.ModelLoadCase mLoadCase in lComb.ModelLoadCase)
+ {
+ if (mLoadCase.IsMovingLoadLoadCase)
+ continue;
+
+ mLoadCase.LoadCase = loadCasesMap[mLoadCase.Guid].DeepClone();
+ }
+
+ if (lComb.StageLoadCase != null && lComb.StageLoadCase.IsFinalStage == false)
+ {
+ lComb.StageLoadCase.Stage = stageMap[lComb.StageLoadCase.StageIndex].DeepClone();
+ }
+ }
+ }
#endregion
}
}
diff --git a/FemDesign.Core/ModellingTools/ConnectedLines.cs b/FemDesign.Core/ModellingTools/ConnectedLines.cs
index 082978dda..905ea5c6d 100644
--- a/FemDesign.Core/ModellingTools/ConnectedLines.cs
+++ b/FemDesign.Core/ModellingTools/ConnectedLines.cs
@@ -6,10 +6,11 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class ConnectedLines: EntityBase, IStructureElement
+ public partial class ConnectedLines: NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int _instance = 0;
+ private static int _connectedLineInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_connectedLineInstances;
[XmlElement("edge" , Order = 1)]
public Geometry.Edge[] Edges { get; set; }
@@ -58,23 +59,6 @@ public Releases.RigidityDataLibType3 PredefRigidity
[XmlElement("ref", Order = 7)]
public GuidListType[] References { get; set; }
-
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- _instance++;
- this._name = $"{RestrictedString.Length(value, 50)}.{_instance.ToString()}";
- }
- }
[XmlAttribute("moving_local")]
public bool MovingLocal { get; set; }
@@ -131,7 +115,7 @@ public ConnectedLines(Geometry.Edge firstEdge, Geometry.Edge secondEdge, Geometr
this.LocalY = localY;
this.Rigidity = rigidity;
this.References = references;
- this.Name = identifier;
+ this.Identifier = identifier;
this.MovingLocal = movingLocal;
this.InterfaceStart = interfaceStart;
this.InterfaceEnd = interfaceEnd;
diff --git a/FemDesign.Core/ModellingTools/ConnectedPoints.cs b/FemDesign.Core/ModellingTools/ConnectedPoints.cs
index ea1f4afb3..c20b139b6 100644
--- a/FemDesign.Core/ModellingTools/ConnectedPoints.cs
+++ b/FemDesign.Core/ModellingTools/ConnectedPoints.cs
@@ -9,10 +9,11 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class ConnectedPoints : EntityBase, IStructureElement
+ public partial class ConnectedPoints : NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int _instance = 0;
+ private static int _connectedPointInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_connectedPointInstances;
[XmlElement("point", Order = 1)]
public Point3d[] _points;
@@ -74,23 +75,6 @@ public RigidityDataLibType2 PredefRigidity
[XmlElement("ref", Order = 6)]
public GuidListType[] References { get; set; }
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- _instance++;
- this._name = $"{RestrictedString.Length(value, 50)}.{_instance.ToString()}";
- }
- }
-
[XmlAttribute("interface")]
public double _interface;
@@ -179,7 +163,7 @@ private void Initialize(Point3d firstPoint, Point3d secondPoint, RigidityDataTyp
this.LocalY = Vector3d.UnitY;
this.Rigidity = rigidity;
this.References = references;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
}
diff --git a/FemDesign.Core/ModellingTools/Diaphragm.cs b/FemDesign.Core/ModellingTools/Diaphragm.cs
index cb4b5ef40..3beafa501 100644
--- a/FemDesign.Core/ModellingTools/Diaphragm.cs
+++ b/FemDesign.Core/ModellingTools/Diaphragm.cs
@@ -4,10 +4,11 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class Diaphragm: EntityBase, IStructureElement, IStageElement
+ public partial class Diaphragm: NamedEntityBase, IStructureElement, IStageElement
{
[XmlIgnore]
- private static int _instance = 0;
+ private static int _diaphragmInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_diaphragmInstances;
[XmlElement("region", Order = 1)]
public Geometry.Region Region { get; set; }
@@ -18,20 +19,6 @@ public partial class Diaphragm: EntityBase, IStructureElement, IStageElement
[XmlAttribute("stage")]
public int StageId { get; set; } = 1;
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- Diaphragm._instance++;
- this._name = $"{RestrictedString.Length(value, 50)}.{_instance}";
- }
- }
-
private Diaphragm()
{
@@ -44,7 +31,7 @@ public Diaphragm(Geometry.Region region, string identifier)
// add properties
this.Region = region;
- this.Name = identifier;
+ this.Identifier = identifier;
}
}
}
diff --git a/FemDesign.Core/ModellingTools/FictitiousBar.cs b/FemDesign.Core/ModellingTools/FictitiousBar.cs
index ee5f5baa5..83b04f5a6 100644
--- a/FemDesign.Core/ModellingTools/FictitiousBar.cs
+++ b/FemDesign.Core/ModellingTools/FictitiousBar.cs
@@ -7,10 +7,11 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class FictitiousBar: EntityBase, IStructureElement
+ public partial class FictitiousBar: NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int Instance = 0;
+ private static int _ficticiousBarInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_ficticiousBarInstances;
[XmlElement("edge", Order = 1)]
public Geometry.Edge Edge { get; set; }
@@ -113,23 +114,6 @@ public Bars.Connectivity EndConnectivity
}
}
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- FictitiousBar.Instance++;
- this._name = RestrictedString.Length(value, 40) + "." + FictitiousBar.Instance.ToString();
- }
- }
-
[XmlAttribute("AE")]
public double _ae;
@@ -205,14 +189,14 @@ private FictitiousBar()
///
/// Internal constructor.
///
- public FictitiousBar(Geometry.Edge edge, Geometry.Vector3d localY, Bars.Connectivity startConnectivity, Bars.Connectivity endConnectivity, string name, double ae, double itg, double i1e, double i2e)
+ public FictitiousBar(Geometry.Edge edge, Geometry.Vector3d localY, Bars.Connectivity startConnectivity, Bars.Connectivity endConnectivity, string identifier, double ae, double itg, double i1e, double i2e)
{
this.EntityCreated();
this.Edge = edge;
this.LocalY = localY;
this.StartConnectivity = startConnectivity;
this.EndConnectivity = endConnectivity;
- this.Name = name;
+ this.Identifier = identifier;
this.AE = ae;
this.ItG = itg;
this.I1E = i1e;
@@ -221,7 +205,7 @@ public FictitiousBar(Geometry.Edge edge, Geometry.Vector3d localY, Bars.Connecti
///
/// Orient this object's coordinate system to GCS.
- ///
+ ///
public void OrientCoordinateSystemToGCS()
{
var cs = this.CoordinateSystem;
diff --git a/FemDesign.Core/ModellingTools/FictitiousShell.cs b/FemDesign.Core/ModellingTools/FictitiousShell.cs
index 67cd1f1a8..b54026674 100644
--- a/FemDesign.Core/ModellingTools/FictitiousShell.cs
+++ b/FemDesign.Core/ModellingTools/FictitiousShell.cs
@@ -6,11 +6,13 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class FictitiousShell: EntityBase, IStructureElement
+ public partial class FictitiousShell: NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int Instance = 0;
+ private static int _ficticiousShellInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_ficticiousShellInstances;
+
[XmlIgnore]
private Geometry.CoordinateSystem _coordinateSystem;
@@ -128,26 +130,6 @@ public Geometry.Vector3d LocalZ
[XmlElement("shear_stiffness", Order=7)]
public StiffnessMatrix2Type ShearStiffness { get; set; }
- ///
- /// Identifier. Default FS.
- ///
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- FictitiousShell.Instance++;
- this._name = RestrictedString.Length(value, 40) + "." + FictitiousShell.Instance.ToString();
- }
- }
-
///
/// Density in t/m2
///
@@ -285,6 +267,7 @@ private FictitiousShell()
///
///
///
+ ///
public FictitiousShell(Geometry.Region region, StiffnessMatrix4Type membraneStiffness, StiffnessMatrix4Type flexuralStiffness, StiffnessMatrix2Type shearStiffness, double density, double t1, double t2, double alpha1, double alpha2, bool ignoreInStImpCalc, double meshSize, string identifier)
{
this.EntityCreated();
@@ -300,7 +283,7 @@ public FictitiousShell(Geometry.Region region, StiffnessMatrix4Type membraneStif
this.Alpha2 = alpha2;
this.IgnoreInStImpCalculation = ignoreInStImpCalc;
this.MeshSize = meshSize;
- this.Name = identifier;
+ this.Identifier = identifier;
}
///
diff --git a/FemDesign.Core/ModellingTools/SurfaceConnection.cs b/FemDesign.Core/ModellingTools/SurfaceConnection.cs
index 3574ff2f7..0d0b892bc 100644
--- a/FemDesign.Core/ModellingTools/SurfaceConnection.cs
+++ b/FemDesign.Core/ModellingTools/SurfaceConnection.cs
@@ -6,10 +6,11 @@
namespace FemDesign.ModellingTools
{
[System.Serializable]
- public partial class SurfaceConnection: EntityBase, IStructureElement
+ public partial class SurfaceConnection: NamedEntityBase, IStructureElement
{
[XmlIgnore]
- private static int _instance = 0;
+ private static int _surfaceConnectionInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_surfaceConnectionInstances;
[XmlElement("region", Order = 1)]
public Geometry.Region Region { get; set; }
@@ -46,23 +47,6 @@ public Releases.RigidityDataLibType1 PredefRigidity
[XmlElement("local_system", Order = 5)]
public Geometry.CoordinateSystem CoordinateSystem { get; set; }
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- _instance++;
- this._name = $"{RestrictedString.Length(value, 50)}.{_instance.ToString()}";
- }
- }
-
[XmlAttribute("distance")]
public double _distance;
diff --git a/FemDesign.Core/Properties/GlobalAssemblyInfo.cs b/FemDesign.Core/Properties/GlobalAssemblyInfo.cs
index 205c3c20a..06c6720ff 100644
--- a/FemDesign.Core/Properties/GlobalAssemblyInfo.cs
+++ b/FemDesign.Core/Properties/GlobalAssemblyInfo.cs
@@ -23,5 +23,5 @@
// Revision
//
-[assembly: AssemblyVersion("21.4.0.0")]
-[assembly: AssemblyFileVersion("21.4.0.0")]
+[assembly: AssemblyVersion("21.5.0.0")]
+[assembly: AssemblyFileVersion("21.5.0.0")]
diff --git a/FemDesign.Core/Reinforcement/HiddenBar.cs b/FemDesign.Core/Reinforcement/HiddenBar.cs
index 156f20451..6cd7a122a 100644
--- a/FemDesign.Core/Reinforcement/HiddenBar.cs
+++ b/FemDesign.Core/Reinforcement/HiddenBar.cs
@@ -6,10 +6,11 @@
namespace FemDesign.Reinforcement
{
[System.Serializable]
- public partial class HiddenBar: EntityBase, IStructureElement
+ public partial class HiddenBar: NamedEntityBase, IStructureElement
{
- private static int _instance = 0;
+ private static int _hiddenBarInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_hiddenBarInstances;
[XmlElement("rectangle", Order = 1)]
public Geometry.RectangleType Rectangle { get; set; }
@@ -20,23 +21,6 @@ public partial class HiddenBar: EntityBase, IStructureElement
[XmlElement("end", Order = 3)]
public string End = "";
- [XmlAttribute("name")]
- public string _name;
-
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- HiddenBar._instance++;
- this._name = RestrictedString.Length(value, 50) + HiddenBar._instance.ToString();
- }
- }
-
[XmlAttribute("base_shell")]
public Guid BaseShell { get; set; }
}
diff --git a/FemDesign.Core/Reinforcement/LongitudinalBar.cs b/FemDesign.Core/Reinforcement/LongitudinalBar.cs
index 7a27c091c..34edd0260 100644
--- a/FemDesign.Core/Reinforcement/LongitudinalBar.cs
+++ b/FemDesign.Core/Reinforcement/LongitudinalBar.cs
@@ -36,8 +36,12 @@ public LongitudinalBar()
///
/// Construct longitudinal bar using start and end distance from bar start
///
+ ///
/// Start anchorage in meters.
/// End anchorage in meters.
+ ///
+ ///
+ ///
public LongitudinalBar(Geometry.Point2d position, double startAnchorage, double endAnchorage, double start, double end, bool auxiliary)
{
this.Position2d = position;
@@ -50,8 +54,13 @@ public LongitudinalBar(Geometry.Point2d position, double startAnchorage, double
///
/// Construct longitudinal bar using start and end param from bar start
///
+ ///
+ ///
/// Start anchorage in meters.
/// End anchorage in meters.
+ ///
+ ///
+ ///
public LongitudinalBar(Bars.Bar bar, Geometry.Point2d position, double startAnchorage, double endAnchorage, double startParam, double endParam, bool auxiliary)
{
this.Position2d = position;
diff --git a/FemDesign.Core/Reinforcement/Ptc.cs b/FemDesign.Core/Reinforcement/Ptc.cs
index fd7d78e0a..1ad7c3b1f 100644
--- a/FemDesign.Core/Reinforcement/Ptc.cs
+++ b/FemDesign.Core/Reinforcement/Ptc.cs
@@ -409,6 +409,8 @@ private Ptc()
///
///
///
+ ///
+ ///
///
///
public Ptc(Bars.Bar bar, PtcShapeType shape, PtcLosses losses, PtcManufacturingType manufacturing, PtcStrandLibType strand, JackingSide jackingSide, double jackingStress, int numberOfStrands = 3, string identifier = "PTC")
@@ -431,6 +433,8 @@ public Ptc(Bars.Bar bar, PtcShapeType shape, PtcLosses losses, PtcManufacturingT
///
///
///
+ ///
+ ///
///
///
public Ptc(Shells.Slab slab, Geometry.LineSegment line, PtcShapeType shape, PtcLosses losses, PtcManufacturingType manufacturing, PtcStrandLibType strand, JackingSide jackingSide, double jackingStress, int numberOfStrands = 3, string identifier = "PTC")
@@ -483,6 +487,7 @@ private PtcStrandLibType()
///
/// Create a custom PTC-strand.
///
+ ///
/// f pk [N/mm2]
/// A p [mm2]
/// E p [N/mm2]
diff --git a/FemDesign.Core/Releases/RigidityDataType0.cs b/FemDesign.Core/Releases/RigidityDataType0.cs
new file mode 100644
index 000000000..479558dd3
--- /dev/null
+++ b/FemDesign.Core/Releases/RigidityDataType0.cs
@@ -0,0 +1,44 @@
+// https://strusoft.com/
+
+using System.Xml.Serialization;
+
+
+namespace FemDesign.Releases
+{
+ ///
+ /// rigidity_data_type1
+ ///
+ [System.Serializable]
+ public partial class RigidityDataType0
+ {
+ [XmlElement("motions", Order = 1)]
+ public Releases.Motions Motions { get; set; }
+ [XmlElement("plastic_limit_forces", Order = 2)]
+ public Releases.MotionsPlasticLimits PlasticLimitForces { get; set; }
+
+ ///
+ /// Parameterless constructor for serialization
+ ///
+ public RigidityDataType0()
+ {
+
+ }
+
+ ///
+ /// Construct RigidityDataType1 with motions only
+ ///
+ public RigidityDataType0(Motions motions)
+ {
+ this.Motions = motions;
+ }
+
+ ///
+ /// Construct RigidityDataType1 with motions and plastic limits forces only
+ ///
+ public RigidityDataType0(Motions motions, MotionsPlasticLimits motionsPlasticLimits)
+ {
+ this.Motions = motions;
+ this.PlasticLimitForces = motionsPlasticLimits;
+ }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Core/Sections/Section.cs b/FemDesign.Core/Sections/Section.cs
index 2a2c78f4f..8341010c5 100644
--- a/FemDesign.Core/Sections/Section.cs
+++ b/FemDesign.Core/Sections/Section.cs
@@ -87,7 +87,7 @@ internal string _sectionName
///
/// Parameterless constructor for serialization
- ///
+ ///
private Section()
{
@@ -95,7 +95,8 @@ private Section()
///
/// Construct a new section
- ///
+ ///
+ [Obsolete("Consider use the other constructor. 'Name' shouldn't be set.")]
public Section(Geometry.RegionGroup regionGroup, string name, string type, Materials.MaterialTypeEnum materialTypeEnum, string groupName, string typeName, string sizeName)
{
this.EntityCreated();
@@ -109,6 +110,22 @@ public Section(Geometry.RegionGroup regionGroup, string name, string type, Mater
this._end = "";
}
+ ///
+ /// Construct a new section
+ ///
+ public Section(Geometry.RegionGroup regionGroup, string type, Materials.MaterialTypeEnum materialTypeEnum, string groupName, string typeName, string sizeName)
+ {
+ this.EntityCreated();
+ this.RegionGroup = regionGroup;
+ this.Name = $"{groupName}, {typeName}, {sizeName}";
+ this.Type = type;
+ this.MaterialType = ((int)materialTypeEnum).ToString();
+ this.GroupName = groupName;
+ this.TypeName = typeName;
+ this.SizeName = sizeName;
+ this._end = "";
+ }
+
[XmlIgnore]
public string MaterialFamily
@@ -141,7 +158,7 @@ public static Section GetSectionByNameOrIndex(List sections, dynamic se
}
catch (Exception ex)
{
- throw new Exception($"{sectionInput} does not exist!");
+ throw new Exception($"{sectionInput} does not exist!", ex);
}
}
else
@@ -152,7 +169,7 @@ public static Section GetSectionByNameOrIndex(List sections, dynamic se
}
catch (Exception ex)
{
- throw new System.Exception($"Materials List only contains {sections.Count} item. {sectionInput} is out of range!");
+ throw new System.Exception($"Materials List only contains {sections.Count} item. {sectionInput} is out of range!", ex);
}
}
return section;
diff --git a/FemDesign.Core/Shells/Panel.cs b/FemDesign.Core/Shells/Panel.cs
index 28b36f742..9935e4dfd 100644
--- a/FemDesign.Core/Shells/Panel.cs
+++ b/FemDesign.Core/Shells/Panel.cs
@@ -11,12 +11,13 @@ namespace FemDesign.Shells
/// panel_type
///
[System.Serializable]
- public partial class Panel: EntityBase, IStructureElement, IStageElement
+ public partial class Panel: NamedEntityBase, IStructureElement, IStageElement
{
///
/// Panel instance counter
///
- private static int _instance = 0;
+ private static int _panelInstances = 0;
+ protected override int GetUniqueInstanceCount() => ++_panelInstances;
///
/// Coordinate system
@@ -252,31 +253,6 @@ public Sections.Section Section
return this._section;
}
}
- [XmlAttribute("name")]
- public string _name; // identifier
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this.Name.IndexOf(".");
- return this.Name.Substring(found + 1);
- }
- }
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- Panel._instance++;
- this._name = RestrictedString.Length(value, 50) + "." + Panel._instance.ToString();
- }
- }
- public string Identifier => this.Name.Split('.')[0];
[XmlAttribute("panelname")]
public string PanelName { get; set; }
@@ -347,6 +323,26 @@ public double UniformAvgMeshSize
[XmlAttribute("stage")]
public int StageId { get; set; } = 1;
+
+ [XmlAttribute("ignored_distance")]
+ public double _ignoredDistance = 0.02;
+
+ [XmlIgnore]
+ public double IgnoredDistance
+ {
+ get
+ {
+ return this._ignoredDistance;
+ }
+ set
+ {
+ this._ignoredDistance = RestrictedDouble.NonNegMax_1000(value);
+ }
+ }
+
+ [XmlAttribute("ignored_in_stability")]
+ public bool IgnoredInStability { get; set; } = false;
+
///
/// Set external edge connections (i.e. set edge connections around region).
/// When this is performed for panels the external rigidity is changed accordingly.
@@ -434,18 +430,18 @@ private Panel()
/// Construct standard panel with "Continuous" analytical model.
///
/// Region of shell containing panels.
- /// Direction of panels.
///
- /// Default value for shell border EdgeConnections. Can be overwritten by EdgeConnection for each specific edge in Region.
/// Type of panel.
- /// Guid reference to material.
- /// Guid reference to complex section.
/// Name of shell.
/// Name of panel.
/// Gap between panels.
/// Orthotropy.
/// ShellEccentricity.
/// EdgeConnection LCS changes along edge?
+ ///
+ ///
+ ///
+ ///
internal Panel(Geometry.Region region, Geometry.Point3d anchorPoint, InternalPanels internalPanels, EdgeConnection externalEdgeConnection, PanelType type, Materials.Material material, Sections.Section section, string identifier, string panelName, double gap, double orthotropy, ShellEccentricity ecc, bool externalMovingLocal)
{
this.EntityCreated();
@@ -464,7 +460,7 @@ internal Panel(Geometry.Region region, Geometry.Point3d anchorPoint, InternalPan
this.Type = type;
this.Material = material; // note that material and section are not added directly to complexMaterial and complexSection fields.
this.Section = section;
- this.Name = identifier;
+ this.Identifier = identifier;
this.PanelName = panelName;
this.Gap = gap;
this.Orthotropy = orthotropy;
@@ -490,6 +486,7 @@ internal Panel(Geometry.Region region, Geometry.Point3d anchorPoint, InternalPan
/// Orthotropy.
/// ShellEccentricity.
/// EdgeConnection LCS changes along edge?
+ ///
internal Panel(Geometry.Region region, Geometry.Point3d anchorPoint, InternalPanels internalPanels, Materials.TimberPanelType timberApplicationData, EdgeConnection externalEdgeConnection, PanelType type, string identifier, string panelName, double gap, double orthotropy, ShellEccentricity ecc, bool externalMovingLocal, double panelWidth)
{
this.EntityCreated();
@@ -508,7 +505,7 @@ internal Panel(Geometry.Region region, Geometry.Point3d anchorPoint, InternalPan
// attributes
this.Type = type;
- this.Name = identifier;
+ this.Identifier = identifier;
this.PanelName = panelName;
this.Gap = gap;
this.Alignment = ecc.Alignment;
diff --git a/FemDesign.Core/Shells/ShellEccentricity.cs b/FemDesign.Core/Shells/ShellEccentricity.cs
index d16eb8cee..29e68a1d0 100644
--- a/FemDesign.Core/Shells/ShellEccentricity.cs
+++ b/FemDesign.Core/Shells/ShellEccentricity.cs
@@ -6,7 +6,6 @@ namespace FemDesign.Shells
{
public partial class ShellEccentricity
{
- private string _alignment; // ver_align
public VerticalAlignment Alignment { get; set; }
private double _eccentricity; // align_offset // abs_max_1e20
public double Eccentricity
diff --git a/FemDesign.Core/Shells/Slab.cs b/FemDesign.Core/Shells/Slab.cs
index b13ca3bbd..aa3470f9e 100644
--- a/FemDesign.Core/Shells/Slab.cs
+++ b/FemDesign.Core/Shells/Slab.cs
@@ -12,29 +12,31 @@ namespace FemDesign.Shells
/// slab_type
///
[System.Serializable]
- public partial class Slab : EntityBase, IStructureElement, IStageElement
+ public partial class Slab : EntityBase, INamedEntity, IStructureElement, IStageElement
{
- private static int _plateInstance = 0;
- private static int _wallInstance = 0;
+ public string Name => this.SlabPart.Name.Substring(0, this.SlabPart.Name.Length - 2); // Remove trailing ".1" from barpart name
+ public int Instance => this.SlabPart.Instance;
+
+ [XmlIgnore]
+ public string Identifier
+ {
+ get => this.SlabPart.Identifier;
+ set => this.SlabPart.Identifier = value;
+ }
+ [XmlIgnore]
+ public bool LockedIdentifier
+ {
+ get => this.SlabPart.LockedIdentifier;
+ set => this.SlabPart.LockedIdentifier = value;
+ }
+
[XmlIgnore]
public Materials.Material Material { get; set; }
[XmlIgnore]
public Reinforcement.SurfaceReinforcementParameters SurfaceReinforcementParameters { get; set; }
[XmlIgnore]
public List SurfaceReinforcement = new List();
- [XmlAttribute("name")]
- public string Name { get; set; } // identifier
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this.Name.IndexOf(".");
- return this.Name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
[XmlAttribute("type")]
public SlabType Type { get; set; }
@@ -71,32 +73,30 @@ private Slab()
///
/// Construct Slab.
///
- private Slab(SlabType type, string name, SlabPart slabPart, Materials.Material material)
+ private Slab(SlabType type, string identifier, SlabPart slabPart, Materials.Material material)
{
this.EntityCreated();
- this.Name = name;
- this.Type = type;
this.SlabPart = slabPart;
+ this.Identifier = identifier;
+ this.Type = type;
this.Material = material;
this.End = "";
}
public static Slab Plate(string identifier, Materials.Material material, Geometry.Region region, EdgeConnection shellEdgeConnection, ShellEccentricity eccentricity, ShellOrthotropy orthotropy, List thickness)
{
- Slab._plateInstance++;
SlabType type = SlabType.Plate;
- string name = identifier + "." + Slab._plateInstance.ToString() + ".1";
- SlabPart slabPart = SlabPart.Define(name, region, thickness, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
- Slab shell = new Slab(type, name, slabPart, material);
+ SlabPart slabPart = SlabPart.Define(type, identifier, region, thickness, material, shellEdgeConnection, eccentricity, orthotropy);
+ Slab shell = new Slab(type, identifier, slabPart, material);
return shell;
}
///
/// Construct a rectangular slab in the XY plane
///
- ///
- ///
+ ///
+ ///
+ ///
///
///
///
@@ -104,20 +104,17 @@ public static Slab Plate(string identifier, Materials.Material material, Geometr
///
///
///
- public static Slab Plate(double width, double height, double thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null, string identifier = "Plate")
+ public static Slab Plate(Geometry.Point3d corner, double widthX, double widthY, double thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null, string identifier = "Plate")
{
- Slab._plateInstance++;
SlabType type = SlabType.Plate;
- string name = identifier + "." + Slab._wallInstance.ToString() + ".1";
- var region = Geometry.Region.RectangleXY(width, height);
+ var region = Geometry.Region.RectangleXY(corner, widthX, widthY);
List thicknessObj = new List();
thicknessObj.Add(new FemDesign.Shells.Thickness(region.CoordinateSystem.Origin, thickness));
- SlabPart slabPart = SlabPart.Define(name, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
+ SlabPart slabPart = SlabPart.Define(type, identifier, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- Slab shell = new Slab(type, name, slabPart, material);
+ Slab shell = new Slab(type, identifier, slabPart, material);
return shell;
}
@@ -136,14 +133,12 @@ public static Slab Plate(double width, double height, double thickness, Material
///
public static Slab Wall(Geometry.Point3d point0, Geometry.Point3d point1, double height, double thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null, string identifier = "Wall")
{
- Slab._plateInstance++;
SlabType type = SlabType.Wall;
- string name = identifier + "." + Slab._wallInstance.ToString() + ".1";
var translation = new Geometry.Vector3d(0, 0, height);
var point2 = point1 + translation;
var point3 = point0 + translation;
- var points = new List() { point0, point1, point2, point3};
+ var points = new List() { point0, point1, point2, point3 };
var fdCoordinate = new Geometry.CoordinateSystem(point0, point1, point3);
@@ -153,10 +148,9 @@ public static Slab Wall(Geometry.Point3d point0, Geometry.Point3d point1, double
List thicknessObj = new List();
thicknessObj.Add(new FemDesign.Shells.Thickness(region.CoordinateSystem.Origin, thickness));
- SlabPart slabPart = SlabPart.Define(name, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
+ SlabPart slabPart = SlabPart.Define(type, identifier, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- Slab shell = new Slab(type, name, slabPart, material);
+ Slab shell = new Slab(type, identifier, slabPart, material);
return shell;
}
@@ -176,9 +170,7 @@ public static Slab Wall(Geometry.Point3d point0, Geometry.Point3d point1, double
///
public static Slab FromFourPoints(Geometry.Point3d point0, Geometry.Point3d point1, Geometry.Point3d point2, Geometry.Point3d point3, double thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null, string identifier = "Plate")
{
- Slab._plateInstance++;
SlabType type = SlabType.Plate;
- string name = identifier + "." + Slab._wallInstance.ToString() + ".1";
var points = new List() { point0, point1, point2, point3 };
var fdCoordinate = new Geometry.CoordinateSystem(point0, point1, point3);
@@ -187,10 +179,9 @@ public static Slab FromFourPoints(Geometry.Point3d point0, Geometry.Point3d poin
List thicknessObj = new List();
thicknessObj.Add(new FemDesign.Shells.Thickness(region.CoordinateSystem.Origin, thickness));
- SlabPart slabPart = SlabPart.Define(name, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
+ SlabPart slabPart = SlabPart.Define(type, identifier, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- Slab shell = new Slab(type, name, slabPart, material);
+ Slab shell = new Slab(type, identifier, slabPart, material);
return shell;
}
@@ -203,41 +194,10 @@ public static Slab Wall(string identifier, Materials.Material material, Geometry
throw new System.ArgumentException("Wall is not vertical! Create plate instead.");
}
- Slab._wallInstance++;
- SlabType type = SlabType.Wall;
- string name = identifier + "." + Slab._wallInstance.ToString() + ".1";
- SlabPart slabPart = SlabPart.Define(name, region, thickness, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
-
- Slab shell = new Slab(type, name, slabPart, material);
- return shell;
- }
- ///
- /// Construct a Wall Element in XZ plane
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static Slab Wall(double width, double height, double thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null, string identifier = "Wall")
- {
- Slab._wallInstance++;
SlabType type = SlabType.Wall;
- string name = identifier + "." + Slab._wallInstance.ToString() + ".1";
- var region = Geometry.Region.RectangleXZ(width, height);
-
- List thicknessObj = new List();
- thicknessObj.Add(new FemDesign.Shells.Thickness(region.CoordinateSystem.Origin, thickness));
-
- SlabPart slabPart = SlabPart.Define(name, region, thicknessObj, material, shellEdgeConnection, eccentricity, orthotropy);
- name = identifier + "." + Slab._plateInstance.ToString();
+ SlabPart slabPart = SlabPart.Define(type, identifier, region, thickness, material, shellEdgeConnection, eccentricity, orthotropy);
- Slab shell = new Slab(type, name, slabPart, material);
+ Slab shell = new Slab(type, identifier, slabPart, material);
return shell;
}
diff --git a/FemDesign.Core/Shells/SlabPart.cs b/FemDesign.Core/Shells/SlabPart.cs
index 52b12dc00..21f26a54e 100644
--- a/FemDesign.Core/Shells/SlabPart.cs
+++ b/FemDesign.Core/Shells/SlabPart.cs
@@ -11,8 +11,26 @@ namespace FemDesign.Shells
/// slab_part_type
///
[System.Serializable]
- public partial class SlabPart: EntityBase
- {
+ public partial class SlabPart: NamedEntityPartBase
+ {
+ private static int _plateInstance = 0;
+ private static int _wallInstance = 0;
+ protected override int GetUniqueInstanceCount()
+ {
+ switch (this.SlabType)
+ {
+ case SlabType.Plate:
+ return ++_plateInstance;
+ case SlabType.Wall:
+ return ++_wallInstance;
+ default:
+ throw new ArgumentException($"Incorrect type of slab: {this.SlabType}");
+ }
+ }
+
+ [XmlIgnore]
+ public SlabType SlabType;
+
///
/// Get ShellEccentricity
///
@@ -37,20 +55,6 @@ public ShellOrthotropy ShellOrthotropy
}
}
- [XmlAttribute("name")]
- public string Name {get; set;} // identifier
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this.Name.IndexOf(".");
- return this.Name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
-
-
[XmlAttribute("complex_material")]
public System.Guid ComplexMaterialGuid {get; set;} // guidtype
@@ -194,7 +198,11 @@ public Geometry.Vector3d LocalZ
}
}
}
- [XmlElement("end", Order = 6)]
+
+ [XmlElement(ElementName = "stiffness_modifiers", Order = 6)]
+ public SlabStiffnessFactors SlabStiffnessFactors { get; set; }
+
+ [XmlElement("end", Order = 7)]
public string End {get; set;} // empty_type
///
@@ -208,10 +216,11 @@ private SlabPart()
///
/// Construct SlabPart.
///
- public SlabPart(string name, Geometry.Region region, List thickness, Materials.Material complexMaterial, ShellEccentricity alignment, ShellOrthotropy orthotropy)
+ public SlabPart(SlabType type, string identifier, Geometry.Region region, List thickness, Materials.Material complexMaterial, ShellEccentricity alignment, ShellOrthotropy orthotropy)
{
this.EntityCreated();
- this.Name = name;
+ this.SlabType = type;
+ this.Identifier = identifier;
this.Region = region;
this.ComplexMaterialGuid = complexMaterial.Guid;
this.ComplexMaterial = complexMaterial;
@@ -231,7 +240,7 @@ public SlabPart(string name, Geometry.Region region, List thickness,
///
/// Construct SlabPart with EdgeConnections.
///
- public static SlabPart Define(string name, Geometry.Region region, List thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null)
+ public static SlabPart Define(SlabType type, string identifier, Geometry.Region region, List thickness, Materials.Material material, EdgeConnection shellEdgeConnection = null, ShellEccentricity eccentricity = null, ShellOrthotropy orthotropy = null)
{
shellEdgeConnection = shellEdgeConnection ?? EdgeConnection.Default;
eccentricity = eccentricity ?? ShellEccentricity.Default;
@@ -241,7 +250,7 @@ public static SlabPart Define(string name, Geometry.Region region, List StiffnessModifiers { get; set; }
+ }
+}
diff --git a/FemDesign.Core/Stage/ActivatedLoadCase.cs b/FemDesign.Core/Stage/ActivatedLoadCase.cs
index f7b5bf573..a30540e10 100644
--- a/FemDesign.Core/Stage/ActivatedLoadCase.cs
+++ b/FemDesign.Core/Stage/ActivatedLoadCase.cs
@@ -6,6 +6,8 @@
using System.Threading.Tasks;
using System.Text.RegularExpressions;
+using FemDesign.GenericClasses;
+
namespace FemDesign
{
public enum PTCLoadCase
@@ -69,12 +71,12 @@ private ActivatedLoadCase()
///
/// The load case to be activated.
/// Load case factor.
- /// Activation type.
- public ActivatedLoadCase(Loads.LoadCase loadCase, double factor, ActivationType type)
+ /// Partitioning.
+ public ActivatedLoadCase(Loads.LoadCase loadCase, double factor, ActivationType partitioning)
{
this.LoadCaseDisplayName = loadCase.Name;
this._case = loadCase.Guid.ToString();
- Initialize(factor, type);
+ Initialize(factor, partitioning);
}
///
@@ -127,21 +129,25 @@ public enum ActivationType
///
/// Only in this stage
///
+ [Parseable("only_in_this_stage", "0", "OnlyInThisStage")]
[XmlEnum("only_in_this_stage")]
OnlyInThisStage,
///
/// From this stage on
///
+ [Parseable("from_this_stage_on", "1", "FromThisStageOn")]
[XmlEnum("from_this_stage_on")]
FromThisStageOn,
///
/// Shifted from first stage
///
+ [Parseable("shifted_from_first_stage", "2", "ShiftedFromFirstStage")]
[XmlEnum("shifted_from_first_stage")]
ShiftedFromFirstStage,
///
/// Only stage activated elements
///
+ [Parseable("only_stage_activated_elem", "3", "OnlyStageActivatedElements")]
[XmlEnum("only_stage_activated_elem")]
OnlyStageActivatedElements
}
diff --git a/FemDesign.Core/Stage/Stage.cs b/FemDesign.Core/Stage/Stage.cs
index 85973662f..83d81d806 100644
--- a/FemDesign.Core/Stage/Stage.cs
+++ b/FemDesign.Core/Stage/Stage.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using FemDesign.GenericClasses;
+using FemDesign.Loads;
namespace FemDesign
{
@@ -35,7 +36,38 @@ private Stage()
}
- public Stage(int index, string description, List activatedLoadCases, List elements, bool initialStressState = false)
+ ///
+ /// Construction stage.
+ ///
+ ///
+ /// Stage description (name).
+ /// LoadCases with factor and partitioning for when to be activated.
+ /// Elements to be activated in this stage.
+ /// Initial stress state.
+ public Stage(int index, string description, List activatedLoadCases = null, List elements = null, bool initialStressState = false)
+ {
+ Initialize(index, description, activatedLoadCases, elements, initialStressState);
+ }
+
+ ///
+ /// Construction stage.
+ ///
+ ///
+ /// Stage description (name).
+ /// LoadCases to be activated (with factor 1.0).
+ /// Elements to be activated in this stage.
+ /// Partitioning for when to activate load cases.
+ /// Initial stress state.
+#if ISDYNAMO // Dynamo may not have any default enum arguments in any constructor in any imported C# libraries it seems like
+ public Stage(int index, string description, List loadCases, List elements, ActivationType partitioning, bool initialStressState = false)
+#else
+ public Stage(int index, string description, List loadCases, List elements, ActivationType partitioning = ActivationType.OnlyInThisStage, bool initialStressState = false)
+#endif
+ {
+ var activatedLoadCase = loadCases.Select(l => new ActivatedLoadCase(l, 1.0, partitioning)).ToList();
+ Initialize(index, description, activatedLoadCase, elements, initialStressState);
+ }
+ private void Initialize(int index, string description, List activatedLoadCases, List elements, bool initialStressState)
{
if (index <= 0)
{
@@ -48,6 +80,34 @@ public Stage(int index, string description, List activatedLoa
this.InitialStressState = initialStressState;
}
+ ///
+ /// Add element to construction stage.
+ ///
+ /// Element to be activated in this stage.
+ public void AddElement(IStageElement element)
+ {
+ this.Elements.Add(element);
+ }
+
+ ///
+ /// Adds a (construction stage) activated load case.
+ ///
+ /// The load case to be activated.
+ /// Load case factor.
+ /// Partitioning.
+ public void AddLoadCase(LoadCase loadCase, double factor, ActivationType partitioning)
+ {
+ AddLoadCase(new ActivatedLoadCase(loadCase, factor, partitioning));
+ }
+
+ ///
+ /// Adds a (construction stage) activated load case.
+ ///
+ public void AddLoadCase(ActivatedLoadCase activatedLoadCase)
+ {
+ this.ActivatedLoadCases.Add(activatedLoadCase);
+ }
+
public override string ToString()
{
return $"Stage {this.Description}";
diff --git a/FemDesign.Core/Supports/Group.cs b/FemDesign.Core/Supports/Group.cs
index 1ef05ac8e..c68100cd6 100644
--- a/FemDesign.Core/Supports/Group.cs
+++ b/FemDesign.Core/Supports/Group.cs
@@ -151,7 +151,7 @@ public Group(Geometry.Vector3d localX, Geometry.Vector3d localY, Motions motions
///
/// Orient this object's coordinate system to GCS
- ///
+ ///
public void OrientCoordinateSystemToGCS()
{
var cs = this.CoordinateSystem;
diff --git a/FemDesign.Core/Supports/LineSupport.cs b/FemDesign.Core/Supports/LineSupport.cs
index 2c0d960b5..380e23e28 100644
--- a/FemDesign.Core/Supports/LineSupport.cs
+++ b/FemDesign.Core/Supports/LineSupport.cs
@@ -12,21 +12,9 @@ namespace FemDesign.Supports
/// line_support_type
///
[System.Serializable]
- public partial class LineSupport: EntityBase, IStructureElement, ISupportElement, IStageElement
+ public partial class LineSupport: NamedEntityBase, IStructureElement, ISupportElement, IStageElement
{
- // serialization properties
- [XmlAttribute("name")]
- public string Name { get; set; } // identifier.
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this.Name.IndexOf(".");
- return this.Name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
+ protected override int GetUniqueInstanceCount() => ++PointSupport._instance; // PointSupport and LineSupport share the same instance counter.
[XmlAttribute("moving_local")]
public bool MovingLocal { get; set; } // bool
@@ -143,9 +131,8 @@ public LineSupport(Edge edge, Motions motions, MotionsPlasticLimits motionsPlast
private void Initialize(Edge edge, Group group, bool movingLocal, string identifier)
{
- PointSupport._instance++; // PointSupport and LineSupport share the same instance counter.
this.EntityCreated();
- this.Name = identifier + "." + PointSupport._instance.ToString();
+ this.Identifier = identifier;
this.MovingLocal = movingLocal;
// set edge specific properties
diff --git a/FemDesign.Core/Supports/PointSupport.cs b/FemDesign.Core/Supports/PointSupport.cs
index 7fb4abefc..c308f2120 100644
--- a/FemDesign.Core/Supports/PointSupport.cs
+++ b/FemDesign.Core/Supports/PointSupport.cs
@@ -11,23 +11,11 @@ namespace FemDesign.Supports
/// point_support_type
///
[System.Serializable]
- public partial class PointSupport : EntityBase, IStructureElement, ISupportElement, IStageElement
+ public partial class PointSupport : NamedEntityBase, IStructureElement, ISupportElement, IStageElement
{
[XmlIgnore]
- public static int _instance = 0; // used for PointSupports and LineSupports
- [XmlAttribute("name")]
- public string Name { get; set; } // identifier
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this.Name.IndexOf(".");
- return this.Name.Substring(found + 1);
- }
- }
- public string Identifier => this.Name.Split('.')[0];
-
+ internal static int _instance = 0; // Shared instance counter for both PointSupport and LineSupport
+ protected override int GetUniqueInstanceCount() => ++_instance;
[XmlAttribute("stage")]
public int StageId { get; set; } = 1;
@@ -99,10 +87,10 @@ public PointSupport(CoordinateSystem plane, Motions motions, Rotations rotations
///
/// Create a Point Support oriented along the Global Axis X and Y.
///
- ///
- ///
- ///
- ///
+ /// Position of the support.
+ /// Motions stiffnessess.
+ /// Rotation stiffnessess.
+ /// Name.
public PointSupport(Point3d point, Motions motions, Rotations rotations, string identifier = "S")
{
var group = new Group(Vector3d.UnitX, Vector3d.UnitY, motions, rotations);
@@ -112,7 +100,7 @@ public PointSupport(Point3d point, Motions motions, Rotations rotations, string
///
/// PointSupport at point with rigidity (motions, rotations) and plastic limits (forces, moments). Group aligned with global coordinate system.
///
- /// Position of the support.
+ /// Position (and orientation) of the support.
/// Motions stiffnessess.
/// Motions plastic limit forces.
/// Rotation stiffnessess.
@@ -120,7 +108,7 @@ public PointSupport(Point3d point, Motions motions, Rotations rotations, string
/// Name.
public PointSupport(CoordinateSystem plane, Motions motions, MotionsPlasticLimits motionsPlasticLimits, Rotations rotations, RotationsPlasticLimits rotationsPlasticLimits, string identifier = "S")
{
- var group = new Group(Vector3d.UnitX, Vector3d.UnitY, motions, motionsPlasticLimits, rotations, rotationsPlasticLimits);
+ var group = new Group(plane.LocalX, plane.LocalY, motions, motionsPlasticLimits, rotations, rotationsPlasticLimits);
Initialize(plane, group, identifier);
}
@@ -154,9 +142,8 @@ public PointSupport(CoordinateSystem plane, bool tx, bool ty, bool tz, bool rx,
private void Initialize(CoordinateSystem point, Group group, string identifier)
{
- PointSupport._instance++;
this.EntityCreated();
- this.Name = $"{identifier}.{_instance}";
+ this.Identifier = identifier;
this.Group = group;
this.Position = point;
}
diff --git a/FemDesign.Core/Supports/StiffnessPoints.cs b/FemDesign.Core/Supports/StiffnessPoints.cs
new file mode 100644
index 000000000..a2af17926
--- /dev/null
+++ b/FemDesign.Core/Supports/StiffnessPoints.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Xml.Serialization;
+using FemDesign;
+using FemDesign.GenericClasses;
+using FemDesign.Releases;
+
+namespace FemDesign.Supports
+{
+ public partial class StiffnessPoint : EntityBase, IStructureElement, ISupportElement
+ {
+ [XmlIgnore]
+ public FemDesign.Geometry.Point3d Point { get; set; }
+
+ [XmlAttribute("x")]
+ public double X;
+
+ [XmlAttribute("y")]
+ public double Y;
+
+ [XmlAttribute("z")]
+ public double Z;
+
+ [XmlAttribute("name")]
+ public string Name { get; set; }
+
+ [XmlIgnore]
+ public FemDesign.Supports.SurfaceSupport Surface { get; set; }
+
+ [XmlAttribute("surface_support")]
+ public Guid SurfaceSupport;
+
+ [XmlElement("rigidity")]
+ public RigidityDataType0 Rigidity { get; set; }
+ public Motions Motions { get { return Rigidity?.Motions; } }
+ public MotionsPlasticLimits MotionsPlasticityLimits { get { return Rigidity?.PlasticLimitForces; } }
+
+ public StiffnessPoint()
+ {
+ }
+
+ private void Initialise(FemDesign.Supports.SurfaceSupport surface, FemDesign.Geometry.Point3d point)
+ {
+ this.SurfaceSupport = surface.Guid;
+ this.X = point.X;
+ this.Y = point.Y;
+ this.Z = point.Z;
+ this.EntityCreated();
+ }
+
+ public StiffnessPoint(FemDesign.Supports.SurfaceSupport surface, FemDesign.Geometry.Point3d point, Motions motions, MotionsPlasticLimits MotionsPlasticityLimits = null, string name = null)
+ {
+ this.Initialise(surface, point);
+ this.Rigidity = new RigidityDataType0(motions, MotionsPlasticityLimits);
+ this.Name = name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Core/Supports/Supports.cs b/FemDesign.Core/Supports/Supports.cs
index c574f43d1..757c01917 100644
--- a/FemDesign.Core/Supports/Supports.cs
+++ b/FemDesign.Core/Supports/Supports.cs
@@ -17,6 +17,8 @@ public partial class Supports
public List LineSupport = new List(); // line_support_type
[XmlElement("surface_support", Order = 3)]
public List SurfaceSupport = new List(); // surface_support
+ [XmlElement("stiffness_point", Order = 4)]
+ public List StiffnessPoint = new List(); // surface_support
public List GetSupports()
{
diff --git a/FemDesign.Core/Supports/SurfaceSupport.cs b/FemDesign.Core/Supports/SurfaceSupport.cs
index 56f92d744..28ffedded 100644
--- a/FemDesign.Core/Supports/SurfaceSupport.cs
+++ b/FemDesign.Core/Supports/SurfaceSupport.cs
@@ -8,35 +8,9 @@
namespace FemDesign.Supports
{
[System.Serializable]
- public partial class SurfaceSupport: EntityBase, IStructureElement, ISupportElement, IStageElement
+ public partial class SurfaceSupport: NamedEntityBase, IStructureElement, ISupportElement, IStageElement
{
- [XmlAttribute("name")]
- public string _name;
- [XmlIgnore]
- public string Name
- {
- get
- {
- return this._name;
- }
- set
- {
- PointSupport._instance++;
- this._name = value + "." + PointSupport._instance.ToString();
- }
- }
- public string Identifier => this.Name.Split('.')[0];
-
-
- [XmlIgnore]
- public string Instance
- {
- get
- {
- var found = this._name.IndexOf(".");
- return this._name.Substring(found + 1);
- }
- }
+ protected override int GetUniqueInstanceCount() => ++PointSupport._instance; // PointSupport and SurfaceSupport share the same instance counter.
[XmlAttribute("stage")]
public int StageId { get; set; } = 1;
@@ -109,7 +83,7 @@ public SurfaceSupport(Geometry.Region region, Motions motions, MotionsPlasticLim
private void Initialize(Geometry.Region region, RigidityDataType1 rigidity, string identifier)
{
this.EntityCreated();
- this.Name = identifier;
+ this.Identifier = identifier;
this.Region = region;
this.Rigidity = rigidity;
this.CoordinateSystem = region.CoordinateSystem;
diff --git a/FemDesign.Dynamo/Dynamo/AdvancedFem/Cover.cs b/FemDesign.Dynamo/Dynamo/AdvancedFem/Cover.cs
index 3ff26cf40..cd9da3372 100644
--- a/FemDesign.Dynamo/Dynamo/AdvancedFem/Cover.cs
+++ b/FemDesign.Dynamo/Dynamo/AdvancedFem/Cover.cs
@@ -4,7 +4,7 @@
namespace FemDesign
{
[IsVisibleInDynamoLibrary(false)]
- public partial class Cover : EntityBase
+ public partial class Cover
{
#region dynamo
@@ -24,7 +24,7 @@ public static Cover OneWayCover(Autodesk.DesignScript.Geometry.Surface surface,
Geometry.Region region = Geometry.Region.FromDynamo(surface);
// get loadBearingDirection
- Geometry.FdVector3d _loadBearingDirection = Geometry.FdVector3d.FromDynamo(loadBearingDirection).Normalize();
+ Geometry.Vector3d _loadBearingDirection = Geometry.Vector3d.FromDynamo(loadBearingDirection).Normalize();
// return
return Cover.OneWayCover(region, supportingStructures, _loadBearingDirection, identifier);
diff --git a/FemDesign.Dynamo/Dynamo/AuxiliaryResults/LabelledSection.cs b/FemDesign.Dynamo/Dynamo/AuxiliaryResults/LabelledSection.cs
index 5da4002eb..98bf234d8 100644
--- a/FemDesign.Dynamo/Dynamo/AuxiliaryResults/LabelledSection.cs
+++ b/FemDesign.Dynamo/Dynamo/AuxiliaryResults/LabelledSection.cs
@@ -8,7 +8,7 @@
namespace FemDesign.AuxiliaryResults
{
[IsVisibleInDynamoLibrary(false)]
- public partial class LabelledSection : EntityBase, IStructureElement
+ public partial class LabelledSection
{
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Bars/Bar.cs b/FemDesign.Dynamo/Dynamo/Bars/Bar.cs
index 4e7c7c808..a37223adb 100644
--- a/FemDesign.Dynamo/Dynamo/Bars/Bar.cs
+++ b/FemDesign.Dynamo/Dynamo/Bars/Bar.cs
@@ -37,7 +37,7 @@ public static Bar Beam(Autodesk.DesignScript.Geometry.Curve curve, Materials.Mat
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- bar.BarPart.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ bar.BarPart.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -77,7 +77,7 @@ public static Bar Column(Autodesk.DesignScript.Geometry.Line line, Materials.Mat
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- bar.BarPart.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ bar.BarPart.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -114,7 +114,7 @@ public static Bar Truss(Autodesk.DesignScript.Geometry.Line line, Materials.Mate
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- bar.BarPart.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ bar.BarPart.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -151,8 +151,7 @@ public static Bar TrussLimitedCapacity(Autodesk.DesignScript.Geometry.Line line,
Geometry.Edge edge = Geometry.Edge.FromDynamoLine(line);
// create bar
- var type = BarType.Truss;
- Bar bar = new Bar(edge, type, material, section, identifier);
+ Bar bar = Bar.Truss(edge, material, section, identifier);
bar.MaxCompression = maxCompression;
bar.MaxTension = maxTension;
bar.CompressionPlasticity = compressionPlasticity;
@@ -161,7 +160,7 @@ public static Bar TrussLimitedCapacity(Autodesk.DesignScript.Geometry.Line line,
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- bar.BarPart.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ bar.BarPart.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -238,7 +237,7 @@ public static Bar Modify(Bar bar, [DefaultArgument("false")] bool newGuid, [Defa
if (localY != null)
{
- bar.BarPart.LocalY = Geometry.FdVector3d.FromDynamo(localY);
+ bar.BarPart.LocalY = Geometry.Vector3d.FromDynamo(localY);
}
if (orientLCS)
@@ -249,7 +248,6 @@ public static Bar Modify(Bar bar, [DefaultArgument("false")] bool newGuid, [Defa
if (identifier != null)
{
bar.Identifier = identifier;
- bar.BarPart.Identifier = bar.Identifier;
}
return bar;
diff --git a/FemDesign.Dynamo/Dynamo/Bars/BarPart.cs b/FemDesign.Dynamo/Dynamo/Bars/BarPart.cs
index ce4e9e52f..0a76af5db 100644
--- a/FemDesign.Dynamo/Dynamo/Bars/BarPart.cs
+++ b/FemDesign.Dynamo/Dynamo/Bars/BarPart.cs
@@ -10,7 +10,7 @@
namespace FemDesign.Bars
{
[IsVisibleInDynamoLibrary(false)]
- public partial class BarPart: EntityBase
+ public partial class BarPart: NamedEntityPartBase
{
}
diff --git a/FemDesign.Dynamo/Dynamo/Bars/ColumnCorbel.cs b/FemDesign.Dynamo/Dynamo/Bars/ColumnCorbel.cs
index c63098588..35d4bd23e 100644
--- a/FemDesign.Dynamo/Dynamo/Bars/ColumnCorbel.cs
+++ b/FemDesign.Dynamo/Dynamo/Bars/ColumnCorbel.cs
@@ -8,7 +8,7 @@
namespace FemDesign.Bars
{
[IsVisibleInDynamoLibrary(false)]
- public partial class ColumnCorbel: EntityBase
+ public partial class ColumnCorbel
{
}
diff --git a/FemDesign.Dynamo/Dynamo/Bars/Connectivity.cs b/FemDesign.Dynamo/Dynamo/Bars/Connectivity.cs
index 3fb59b186..981baa362 100644
--- a/FemDesign.Dynamo/Dynamo/Bars/Connectivity.cs
+++ b/FemDesign.Dynamo/Dynamo/Bars/Connectivity.cs
@@ -9,13 +9,6 @@ namespace FemDesign.Bars
[IsVisibleInDynamoLibrary(false)]
public partial class Connectivity
{
- ///
- /// Define default (rigid) releases for a bar-element.
- ///
- ///
- [IsVisibleInDynamoLibrary(false)]
- public static Connectivity Default() => GetDefault();
-
///
/// Define releases for a bar-element.
///
@@ -94,18 +87,18 @@ public static Connectivity SemiRigid([DefaultArgument("true")] System.Object mx,
///
/// Create
[IsVisibleInDynamoLibrary(true)]
- public static Connectivity Hinged()
+ public static Connectivity GetHinged()
{
- return GetHinged();
+ return Connectivity.Hinged;
}
///
/// Define rigid releases for a bar-element.
///
/// Create
[IsVisibleInDynamoLibrary(true)]
- public static Connectivity Rigid()
+ public static Connectivity GetRigid()
{
- return GetRigid();
+ return Connectivity.Rigid;
}
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Bars/Eccentricity.cs b/FemDesign.Dynamo/Dynamo/Bars/Eccentricity.cs
index 9290e0904..d59bcd989 100644
--- a/FemDesign.Dynamo/Dynamo/Bars/Eccentricity.cs
+++ b/FemDesign.Dynamo/Dynamo/Bars/Eccentricity.cs
@@ -22,13 +22,5 @@ public static Eccentricity Define(double y = 0, double z = 0)
{
return new Eccentricity(y, z);
}
-
- ///
- /// Create a default eccentricity, i.e. no ecceentricity (y=z=0).
- ///
- /// Create
- ///
- [IsVisibleInDynamoLibrary(false)]
- public static Eccentricity Default() => GetDefault();
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Calculate/Application.cs b/FemDesign.Dynamo/Dynamo/Calculate/Application.cs
index 943e38c3b..e3c417365 100644
--- a/FemDesign.Dynamo/Dynamo/Calculate/Application.cs
+++ b/FemDesign.Dynamo/Dynamo/Calculate/Application.cs
@@ -26,7 +26,7 @@ public partial class Application
/// Bool. True if session has exited. False if session is still open or was closed manually.
[IsVisibleInDynamoLibrary(true)]
[MultiReturn(new[] { "FdModel", "FdFeaModel", "Results", "HasExited" })]
- public static Dictionary RunAnalysis(Model fdModel, string struxmlPath, Calculate.Analysis analysis, [DefaultArgument("[]")] List resultTypes, [DefaultArgument("[]")] Results.UnitResults units, string docxTemplatePath = "", bool endSession = true, bool closeOpenWindows = false, bool runNode = true)
+ public static Dictionary RunAnalysis(Model fdModel, string struxmlPath, Calculate.Analysis analysis, [DefaultArgument("[]")] List resultTypes, [DefaultArgument("[]")] Results.UnitResults units, string docxTemplatePath = "", bool endSession = true, bool closeOpenWindows = false, bool runNode = true)
{
if (!runNode)
{
@@ -38,12 +38,12 @@ public static Dictionary RunAnalysis(Model fdModel, string strux
units = Results.UnitResults.Default();
// It needs to check if model has been runned
// Always Return the FeaNode Result
- resultTypes.Insert(0, Results.ResultType.FeaNode);
- resultTypes.Insert(1, Results.ResultType.FeaBar);
- resultTypes.Insert(1, Results.ResultType.FeaShell);
+ resultTypes.Insert(0, typeof(Results.FeaNode));
+ resultTypes.Insert(1, typeof(Results.FeaBar));
+ resultTypes.Insert(2, typeof(Results.FeaShell));
// Create Bsc files from resultTypes
- var listProcs = resultTypes.Select(r => Results.ResultAttributeExtentions.ListProcs[r]);
+ //var listProcs = resultTypes.Select(r => Results.ResultAttributeExtentions.ListProcs[r]);
var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(resultTypes, struxmlPath, units);
var rtn = fdModel.FdApp.RunAnalysis(struxmlPath, analysis, bscPathsFromResultTypes, docxTemplatePath, endSession, closeOpenWindows);
diff --git a/FemDesign.Dynamo/Dynamo/Calculate/LoadCombination.cs b/FemDesign.Dynamo/Dynamo/Calculate/LoadCombination.cs
index 68e3c757b..3e68e5491 100644
--- a/FemDesign.Dynamo/Dynamo/Calculate/LoadCombination.cs
+++ b/FemDesign.Dynamo/Dynamo/Calculate/LoadCombination.cs
@@ -25,7 +25,7 @@ public partial class LoadCombination
/// Ground water level
///
[IsVisibleInDynamoLibrary(true)]
- public static Loads.LoadCombination SetupCalculation(Loads.LoadCombination loadCombination, int ImpfRqd = 0, int StabRqd = 0, bool NLE = false, bool PL = false, bool NLS = false, bool Cr = false, bool f2nd = false, bool Im = false, int Waterlevel = 0)
+ public static Loads.LoadCombination SetupCalculation(Loads.LoadCombination loadCombination, int ImpfRqd = 0, int StabRqd = 0, bool NLE = false, bool PL = false, bool NLS = false, bool Cr = false, bool f2nd = false, int Im = 0, int Waterlevel = 0)
{
loadCombination.CombItem = new Calculate.CombItem(ImpfRqd, StabRqd, NLE, PL, NLS, Cr, f2nd, Im, Waterlevel);
return loadCombination;
diff --git a/FemDesign.Dynamo/Dynamo/Calculate/Stage.cs b/FemDesign.Dynamo/Dynamo/Calculate/Stage.cs
index 6a3f4887e..78e0e8528 100644
--- a/FemDesign.Dynamo/Dynamo/Calculate/Stage.cs
+++ b/FemDesign.Dynamo/Dynamo/Calculate/Stage.cs
@@ -1,8 +1,13 @@
using System;
using System.Xml.Serialization;
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+#endregion
+
namespace FemDesign.Calculate
{
+ [IsVisibleInDynamoLibrary(false)]
public partial class Stage
{
diff --git a/FemDesign.Dynamo/Dynamo/Deconstruct/Deconstruct.cs b/FemDesign.Dynamo/Dynamo/Deconstruct/Deconstruct.cs
index f4090aec9..5896b9c78 100644
--- a/FemDesign.Dynamo/Dynamo/Deconstruct/Deconstruct.cs
+++ b/FemDesign.Dynamo/Dynamo/Deconstruct/Deconstruct.cs
@@ -88,7 +88,7 @@ public static Dictionary FictitiousBarDeconstruct(FemDesign.Mode
return new Dictionary
{
{"Guid", fictitiousBar.Guid},
- {"AnalyticalID", fictitiousBar.Identifier},
+ {"AnalyticalID", fictitiousBar.Name},
{"Curve", fictitiousBar.Edge.ToDynamo()},
{"AE", fictitiousBar.AE},
{"ItG", fictitiousBar.ItG},
@@ -112,7 +112,7 @@ public static Dictionary CoverDeconstruct(FemDesign.Cover cover)
return new Dictionary
{
{"Guid", cover.Guid},
- {"Id", cover.Identifier},
+ {"Id", cover.Name},
{"Surface", cover.GetDynamoSurface()},
{"Contours", cover.GetDynamoCurves()}
};
@@ -369,7 +369,7 @@ public static Dictionary LoadCaseDeconstruct(FemDesign.Loads.Loa
return new Dictionary
{
{"Guid", loadCase.Guid.ToString()},
- {"Name", loadCase.Identifier},
+ {"Name", loadCase.Name},
{"Type", loadCase.Type.ToString()},
{"DurationClass", loadCase.DurationClass.ToString()}
};
@@ -387,7 +387,7 @@ public static Dictionary LoadCombinationDeconstruct(FemDesign.Lo
return new Dictionary
{
{"Guid", loadCombination.Guid},
- {"Name", loadCombination.Identifier},
+ {"Name", loadCombination.Name},
{"Type", loadCombination.Type.ToString()},
{"LoadCases", loadCombination.GetLoadCaseGuidsAsString()},
{"Gammas", loadCombination.GetGammas()}
@@ -415,7 +415,7 @@ public static Dictionary MaterialDeconstruct(FemDesign.Materials
{"Guid", material.Guid},
{"Standard", standard},
{"Country", country},
- {"Name", material.Identifier}
+ {"Name", material.Name}
};
}
@@ -538,7 +538,7 @@ public static Dictionary StoreyDeconstruct(FemDesign.StructureGr
{"Direction", storey.Direction.ToDynamo()},
{"DimensionX", storey.DimensionX},
{"DimensionY", storey.DimensionY},
- {"Name", storey.Identifier}
+ {"Name", storey.Name}
};
}
@@ -599,7 +599,7 @@ public static Dictionary FictitiousShellDeconstruct(FemDesign.Mo
return new Dictionary
{
{"Guid", fictitiousShell.Guid},
- {"AnalyticalId", fictitiousShell.Identifier},
+ {"AnalyticalId", fictitiousShell.Name},
{"Surface", fictitiousShell.Region.ToDynamoSurface()},
{"MembraneStiffness", fictitiousShell.MembraneStiffness},
{"FlexuralStiffness", fictitiousShell.FlexuralStiffness},
@@ -630,7 +630,7 @@ public static Dictionary DiaphragmDeconstruct(FemDesign.Modellin
{
{"Guid", diaphragm.Guid},
{"Surface", diaphragm.Region.ToDynamoSurface()},
- {"Identifier", diaphragm.Identifier}
+ {"Identifier", diaphragm.Name}
};
}
@@ -671,7 +671,7 @@ public static Dictionary SectionDeconstruct(FemDesign.Sections.S
return new Dictionary
{
{"Guid", section.Guid},
- {"Name", section.Identifier},
+ {"Name", section.Name},
{"Surfaces", section.RegionGroup.ToDynamo()},
{"SectionType", section.Type},
{"MaterialType", section.MaterialType},
@@ -710,7 +710,7 @@ public static Dictionary EdgeConnectionDeconstruct(FemDesign.She
return new Dictionary
{
{"Guid", shellEdgeConnection.Guid},
- {"AnalyticalID", shellEdgeConnection.Identifier},
+ {"AnalyticalID", shellEdgeConnection.Name},
{"PredefinedName", null},
{"PredefinedGuid", null},
{"Friction", null},
@@ -723,7 +723,7 @@ public static Dictionary EdgeConnectionDeconstruct(FemDesign.She
return new Dictionary
{
{"Guid", shellEdgeConnection.Guid},
- {"AnalyticalID", shellEdgeConnection.Identifier},
+ {"AnalyticalID", shellEdgeConnection.Name},
{"PredefinedName", null},
{"PredefinedGuid", null},
{"Friction", shellEdgeConnection.Rigidity.Friction},
@@ -736,8 +736,8 @@ public static Dictionary EdgeConnectionDeconstruct(FemDesign.She
return new Dictionary
{
{"Guid", shellEdgeConnection.Guid},
- {"AnalyticalID", shellEdgeConnection.Identifier},
- {"PredefinedName", shellEdgeConnection.PredefRigidity.Identifier},
+ {"AnalyticalID", shellEdgeConnection.Name},
+ {"PredefinedName", shellEdgeConnection.PredefRigidity.Name},
{"PredefinedGuid", shellEdgeConnection.PredefRigidity.Guid},
{"Friction", null},
{"Motions", shellEdgeConnection.PredefRigidity.Rigidity.Motions},
@@ -749,8 +749,8 @@ public static Dictionary EdgeConnectionDeconstruct(FemDesign.She
return new Dictionary
{
{"Guid", shellEdgeConnection.Guid},
- {"AnalyticalID", shellEdgeConnection.Identifier},
- {"PredefinedName", shellEdgeConnection.PredefRigidity.Identifier},
+ {"AnalyticalID", shellEdgeConnection.Name},
+ {"PredefinedName", shellEdgeConnection.PredefRigidity.Name},
{"PredefinedGuid", shellEdgeConnection.PredefRigidity.Guid},
{"Friction", shellEdgeConnection.PredefRigidity.Rigidity.Friction},
{"Motions", shellEdgeConnection.PredefRigidity.Rigidity.Motions},
diff --git a/FemDesign.Dynamo/Dynamo/GenericClasses/LocationValue.cs b/FemDesign.Dynamo/Dynamo/GenericClasses/LocationValue.cs
index 04c4ef3e4..7d96dc426 100644
--- a/FemDesign.Dynamo/Dynamo/GenericClasses/LocationValue.cs
+++ b/FemDesign.Dynamo/Dynamo/GenericClasses/LocationValue.cs
@@ -7,7 +7,7 @@
namespace FemDesign
{
[IsVisibleInDynamoLibrary(false)]
- public partial class LocationValue: Geometry.FdPoint3d
+ public partial class LocationValue: Geometry.Point3d
{
}
diff --git a/FemDesign.Dynamo/Dynamo/GenericClasses/NamedEntityBase.cs b/FemDesign.Dynamo/Dynamo/GenericClasses/NamedEntityBase.cs
new file mode 100644
index 000000000..a8b16f31a
--- /dev/null
+++ b/FemDesign.Dynamo/Dynamo/GenericClasses/NamedEntityBase.cs
@@ -0,0 +1,20 @@
+using System.Xml.Serialization;
+
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+#endregion
+
+namespace FemDesign
+{
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class NamedEntityBase
+ {
+
+ }
+
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class NamedEntityPartBase
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/FdCoordinateSystem.cs b/FemDesign.Dynamo/Dynamo/Geometry/CoordinateSystem.cs
similarity index 54%
rename from FemDesign.Dynamo/Dynamo/Geometry/FdCoordinateSystem.cs
rename to FemDesign.Dynamo/Dynamo/Geometry/CoordinateSystem.cs
index adf25dbae..558b4dc2a 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/FdCoordinateSystem.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/CoordinateSystem.cs
@@ -8,20 +8,20 @@
namespace FemDesign.Geometry
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FdCoordinateSystem
+ public partial class CoordinateSystem
{
#region dynamo
///
/// Create FdCoordinateSystem from Dynamo coordinate system of a Line or NurbsCurve(?).
/// This method realignes the coordinate system.
///
- internal static FdCoordinateSystem FromDynamoCoordinateSystemLine(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
+ internal static CoordinateSystem FromDynamoCoordinateSystemLine(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
{
- FdPoint3d origin = FdPoint3d.FromDynamo(obj.Origin);
- FdVector3d localX = FdVector3d.FromDynamo(obj.YAxis);
- FdVector3d localY = FdVector3d.FromDynamo(obj.XAxis.Reverse());
- FdVector3d localZ = localX.Cross(localY).Normalize();
- return new FdCoordinateSystem(origin, localX, localY, localZ);
+ Point3d origin = Point3d.FromDynamo(obj.Origin);
+ Vector3d localX = Vector3d.FromDynamo(obj.YAxis);
+ Vector3d localY = Vector3d.FromDynamo(obj.XAxis.Reverse());
+ Vector3d localZ = localX.Cross(localY).Normalize();
+ return new CoordinateSystem(origin, localX, localY, localZ);
}
///
@@ -30,32 +30,32 @@ internal static FdCoordinateSystem FromDynamoCoordinateSystemLine(Autodesk.Desig
/// Dynamo Arcs and Circles follow left-hand rule.
/// This method realignes the coordinate system.
///
- internal static FdCoordinateSystem FromDynamoCoordinateSystemArcOrCircle(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
+ internal static CoordinateSystem FromDynamoCoordinateSystemArcOrCircle(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
{
- FdPoint3d origin = FdPoint3d.FromDynamo(obj.Origin);
- FdVector3d localX = FdVector3d.FromDynamo(obj.YAxis);
- FdVector3d localY = FdVector3d.FromDynamo(obj.XAxis);
- FdVector3d localZ = localX.Cross(localY).Normalize();
- return new FdCoordinateSystem(origin, localX, localY, localZ);
+ Point3d origin = Point3d.FromDynamo(obj.Origin);
+ Vector3d localX = Vector3d.FromDynamo(obj.YAxis);
+ Vector3d localY = Vector3d.FromDynamo(obj.XAxis);
+ Vector3d localZ = localX.Cross(localY).Normalize();
+ return new CoordinateSystem(origin, localX, localY, localZ);
}
///
/// Create FdCoordinateSystem from Dynamo coordinate system of a Surface.
/// No realignment neccessary.
///
- internal static FdCoordinateSystem FromDynamoCoordinateSystemSurface(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
+ internal static CoordinateSystem FromDynamoCoordinateSystemSurface(Autodesk.DesignScript.Geometry.CoordinateSystem obj)
{
- FdPoint3d origin = FdPoint3d.FromDynamo(obj.Origin);
- FdVector3d localX = FdVector3d.FromDynamo(obj.XAxis);
- FdVector3d localY = FdVector3d.FromDynamo(obj.YAxis);
- FdVector3d localZ = FdVector3d.FromDynamo(obj.ZAxis);
- return new FdCoordinateSystem(origin, localX, localY, localZ);
+ Point3d origin = Point3d.FromDynamo(obj.Origin);
+ Vector3d localX = Vector3d.FromDynamo(obj.XAxis);
+ Vector3d localY = Vector3d.FromDynamo(obj.YAxis);
+ Vector3d localZ = Vector3d.FromDynamo(obj.ZAxis);
+ return new CoordinateSystem(origin, localX, localY, localZ);
}
///
/// Create FdCoordinateSystem from Dynamo coordinate system on curve mid u-point.
///
- internal static FdCoordinateSystem FromDynamoCurve(Autodesk.DesignScript.Geometry.Curve obj)
+ internal static CoordinateSystem FromDynamoCurve(Autodesk.DesignScript.Geometry.Curve obj)
{
// CoordinateSystemAtParameter returns a coordinate system on curve
// with origin at the point at the given parameter.
@@ -67,7 +67,7 @@ internal static FdCoordinateSystem FromDynamoCurve(Autodesk.DesignScript.Geometr
// Note: Arcs and Circles in Dynamo are defined with left-hand rule while coordinate system is defined by right-hand rule
if (obj.GetType() == typeof(Autodesk.DesignScript.Geometry.Arc) || obj.GetType() == typeof(Autodesk.DesignScript.Geometry.Circle))
{
- return FdCoordinateSystem.FromDynamoCoordinateSystemArcOrCircle(cs);
+ return CoordinateSystem.FromDynamoCoordinateSystemArcOrCircle(cs);
}
else
{
@@ -78,10 +78,10 @@ internal static FdCoordinateSystem FromDynamoCurve(Autodesk.DesignScript.Geometr
///
/// Create FdCoordinateSystem from Dynamo coordinate system on surface mid u/v-point.
///
- internal static FdCoordinateSystem FromDynamoSurface(Autodesk.DesignScript.Geometry.Surface obj)
+ internal static CoordinateSystem FromDynamoSurface(Autodesk.DesignScript.Geometry.Surface obj)
{
Autodesk.DesignScript.Geometry.CoordinateSystem cs = obj.CoordinateSystemAtParameter(0.5, 0.5);
- return FdCoordinateSystem.FromDynamoCoordinateSystemSurface(cs);
+ return CoordinateSystem.FromDynamoCoordinateSystemSurface(cs);
}
#endregion
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/Edge.cs b/FemDesign.Dynamo/Dynamo/Geometry/Edge.cs
index e494bff7a..69cc9e14c 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/Edge.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Edge.cs
@@ -129,11 +129,11 @@ public static Geometry.Edge FromDynamoArc1(Autodesk.DesignScript.Geometry.Arc ob
double radius = obj.Radius;
double startAngle = 0;
double endAngle = startAngle + Degree.ToRadians(obj.SweepAngle);
- FdPoint3d centerPoint = FdPoint3d.FromDynamo(obj.CenterPoint);
- FdVector3d xAxis = new FdVector3d(centerPoint, FdPoint3d.FromDynamo(obj.StartPoint)).Normalize();
+ Point3d centerPoint = Point3d.FromDynamo(obj.CenterPoint);
+ Vector3d xAxis = new Vector3d(centerPoint, Point3d.FromDynamo(obj.StartPoint)).Normalize();
// lcs
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoCurve(obj);
// return
return new Geometry.Edge(radius, startAngle, endAngle, centerPoint, xAxis, cs);
@@ -145,12 +145,12 @@ public static Geometry.Edge FromDynamoArc1(Autodesk.DesignScript.Geometry.Arc ob
///
public static Geometry.Edge FromDynamoArc2(Autodesk.DesignScript.Geometry.Arc obj)
{
- FdPoint3d p0 = FdPoint3d.FromDynamo(obj.StartPoint);
- FdPoint3d p1 = FdPoint3d.FromDynamo(obj.PointAtParameter(0.5));
- FdPoint3d p2 = FdPoint3d.FromDynamo(obj.EndPoint);
+ Point3d p0 = Point3d.FromDynamo(obj.StartPoint);
+ Point3d p1 = Point3d.FromDynamo(obj.PointAtParameter(0.5));
+ Point3d p2 = Point3d.FromDynamo(obj.EndPoint);
// lcs
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoCurve(obj);
// return
return new Geometry.Edge(p0, p1, p2, cs);
@@ -162,10 +162,10 @@ public static Geometry.Edge FromDynamoArc2(Autodesk.DesignScript.Geometry.Arc ob
public static Geometry.Edge FromDynamoCircle(Autodesk.DesignScript.Geometry.Circle obj)
{
double radius = obj.Radius;
- FdPoint3d centerPoint = FdPoint3d.FromDynamo(obj.CenterPoint);
+ Point3d centerPoint = Point3d.FromDynamo(obj.CenterPoint);
// lcs
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoCurve(obj);
// return
return new Geometry.Edge(radius, centerPoint, cs);
@@ -176,11 +176,11 @@ public static Geometry.Edge FromDynamoCircle(Autodesk.DesignScript.Geometry.Circ
///
public static Geometry.Edge FromDynamoLine(Autodesk.DesignScript.Geometry.Line obj)
{
- FdPoint3d startPoint = FdPoint3d.FromDynamo(obj.StartPoint);
- FdPoint3d endPoint = FdPoint3d.FromDynamo(obj.EndPoint);
+ Point3d startPoint = Point3d.FromDynamo(obj.StartPoint);
+ Point3d endPoint = Point3d.FromDynamo(obj.EndPoint);
// lcs
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoCurve(obj);
// return
return new Geometry.Edge(startPoint, endPoint, cs);
@@ -191,11 +191,11 @@ public static Geometry.Edge FromDynamoLine(Autodesk.DesignScript.Geometry.Line o
///
public static Geometry.Edge FromDynamoLinearNurbsCurve(Autodesk.DesignScript.Geometry.NurbsCurve obj)
{
- FdPoint3d startPoint = FdPoint3d.FromDynamo(obj.StartPoint);
- FdPoint3d endPoint = FdPoint3d.FromDynamo(obj.EndPoint);
+ Point3d startPoint = Point3d.FromDynamo(obj.StartPoint);
+ Point3d endPoint = Point3d.FromDynamo(obj.EndPoint);
// lcs
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoCurve(obj);
// return
return new Geometry.Edge(startPoint, endPoint, cs);
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/FdPoint2d.cs b/FemDesign.Dynamo/Dynamo/Geometry/Point2d.cs
similarity index 84%
rename from FemDesign.Dynamo/Dynamo/Geometry/FdPoint2d.cs
rename to FemDesign.Dynamo/Dynamo/Geometry/Point2d.cs
index f01cefa4a..2083fdd84 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/FdPoint2d.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Point2d.cs
@@ -8,7 +8,7 @@
namespace FemDesign.Geometry
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FdPoint2d
+ public partial class Point2d
{
}
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/FdPoint3d.cs b/FemDesign.Dynamo/Dynamo/Geometry/Point3d.cs
similarity index 76%
rename from FemDesign.Dynamo/Dynamo/Geometry/FdPoint3d.cs
rename to FemDesign.Dynamo/Dynamo/Geometry/Point3d.cs
index 0034c7184..1c1f202ea 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/FdPoint3d.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Point3d.cs
@@ -9,15 +9,15 @@
namespace FemDesign.Geometry
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FdPoint3d
+ public partial class Point3d
{
#region dynamo
///
/// Create FdPoint3d from Dynamo point.
///
- public static FdPoint3d FromDynamo(Autodesk.DesignScript.Geometry.Point point)
+ public static Point3d FromDynamo(Autodesk.DesignScript.Geometry.Point point)
{
- FdPoint3d newPoint = new FdPoint3d(point.X, point.Y, point.Z);
+ Point3d newPoint = new Point3d(point.X, point.Y, point.Z);
return newPoint;
}
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/Region.cs b/FemDesign.Dynamo/Dynamo/Geometry/Region.cs
index b3e16f70c..016bea823 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/Region.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Region.cs
@@ -152,7 +152,7 @@ public static Geometry.Region FromDynamo(Autodesk.DesignScript.Geometry.Surface
}
// get LCS
- FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoSurface(obj);
+ CoordinateSystem cs = CoordinateSystem.FromDynamoSurface(obj);
// return
return new Geometry.Region(contours, cs);
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/FdVector2d.cs b/FemDesign.Dynamo/Dynamo/Geometry/Vector2d.cs
similarity index 84%
rename from FemDesign.Dynamo/Dynamo/Geometry/FdVector2d.cs
rename to FemDesign.Dynamo/Dynamo/Geometry/Vector2d.cs
index 1233e4e7c..4437c88b2 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/FdVector2d.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Vector2d.cs
@@ -8,7 +8,7 @@
namespace FemDesign.Geometry
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FdVector2d
+ public partial class Vector2d
{
}
diff --git a/FemDesign.Dynamo/Dynamo/Geometry/FdVector3d.cs b/FemDesign.Dynamo/Dynamo/Geometry/Vector3d.cs
similarity index 76%
rename from FemDesign.Dynamo/Dynamo/Geometry/FdVector3d.cs
rename to FemDesign.Dynamo/Dynamo/Geometry/Vector3d.cs
index a53951685..889d998be 100644
--- a/FemDesign.Dynamo/Dynamo/Geometry/FdVector3d.cs
+++ b/FemDesign.Dynamo/Dynamo/Geometry/Vector3d.cs
@@ -9,15 +9,15 @@
namespace FemDesign.Geometry
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FdVector3d
+ public partial class Vector3d
{
#region dynamo
///
/// Create FdVector3d from Dynamo vector.
///
- public static FdVector3d FromDynamo(Autodesk.DesignScript.Geometry.Vector vector)
+ public static Vector3d FromDynamo(Autodesk.DesignScript.Geometry.Vector vector)
{
- FdVector3d newVector = new FdVector3d(vector.X, vector.Y, vector.Z);
+ Vector3d newVector = new Vector3d(vector.X, vector.Y, vector.Z);
return newVector;
}
diff --git a/FemDesign.Dynamo/Dynamo/Loads/Footfall.cs b/FemDesign.Dynamo/Dynamo/Loads/Footfall.cs
index 5138d2530..f04abc74a 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/Footfall.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/Footfall.cs
@@ -19,7 +19,7 @@ public partial class Footfall
[IsVisibleInDynamoLibrary(true)]
public static Footfall FullExcitation(Autodesk.DesignScript.Geometry.Point point, string identifier = "FE", string comment = "")
{
- var p0 = FdPoint3d.FromDynamo(point);
+ var p0 = Point3d.FromDynamo(point);
return new Footfall(p0, identifier, comment);
}
diff --git a/FemDesign.Dynamo/Dynamo/Loads/LineLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/LineLoad.cs
index 53229a4d2..e66566c07 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/LineLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/LineLoad.cs
@@ -24,8 +24,8 @@ public static LineLoad ForceUniform(Autodesk.DesignScript.Geometry.Curve curve,
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d _startForce = Geometry.FdVector3d.FromDynamo(force);
- Geometry.FdVector3d _endForce = _startForce;
+ Geometry.Vector3d _startForce = Geometry.Vector3d.FromDynamo(force);
+ Geometry.Vector3d _endForce = _startForce;
// check zero vector
if (_startForce.IsZero())
@@ -52,8 +52,8 @@ public static LineLoad Force(Autodesk.DesignScript.Geometry.Curve curve, Autodes
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d _startForce = Geometry.FdVector3d.FromDynamo(startForce);
- Geometry.FdVector3d _endForce = Geometry.FdVector3d.FromDynamo(endForce);
+ Geometry.Vector3d _startForce = Geometry.Vector3d.FromDynamo(startForce);
+ Geometry.Vector3d _endForce = Geometry.Vector3d.FromDynamo(endForce);
//
return new LineLoad(edge, _startForce, _endForce, loadCase, ForceLoadType.Force, comment, constLoadDir, loadProjection: false);
@@ -73,8 +73,8 @@ public static LineLoad MomentUniform(Autodesk.DesignScript.Geometry.Curve curve,
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d _startForce = Geometry.FdVector3d.FromDynamo(force);
- Geometry.FdVector3d _endForce = _startForce;
+ Geometry.Vector3d _startForce = Geometry.Vector3d.FromDynamo(force);
+ Geometry.Vector3d _endForce = _startForce;
// check zero vector
if (_startForce.IsZero())
@@ -100,8 +100,8 @@ public static LineLoad Moment(Autodesk.DesignScript.Geometry.Curve curve, Autode
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d _startForce = Geometry.FdVector3d.FromDynamo(startForce);
- Geometry.FdVector3d _endForce = Geometry.FdVector3d.FromDynamo(endForce);
+ Geometry.Vector3d _startForce = Geometry.Vector3d.FromDynamo(startForce);
+ Geometry.Vector3d _endForce = Geometry.Vector3d.FromDynamo(endForce);
return new LineLoad(edge, _startForce, _endForce, loadCase, ForceLoadType.Moment, comment, constLoadDir, loadProjection: false);
}
diff --git a/FemDesign.Dynamo/Dynamo/Loads/LineStressLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/LineStressLoad.cs
index 465b084de..465dac9c2 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/LineStressLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/LineStressLoad.cs
@@ -25,7 +25,7 @@ public static LineStressLoad Define(Autodesk.DesignScript.Geometry.Curve curve,
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d v = Geometry.FdVector3d.FromDynamo(direction);
+ Geometry.Vector3d v = Geometry.Vector3d.FromDynamo(direction);
// return
return new LineStressLoad(edge, v, topBottomLocationValues, loadCase, comments);
diff --git a/FemDesign.Dynamo/Dynamo/Loads/LineTemperatureLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/LineTemperatureLoad.cs
index 02fc380ef..10756f731 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/LineTemperatureLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/LineTemperatureLoad.cs
@@ -25,7 +25,7 @@ public static LineTemperatureLoad Define(Autodesk.DesignScript.Geometry.Curve cu
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc1(curve);
- Geometry.FdVector3d v = Geometry.FdVector3d.FromDynamo(direction);
+ Geometry.Vector3d v = Geometry.Vector3d.FromDynamo(direction);
// return
return new LineTemperatureLoad(edge, v, topBottomLocationValues, loadCase, comments);
diff --git a/FemDesign.Dynamo/Dynamo/Loads/LoadCase.cs b/FemDesign.Dynamo/Dynamo/Loads/LoadCase.cs
index af2b998a9..49a4f02c3 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/LoadCase.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/LoadCase.cs
@@ -41,7 +41,7 @@ public static LoadCase GetLoadCaseFromListByName(List loadCases, strin
{
foreach (LoadCase _loadCase in loadCases)
{
- if (_loadCase.Identifier == name)
+ if (_loadCase.Name == name)
{
return _loadCase;
}
diff --git a/FemDesign.Dynamo/Dynamo/Loads/LoadLocationValue.cs b/FemDesign.Dynamo/Dynamo/Loads/LoadLocationValue.cs
index efe738fa0..c77cdbae4 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/LoadLocationValue.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/LoadLocationValue.cs
@@ -18,7 +18,7 @@ public partial class LoadLocationValue: LocationValue
[IsVisibleInDynamoLibrary(true)]
public static LoadLocationValue Define(Autodesk.DesignScript.Geometry.Point point, double intensity)
{
- return new LoadLocationValue(Geometry.FdPoint3d.FromDynamo(point), intensity);
+ return new LoadLocationValue(Geometry.Point3d.FromDynamo(point), intensity);
}
#endregion
diff --git a/FemDesign.Dynamo/Dynamo/Loads/PointLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/PointLoad.cs
index c1c4cb1d8..18bba1906 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/PointLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/PointLoad.cs
@@ -21,8 +21,8 @@ public partial class PointLoad: ForceLoadBase
[IsVisibleInDynamoLibrary(true)]
public static PointLoad Force(Autodesk.DesignScript.Geometry.Point point, Autodesk.DesignScript.Geometry.Vector force, LoadCase loadCase, string comment = "")
{
- var p0 = Geometry.FdPoint3d.FromDynamo(point);
- var v0 = Geometry.FdVector3d.FromDynamo(force);
+ var p0 = Geometry.Point3d.FromDynamo(point);
+ var v0 = Geometry.Vector3d.FromDynamo(force);
PointLoad pointLoad = new PointLoad(p0, v0, loadCase, comment, ForceLoadType.Force);
return pointLoad;
}
@@ -37,8 +37,8 @@ public static PointLoad Force(Autodesk.DesignScript.Geometry.Point point, Autode
[IsVisibleInDynamoLibrary(true)]
public static PointLoad Moment(Autodesk.DesignScript.Geometry.Point point, Autodesk.DesignScript.Geometry.Vector moment, LoadCase loadCase, string comment = "")
{
- var p0 = Geometry.FdPoint3d.FromDynamo(point);
- var v0 = Geometry.FdVector3d.FromDynamo(moment);
+ var p0 = Geometry.Point3d.FromDynamo(point);
+ var v0 = Geometry.Vector3d.FromDynamo(moment);
PointLoad pointLoad = new PointLoad(p0, v0, loadCase, comment, ForceLoadType.Moment);
return pointLoad;
}
diff --git a/FemDesign.Dynamo/Dynamo/Loads/PressureLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/PressureLoad.cs
index 1f1e48b97..af6229458 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/PressureLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/PressureLoad.cs
@@ -30,7 +30,7 @@ public static PressureLoad Define(Autodesk.DesignScript.Geometry.Surface surface
Geometry.Region region = Geometry.Region.FromDynamo(surface);
// normalize direction
- Geometry.FdVector3d _loadDirection = Geometry.FdVector3d.FromDynamo(direction).Normalize();
+ Geometry.Vector3d _loadDirection = Geometry.Vector3d.FromDynamo(direction).Normalize();
// create SurfaceLoad
PressureLoad _pressureLoad = new PressureLoad(region, _loadDirection, z0, q0, qh, loadCase, comment, false, ForceLoadType.Force);
diff --git a/FemDesign.Dynamo/Dynamo/Loads/SurfaceLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/SurfaceLoad.cs
index e4fa551cc..dd1d62b7d 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/SurfaceLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/SurfaceLoad.cs
@@ -21,7 +21,7 @@ public partial class SurfaceLoad: ForceLoadBase
public static SurfaceLoad Uniform(Autodesk.DesignScript.Geometry.Surface surface, Autodesk.DesignScript.Geometry.Vector force, LoadCase loadCase, string comment = "")
{
Geometry.Region region = Geometry.Region.FromDynamo(surface);
- Geometry.FdVector3d _force = Geometry.FdVector3d.FromDynamo(force);
+ Geometry.Vector3d _force = Geometry.Vector3d.FromDynamo(force);
SurfaceLoad surfaceLoad = SurfaceLoad.Uniform(region, _force, loadCase, false, comment);
@@ -48,7 +48,7 @@ public static SurfaceLoad Variable(Autodesk.DesignScript.Geometry.Surface surfac
}
Geometry.Region region = Geometry.Region.FromDynamo(surface);
- Geometry.FdVector3d loadDirection = Geometry.FdVector3d.FromDynamo(direction).Normalize();
+ Geometry.Vector3d loadDirection = Geometry.Vector3d.FromDynamo(direction).Normalize();
SurfaceLoad surfaceLoad = SurfaceLoad.Variable(region, loadDirection, loadLocationValue, loadCase, false, comment);
return surfaceLoad;
diff --git a/FemDesign.Dynamo/Dynamo/Loads/SurfaceTemperatureLoad.cs b/FemDesign.Dynamo/Dynamo/Loads/SurfaceTemperatureLoad.cs
index 14301d5b6..549c66b62 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/SurfaceTemperatureLoad.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/SurfaceTemperatureLoad.cs
@@ -25,7 +25,7 @@ public static SurfaceTemperatureLoad Define(Autodesk.DesignScript.Geometry.Surfa
{
// convert geometry
Geometry.Region region = Geometry.Region.FromDynamo(surface);
- Geometry.FdVector3d dir = Geometry.FdVector3d.FromDynamo(direction);
+ Geometry.Vector3d dir = Geometry.Vector3d.FromDynamo(direction);
// return
return new SurfaceTemperatureLoad(region, dir, tempLocValue, loadCase, comment);
diff --git a/FemDesign.Dynamo/Dynamo/Loads/TopBotLocationValue.cs b/FemDesign.Dynamo/Dynamo/Loads/TopBotLocationValue.cs
index a0aa7aeed..63dbd479c 100644
--- a/FemDesign.Dynamo/Dynamo/Loads/TopBotLocationValue.cs
+++ b/FemDesign.Dynamo/Dynamo/Loads/TopBotLocationValue.cs
@@ -7,7 +7,7 @@
namespace FemDesign.Loads
{
[IsVisibleInDynamoLibrary(false)]
- public partial class TopBotLocationValue: Geometry.FdPoint3d
+ public partial class TopBotLocationValue: Geometry.Point3d
{
#region dynamo
///
@@ -21,7 +21,7 @@ public partial class TopBotLocationValue: Geometry.FdPoint3d
public static TopBotLocationValue Define(Autodesk.DesignScript.Geometry.Point point, double topVal, double bottomVal)
{
// convert geometry
- Geometry.FdPoint3d p = Geometry.FdPoint3d.FromDynamo(point);
+ Geometry.Point3d p = Geometry.Point3d.FromDynamo(point);
return new TopBotLocationValue(p, topVal, bottomVal);
}
diff --git a/FemDesign.Dynamo/Dynamo/Model/Model.cs b/FemDesign.Dynamo/Dynamo/Model/Model.cs
index 3ba75d132..5fd7a8fb4 100644
--- a/FemDesign.Dynamo/Dynamo/Model/Model.cs
+++ b/FemDesign.Dynamo/Dynamo/Model/Model.cs
@@ -172,19 +172,36 @@ public static Model ReadStruxml(string filePathStruxml)
///
[IsVisibleInDynamoLibrary(true)]
[MultiReturn(new[]{"Model", "FdFeaModel", "Results" })]
- public static Dictionary ReadStr(string strPath, List resultTypes, Results.UnitResults units)
+ public static Dictionary ReadStr(string strPath, List resultTypes, Results.UnitResults units)
{
Results.FDfea fdFeaModel = null;
// It needs to check if model has been runned
// Always Return the FeaNode Result
- resultTypes.Insert(0, Results.ResultType.FeaNode);
- resultTypes.Insert(1, Results.ResultType.FeaBar);
- resultTypes.Insert(2, Results.ResultType.FeaShell);
+ resultTypes.Insert(0, "FeaNode");
+ resultTypes.Insert(1, "FeaBar");
+ resultTypes.Insert(2, "FeaShell");
+
+ var notValidResultTypes = new List();
+ var _resultTypes = resultTypes.Select(r =>
+ {
+ var sucess = Results.ResultTypes.All.TryGetValue(r, out Type value);
+ if (sucess)
+ return value;
+ else
+ {
+ notValidResultTypes.Add(r);
+ return null;
+ }
+ });
+ if (notValidResultTypes.Count() != 0)
+ {
+ throw new Exception( "The following strings are not valid result types: " + string.Join(", ", notValidResultTypes));
+ }
// Create Bsc files from resultTypes
- var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(resultTypes, strPath, units);
+ var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(_resultTypes, strPath, units);
// Create FdScript
var fdScript = FemDesign.Calculate.FdScript.ReadStr(strPath, bscPathsFromResultTypes);
@@ -202,7 +219,7 @@ public static Dictionary ReadStr(string strPath, List feaBarRes = new List();
List feaShellRes = new List();
- if (resultTypes != null && resultTypes.Any())
+ if (_resultTypes != null && _resultTypes.Any())
{
foreach (var cmd in fdScript.CmdListGen)
{
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedLines.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedLines.cs
index 7c506190d..15952dd51 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedLines.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedLines.cs
@@ -8,7 +8,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class ConnectedLines: EntityBase
+ public partial class ConnectedLines
{
#region dynamo
[IsVisibleInDynamoLibrary(true)]
@@ -17,8 +17,8 @@ public static ConnectedLines Define(Autodesk.DesignScript.Geometry.Curve firstCu
// convert geometry
Geometry.Edge edge0 = Geometry.Edge.FromDynamoLineOrArc2(firstCurve);
Geometry.Edge edge1 = Geometry.Edge.FromDynamoLineOrArc2(secondCurve);
- Geometry.FdVector3d x = Geometry.FdVector3d.FromDynamo(localX);
- Geometry.FdVector3d y = Geometry.FdVector3d.FromDynamo(localY);
+ Geometry.Vector3d x = Geometry.Vector3d.FromDynamo(localX);
+ Geometry.Vector3d y = Geometry.Vector3d.FromDynamo(localY);
// rigidity
Releases.RigidityDataType3 rigidity = new Releases.RigidityDataType3(motions, rotations);
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedPoints.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedPoints.cs
index 2ca7f8510..1072b0117 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedPoints.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/ConnectedPoints.cs
@@ -8,7 +8,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class ConnectedPoints: EntityBase
+ public partial class ConnectedPoints
{
#region dynamo
@@ -17,8 +17,8 @@ public partial class ConnectedPoints: EntityBase
public static ConnectedPoints Define(Autodesk.DesignScript.Geometry.Point firstPoint, Autodesk.DesignScript.Geometry.Point secondPoint, Releases.Motions motions, Releases.Rotations rotations, System.Guid[] references, string identifier)
{
// convert geometry
- Geometry.FdPoint3d p1 = Geometry.FdPoint3d.FromDynamo(firstPoint);
- Geometry.FdPoint3d p2 = Geometry.FdPoint3d.FromDynamo(secondPoint);
+ Geometry.Point3d p1 = Geometry.Point3d.FromDynamo(firstPoint);
+ Geometry.Point3d p2 = Geometry.Point3d.FromDynamo(secondPoint);
// rigidity
Releases.RigidityDataType2 rigidity = new Releases.RigidityDataType2(motions, rotations);
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/Diaphragm.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/Diaphragm.cs
index 84fa3a016..b28ddbf24 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/Diaphragm.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/Diaphragm.cs
@@ -7,7 +7,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class Diaphragm : EntityBase
+ public partial class Diaphragm
{
[IsVisibleInDynamoLibrary(true)]
public static Diaphragm Define(Autodesk.DesignScript.Geometry.Surface surface, string identifier = "D")
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousBar.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousBar.cs
index a4459a354..37cb3b27b 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousBar.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousBar.cs
@@ -9,7 +9,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FictitiousBar: EntityBase
+ public partial class FictitiousBar
{
#region dynamo
[IsVisibleInDynamoLibrary(true)]
@@ -30,7 +30,7 @@ public static FictitiousBar Define(Autodesk.DesignScript.Geometry.Curve curve, [
{
// convert geometry
Geometry.Edge edge = Geometry.Edge.FromDynamoLineOrArc2(curve);
- Geometry.FdVector3d y = Geometry.FdVector3d.FromDynamo(localY);
+ Geometry.Vector3d y = Geometry.Vector3d.FromDynamo(localY);
// get connectivity
Bars.Connectivity startConnectivity;
@@ -56,7 +56,7 @@ public static FictitiousBar Define(Autodesk.DesignScript.Geometry.Curve curve, [
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- bar.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ bar.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousShell.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousShell.cs
index 315db3548..050c2766d 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousShell.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/FictitiousShell.cs
@@ -8,7 +8,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class FictitiousShell: EntityBase
+ public partial class FictitiousShell
{
///
/// Set EdgeConnection by indices.
@@ -47,8 +47,8 @@ public static FictitiousShell Define(Autodesk.DesignScript.Geometry.Surface surf
{
// convert geometry
Geometry.Region region = Geometry.Region.FromDynamo(surface);
- Geometry.FdVector3d x = Geometry.FdVector3d.FromDynamo(localX);
- Geometry.FdVector3d z = Geometry.FdVector3d.FromDynamo(localZ);
+ Geometry.Vector3d x = Geometry.Vector3d.FromDynamo(localX);
+ Geometry.Vector3d z = Geometry.Vector3d.FromDynamo(localZ);
// add edge connections to region
region.SetEdgeConnections(edgeConnection);
@@ -59,13 +59,13 @@ public static FictitiousShell Define(Autodesk.DesignScript.Geometry.Surface surf
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ obj.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ obj.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
// return
diff --git a/FemDesign.Dynamo/Dynamo/ModellingTools/SurfaceConnection.cs b/FemDesign.Dynamo/Dynamo/ModellingTools/SurfaceConnection.cs
index 6e5d2bd2a..36142b122 100644
--- a/FemDesign.Dynamo/Dynamo/ModellingTools/SurfaceConnection.cs
+++ b/FemDesign.Dynamo/Dynamo/ModellingTools/SurfaceConnection.cs
@@ -8,7 +8,7 @@
namespace FemDesign.ModellingTools
{
[IsVisibleInDynamoLibrary(false)]
- public partial class SurfaceConnection: EntityBase
+ public partial class SurfaceConnection
{
}
diff --git a/FemDesign.Dynamo/Dynamo/Reinforcement/BarReinforcement.cs b/FemDesign.Dynamo/Dynamo/Reinforcement/BarReinforcement.cs
index d6f77fe05..2006d2bc4 100644
--- a/FemDesign.Dynamo/Dynamo/Reinforcement/BarReinforcement.cs
+++ b/FemDesign.Dynamo/Dynamo/Reinforcement/BarReinforcement.cs
@@ -46,7 +46,7 @@ public static Bars.Bar AddToBar(Bars.Bar bar, List
/// Deconstruct the Bar Displacement Results
///
@@ -37,8 +43,8 @@ public static Dictionary Deconstruct(List)result["CaseIdentifier"];
var elementId = (List)result["ElementId"];
var positionResult = (List)result["PositionResult"];
- var iTranslation = (List)result["Translation"];
- var iRotation = (List)result["Rotation"];
+ var iTranslation = (List)result["Translation"];
+ var iRotation = (List)result["Rotation"];
// Convert the FdVector to Dynamo
var oTranslation = iTranslation.Select(x => x.ToDynamo());
diff --git a/FemDesign.Dynamo/Dynamo/Results/BarInternalForce.cs b/FemDesign.Dynamo/Dynamo/Results/BarInternalForce.cs
index addcfa004..4bb4a33f0 100644
--- a/FemDesign.Dynamo/Dynamo/Results/BarInternalForce.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/BarInternalForce.cs
@@ -11,6 +11,13 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class BarInternalForce : IResult
{
+
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "BarInternalForce";
+ }
+
///
/// Create new model. Add entities to model. Nested lists are not supported, use flatten.
///
diff --git a/FemDesign.Dynamo/Dynamo/Results/BarStress.cs b/FemDesign.Dynamo/Dynamo/Results/BarStress.cs
index 651ed055d..7fa9f0f11 100644
--- a/FemDesign.Dynamo/Dynamo/Results/BarStress.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/BarStress.cs
@@ -11,6 +11,13 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class BarStress : IResult
{
+
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "BarStress";
+ }
+
///
/// Read Bar Stress from a previously run model.
///
diff --git a/FemDesign.Dynamo/Dynamo/Results/EigenFrequencies.cs b/FemDesign.Dynamo/Dynamo/Results/EigenFrequencies.cs
index 7a85adf98..9552b9856 100644
--- a/FemDesign.Dynamo/Dynamo/Results/EigenFrequencies.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/EigenFrequencies.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class EigenFrequencies : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "EigenFrequencies";
+ }
+
///
/// Read the EigenFrequencies for the entire model
///
diff --git a/FemDesign.Dynamo/Dynamo/Results/FeaNode.cs b/FemDesign.Dynamo/Dynamo/Results/FeaNode.cs
index c72e77b29..5615664ff 100644
--- a/FemDesign.Dynamo/Dynamo/Results/FeaNode.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/FeaNode.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class FeaNode : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "FeaNode";
+ }
+
///
/// Deconstruct the Fea Node Element
///
@@ -25,7 +31,7 @@ public static Dictionary Deconstruct(FDfea FdFeaModel)
var nodeId = (List)result["NodeId"];
- var feaNodePoint = (List)result["Position"];
+ var feaNodePoint = (List)result["Position"];
// Convert the FdPoint to Rhino
diff --git a/FemDesign.Dynamo/Dynamo/Results/LineSupportReaction.cs b/FemDesign.Dynamo/Dynamo/Results/LineSupportReaction.cs
index 7db9b0317..0765846b6 100644
--- a/FemDesign.Dynamo/Dynamo/Results/LineSupportReaction.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/LineSupportReaction.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class LineSupportReaction : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "LineSupportReaction";
+ }
+
///
///
///
@@ -37,8 +43,8 @@ public static Dictionary Deconstruct(List)result["Identifier"];
var elementId = (List)result["ElementId"];
var nodeId = (List)result["NodeId"];
- var iReactionForce = (List)result["ReactionForce"];
- var iReactionMoment = (List)result["ReactionMoment"];
+ var iReactionForce = (List)result["ReactionForce"];
+ var iReactionMoment = (List)result["ReactionMoment"];
var iForceResultant = (List)result["ForceResultant"];
var iMomentResultant = (List)result["MomentResultant"];
diff --git a/FemDesign.Dynamo/Dynamo/Results/NodalDisplacement.cs b/FemDesign.Dynamo/Dynamo/Results/NodalDisplacement.cs
index 6b181b357..8571e1ba4 100644
--- a/FemDesign.Dynamo/Dynamo/Results/NodalDisplacement.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/NodalDisplacement.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class NodalDisplacement : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "NodalDisplacement";
+ }
+
///
/// Create new model. Add entities to model. Nested lists are not supported, use flatten.
///
@@ -35,8 +41,8 @@ public static Dictionary Deconstruct(List)result["CaseIdentifier"];
var nodeId = (List)result["NodeId"];
- var iTranslation = (List)result["Translation"];
- var iRotation = (List)result["Rotation"];
+ var iTranslation = (List)result["Translation"];
+ var iRotation = (List)result["Rotation"];
// Convert the FdVector to Dynamo
diff --git a/FemDesign.Dynamo/Dynamo/Results/NodalVibration.cs b/FemDesign.Dynamo/Dynamo/Results/NodalVibration.cs
index 6cccfa939..52701ed38 100644
--- a/FemDesign.Dynamo/Dynamo/Results/NodalVibration.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/NodalVibration.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class NodalVibration : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "NodalVibration";
+ }
+
///
/// Read the Modal Shape vectors for the entire model
///
@@ -36,8 +42,8 @@ public static Dictionary Deconstruct(List)result["ShapeId"];
var identifier = (List)result["Id"];
var nodeId = (List)result["NodeId"];
- var iTranslation = (List)result["Translation"];
- var iRotation = (List)result["Rotation"];
+ var iTranslation = (List)result["Translation"];
+ var iRotation = (List)result["Rotation"];
// Convert the FdVector to Dynamo
var oTranslation = iTranslation.Select(x => x.ToDynamo());
diff --git a/FemDesign.Dynamo/Dynamo/Results/PointSupportReaction.cs b/FemDesign.Dynamo/Dynamo/Results/PointSupportReaction.cs
index 6a59db7dd..cd209a160 100644
--- a/FemDesign.Dynamo/Dynamo/Results/PointSupportReaction.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/PointSupportReaction.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class PointSupportReaction : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "PointSupportReaction";
+ }
+
///
///
///
@@ -35,9 +41,9 @@ public static Dictionary Deconstruct(List)result["CaseIdentifier"];
var identifier = (List)result["Identifier"];
var nodeId = (List)result["NodeId"];
- var iPos = (List)result["Position"];
- var iReactionForce = (List)result["ReactionForce"];
- var iReactionMoment = (List)result["ReactionMoment"];
+ var iPos = (List)result["Position"];
+ var iReactionForce = (List)result["ReactionForce"];
+ var iReactionMoment = (List)result["ReactionMoment"];
var iForceResultant = (List)result["ForceResultant"];
var iMomentResultant = (List)result["MomentResultant"];
diff --git a/FemDesign.Dynamo/Dynamo/Results/PointSupportReactionMinMax.cs b/FemDesign.Dynamo/Dynamo/Results/PointSupportReactionMinMax.cs
new file mode 100644
index 000000000..d045dd57b
--- /dev/null
+++ b/FemDesign.Dynamo/Dynamo/Results/PointSupportReactionMinMax.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+using Autodesk.DesignScript.Geometry;
+#endregion
+
+namespace FemDesign.Results
+{
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class PointSupportReactionMinMax : IResult
+ {
+
+
+ ///
+ ///
+ ///
+ /// Result to be Parse
+ /// Name of Load Case/Load Combination for which to return the results. Default value returns the results for the first load case
+ [IsVisibleInDynamoLibrary(true)]
+ [MultiReturn(new[] { "MinMax", "CaseIdentifier", "Identifier", "NodeId", "SupportPosition", "ReactionForce", "ReactionMoment", "ForceResultant", "MomentResultant" })]
+ public static Dictionary Deconstruct(List Result)
+ {
+
+ List minMax = new List();
+ List loadCases = new List();
+ List identifier = new List();
+ List nodeId = new List();
+ List pos = new List();
+ List reactionForce = new List();
+ List reactionMoment = new List();
+ List forceResultant = new List();
+ List momentResultant = new List();
+
+ foreach (var item in Result)
+ {
+ minMax.Add(item.Max);
+ loadCases.Add(item.CaseIdentifier);
+ identifier.Add(item.Id);
+ nodeId.Add(item.NodeId);
+ pos.Add(Autodesk.DesignScript.Geometry.Point.ByCoordinates(item.X, item.Y, item.Z));
+ reactionForce.Add(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(item.Fx, item.Fy, item.Fz));
+ reactionMoment.Add(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(item.Mx, item.My, item.Mz));
+ forceResultant.Add(item.Fr);
+ momentResultant.Add(item.Mr);
+ }
+
+ return new Dictionary
+ {
+ {"MinMax", minMax },
+ {"CaseIdentifier", loadCases},
+ {"Identifier", identifier},
+ {"NodeId", nodeId},
+ {"SupportPosition", pos},
+ {"ReactionForce", reactionForce},
+ {"ReactionMoment", reactionMoment},
+ {"ForceResultant", forceResultant},
+ {"MomentResultant", momentResultant}
+ };
+ }
+
+
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "PointSupportReactionMinMax";
+ }
+ }
+}
diff --git a/FemDesign.Dynamo/Dynamo/Results/ShellDisplacement.cs b/FemDesign.Dynamo/Dynamo/Results/ShellDisplacement.cs
index 6826c8a27..eb2cdff24 100644
--- a/FemDesign.Dynamo/Dynamo/Results/ShellDisplacement.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/ShellDisplacement.cs
@@ -12,6 +12,12 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class ShellDisplacement : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "ShellDisplacement";
+ }
+
///
/// Deconstruct the Shell Displacement Results
///
@@ -37,8 +43,8 @@ public static Dictionary Deconstruct(List)result["CaseIdentifier"];
var elementId = (List)result["ElementId"];
var nodeId = (List)result["NodeId"];
- var iTranslation = (List)result["Translation"];
- var iRotation = (List)result["Rotation"];
+ var iTranslation = (List)result["Translation"];
+ var iRotation = (List)result["Rotation"];
// Convert the FdVector to Dynamo
var oTranslation = iTranslation.Select(x => x.ToDynamo());
diff --git a/FemDesign.Dynamo/Dynamo/Results/ShellInternalForce.cs b/FemDesign.Dynamo/Dynamo/Results/ShellInternalForce.cs
index 668acdc4f..e48b79e1c 100644
--- a/FemDesign.Dynamo/Dynamo/Results/ShellInternalForce.cs
+++ b/FemDesign.Dynamo/Dynamo/Results/ShellInternalForce.cs
@@ -14,6 +14,13 @@ namespace FemDesign.Results
[IsVisibleInDynamoLibrary(false)]
public partial class ShellInternalForce : IResult
{
+ [IsVisibleInDynamoLibrary(true)]
+ public static string ResultType()
+ {
+ return "ShellInternalForce";
+ }
+
+
///
/// Deconstruct the Shell Internal Force Results
///
diff --git a/FemDesign.Dynamo/Dynamo/Shells/EdgeConnection.cs b/FemDesign.Dynamo/Dynamo/Shells/EdgeConnection.cs
index b3aa19d5c..1061ba982 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/EdgeConnection.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/EdgeConnection.cs
@@ -11,13 +11,6 @@ namespace FemDesign.Shells
[IsVisibleInDynamoLibrary(false)]
public partial class EdgeConnection: EdgeConnectionBase
{
- ///
- /// Create a default (rigid) EdgeConnection.
- ///
- ///
- [IsVisibleInDynamoLibrary(false)]
- public static EdgeConnection Default() => GetDefault();
-
///
/// Define a new EdgeConnection
///
@@ -37,9 +30,9 @@ public static EdgeConnection Define(Releases.Motions motions, Releases.Rotations
/// Create
///
[IsVisibleInDynamoLibrary(true)]
- public static EdgeConnection Hinged()
+ public static EdgeConnection GetHinged()
{
- return EdgeConnection.GetHinged();
+ return EdgeConnection.Hinged;
}
///
@@ -48,9 +41,9 @@ public static EdgeConnection Hinged()
/// Create
///
[IsVisibleInDynamoLibrary(true)]
- public static EdgeConnection Rigid()
+ public static EdgeConnection GetRigid()
{
- return EdgeConnection.GetRigid();
+ return EdgeConnection.Rigid;
}
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Shells/Panel.cs b/FemDesign.Dynamo/Dynamo/Shells/Panel.cs
index 0eda6a02c..b13e2006f 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/Panel.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/Panel.cs
@@ -10,7 +10,7 @@
namespace FemDesign.Shells
{
[IsVisibleInDynamoLibrary(false)]
- public partial class Panel: EntityBase
+ public partial class Panel
{
#region dynamo
@@ -40,13 +40,13 @@ public static Panel ProfiledPlate(Autodesk.DesignScript.Geometry.Surface surface
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ obj.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ obj.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
// set mesh
diff --git a/FemDesign.Dynamo/Dynamo/Shells/ShellEccentricity.cs b/FemDesign.Dynamo/Dynamo/Shells/ShellEccentricity.cs
index 1539096c6..a97fa5195 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/ShellEccentricity.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/ShellEccentricity.cs
@@ -20,13 +20,5 @@ public static ShellEccentricity Create(VerticalAlignment alignment, double eccen
{
return new ShellEccentricity(alignment, eccentricity, eccentricityCalculation, eccentricityByCracking);
}
-
- ///
- /// Create a default ShellEccentricity.
- ///
- /// Create
- ///
- [IsVisibleInDynamoLibrary(false)]
- public static ShellEccentricity Default() => GetDefault();
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Shells/ShellOrthotropy.cs b/FemDesign.Dynamo/Dynamo/Shells/ShellOrthotropy.cs
index d4d433abb..ef889b97d 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/ShellOrthotropy.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/ShellOrthotropy.cs
@@ -20,13 +20,5 @@ public static ShellOrthotropy Create(double orthoAlfa = 0, double orthoRatio = 1
{
return new ShellOrthotropy(orthoAlfa, orthoRatio);
}
-
- ///
- /// Create a default definition for ShellOrthotropy.
- ///
- /// Create
- ///
- [IsVisibleInDynamoLibrary(false)]
- public static ShellOrthotropy Default() => GetDefault();
}
}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Shells/Slab.cs b/FemDesign.Dynamo/Dynamo/Shells/Slab.cs
index d47140e8f..33cf8e228 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/Slab.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/Slab.cs
@@ -9,7 +9,7 @@
namespace FemDesign.Shells
{
[IsVisibleInDynamoLibrary(false)]
- public partial class Slab: EntityBase
+ public partial class Slab
{
#region dynamo
@@ -66,13 +66,13 @@ public static Slab Plate(Autodesk.DesignScript.Geometry.Surface surface, double
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ slab.SlabPart.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ slab.SlabPart.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
return slab;
@@ -109,13 +109,13 @@ public static Slab PlateVariableThickness(Autodesk.DesignScript.Geometry.Surface
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ slab.SlabPart.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ slab.SlabPart.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
return slab;
@@ -156,13 +156,13 @@ public static Slab Wall(Autodesk.DesignScript.Geometry.Surface surface, double t
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ slab.SlabPart.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ slab.SlabPart.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
return slab;
@@ -205,13 +205,13 @@ public static Slab WallVariableThickness(Autodesk.DesignScript.Geometry.Surface
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalX = FemDesign.Geometry.FdVector3d.FromDynamo(localX);
+ slab.SlabPart.LocalX = FemDesign.Geometry.Vector3d.FromDynamo(localX);
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- slab.SlabPart.LocalZ = FemDesign.Geometry.FdVector3d.FromDynamo(localZ);
+ slab.SlabPart.LocalZ = FemDesign.Geometry.Vector3d.FromDynamo(localZ);
}
return slab;
@@ -230,8 +230,8 @@ public Slab SetLocalAxes(Autodesk.DesignScript.Geometry.Vector localX, Autodesk.
Slab slab = this.DeepClone();
// set local x and local z
- slab.SlabPart.LocalX = Geometry.FdVector3d.FromDynamo(localX);
- slab.SlabPart.LocalZ = Geometry.FdVector3d.FromDynamo(localZ);
+ slab.SlabPart.LocalX = Geometry.Vector3d.FromDynamo(localX);
+ slab.SlabPart.LocalZ = Geometry.Vector3d.FromDynamo(localZ);
//
return slab;
diff --git a/FemDesign.Dynamo/Dynamo/Shells/SlabPart.cs b/FemDesign.Dynamo/Dynamo/Shells/SlabPart.cs
index 159c8bbf9..0813fa5c5 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/SlabPart.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/SlabPart.cs
@@ -10,7 +10,7 @@
namespace FemDesign.Shells
{
[IsVisibleInDynamoLibrary(false)]
- public partial class SlabPart: EntityBase
+ public partial class SlabPart
{
#region dynamo
diff --git a/FemDesign.Dynamo/Dynamo/Shells/Thickness.cs b/FemDesign.Dynamo/Dynamo/Shells/Thickness.cs
index c1fba3be2..21bc1088e 100644
--- a/FemDesign.Dynamo/Dynamo/Shells/Thickness.cs
+++ b/FemDesign.Dynamo/Dynamo/Shells/Thickness.cs
@@ -19,7 +19,7 @@ public partial class Thickness: LocationValue
[IsVisibleInDynamoLibrary(true)]
public static Thickness Define(Autodesk.DesignScript.Geometry.Point point, double val)
{
- return new Thickness(Geometry.FdPoint3d.FromDynamo(point), val);
+ return new Thickness(Geometry.Point3d.FromDynamo(point), val);
}
#endregion
diff --git a/FemDesign.Dynamo/Dynamo/Stage/ActivatedLoadCase.cs b/FemDesign.Dynamo/Dynamo/Stage/ActivatedLoadCase.cs
new file mode 100644
index 000000000..eb8871802
--- /dev/null
+++ b/FemDesign.Dynamo/Dynamo/Stage/ActivatedLoadCase.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Xml.Serialization;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using FemDesign.GenericClasses;
+
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+#endregion
+
+namespace FemDesign
+{
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class ActivatedLoadCase
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Stage/ConstructionStages.cs b/FemDesign.Dynamo/Dynamo/Stage/ConstructionStages.cs
new file mode 100644
index 000000000..9157dabc8
--- /dev/null
+++ b/FemDesign.Dynamo/Dynamo/Stage/ConstructionStages.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Xml.Serialization;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using FemDesign.GenericClasses;
+
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+#endregion
+
+namespace FemDesign
+{
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class ConstructionStages
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/Stage/Stage.cs b/FemDesign.Dynamo/Dynamo/Stage/Stage.cs
new file mode 100644
index 000000000..dcb3b81f8
--- /dev/null
+++ b/FemDesign.Dynamo/Dynamo/Stage/Stage.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Xml.Serialization;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using FemDesign.GenericClasses;
+
+#region dynamo
+using Autodesk.DesignScript.Runtime;
+#endregion
+
+namespace FemDesign
+{
+ [IsVisibleInDynamoLibrary(false)]
+ public partial class Stage
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Dynamo/Dynamo/StructureGrid/Axis.cs b/FemDesign.Dynamo/Dynamo/StructureGrid/Axis.cs
index 78cfe4467..b65246bf7 100644
--- a/FemDesign.Dynamo/Dynamo/StructureGrid/Axis.cs
+++ b/FemDesign.Dynamo/Dynamo/StructureGrid/Axis.cs
@@ -22,8 +22,8 @@ public partial class Axis: EntityBase
public static Axis Define(Autodesk.DesignScript.Geometry.Line line, [DefaultArgument("")] string prefix, int id, [DefaultArgument("false")] bool idIsLetter)
{
// convert geometry
- Geometry.FdPoint3d p0 = Geometry.FdPoint3d.FromDynamo(line.StartPoint);
- Geometry.FdPoint3d p1 = Geometry.FdPoint3d.FromDynamo(line.EndPoint);
+ Geometry.Point3d p0 = Geometry.Point3d.FromDynamo(line.StartPoint);
+ Geometry.Point3d p1 = Geometry.Point3d.FromDynamo(line.EndPoint);
//
return new Axis(p0, p1, prefix, id, idIsLetter);
diff --git a/FemDesign.Dynamo/Dynamo/StructureGrid/Storey.cs b/FemDesign.Dynamo/Dynamo/StructureGrid/Storey.cs
index 8bae6b0b0..03bad591a 100644
--- a/FemDesign.Dynamo/Dynamo/StructureGrid/Storey.cs
+++ b/FemDesign.Dynamo/Dynamo/StructureGrid/Storey.cs
@@ -24,8 +24,8 @@ public partial class Storey: EntityBase
public static Storey Define(string name, Autodesk.DesignScript.Geometry.Point origo, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.XAxis()")] Autodesk.DesignScript.Geometry.Vector direction, double dimensionX = 50, double dimensionY = 30)
{
// convert geometry
- Geometry.FdPoint3d p = Geometry.FdPoint3d.FromDynamo(origo);
- Geometry.FdVector3d v = Geometry.FdVector3d.FromDynamo(direction);
+ Geometry.Point3d p = Geometry.Point3d.FromDynamo(origo);
+ Geometry.Vector3d v = Geometry.Vector3d.FromDynamo(direction);
// return
return new Storey(p, v, dimensionX, dimensionY, name);
diff --git a/FemDesign.Dynamo/Dynamo/Supports/LineSupport.cs b/FemDesign.Dynamo/Dynamo/Supports/LineSupport.cs
index 3c6125c96..0860b153d 100644
--- a/FemDesign.Dynamo/Dynamo/Supports/LineSupport.cs
+++ b/FemDesign.Dynamo/Dynamo/Supports/LineSupport.cs
@@ -7,7 +7,7 @@
namespace FemDesign.Supports
{
[IsVisibleInDynamoLibrary(false)]
- public partial class LineSupport: EntityBase
+ public partial class LineSupport: NamedEntityBase
{
///
/// Create a rigid line support element.
@@ -28,7 +28,7 @@ public static LineSupport Rigid(Autodesk.DesignScript.Geometry.Curve curve, [Def
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.Group.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ obj.Group.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -62,7 +62,7 @@ public static LineSupport Hinged(Autodesk.DesignScript.Geometry.Curve curve, [De
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.Group.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ obj.Group.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
@@ -98,7 +98,7 @@ public static LineSupport Define(Autodesk.DesignScript.Geometry.Curve curve, Mot
// set local y-axis
if (!localY.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.Group.LocalY = FemDesign.Geometry.FdVector3d.FromDynamo(localY);
+ obj.Group.LocalY = FemDesign.Geometry.Vector3d.FromDynamo(localY);
}
// else orient coordinate system to GCS
diff --git a/FemDesign.Dynamo/Dynamo/Supports/PointSupport.cs b/FemDesign.Dynamo/Dynamo/Supports/PointSupport.cs
index ebbe04e20..4d4a7c99e 100644
--- a/FemDesign.Dynamo/Dynamo/Supports/PointSupport.cs
+++ b/FemDesign.Dynamo/Dynamo/Supports/PointSupport.cs
@@ -7,7 +7,7 @@
namespace FemDesign.Supports
{
[IsVisibleInDynamoLibrary(false)]
- public partial class PointSupport: EntityBase
+ public partial class PointSupport: NamedEntityBase
{
///
/// Create a rigid point support element.
@@ -19,7 +19,7 @@ public partial class PointSupport: EntityBase
[IsVisibleInDynamoLibrary(true)]
public static PointSupport Rigid(Autodesk.DesignScript.Geometry.Point point, [DefaultArgument("S")] string identifier)
{
- return PointSupport.Rigid(Geometry.FdPoint3d.FromDynamo(point), identifier);
+ return PointSupport.Rigid(Geometry.Point3d.FromDynamo(point), identifier);
}
///
@@ -32,7 +32,7 @@ public static PointSupport Rigid(Autodesk.DesignScript.Geometry.Point point, [De
[IsVisibleInDynamoLibrary(true)]
public static PointSupport Hinged(Autodesk.DesignScript.Geometry.Point point, [DefaultArgument("S")] string identifier)
{
- return PointSupport.Hinged(Geometry.FdPoint3d.FromDynamo(point), identifier);
+ return PointSupport.Hinged(Geometry.Point3d.FromDynamo(point), identifier);
}
///
@@ -49,7 +49,7 @@ public static PointSupport Hinged(Autodesk.DesignScript.Geometry.Point point, [D
[IsVisibleInDynamoLibrary(true)]
public static PointSupport Define(Autodesk.DesignScript.Geometry.Point point, Motions motions, [DefaultArgument("MotionsPlasticLimits.Default()")] MotionsPlasticLimits motionsPlasticLimits, Rotations rotations, [DefaultArgument("RotationsPlasticLimits.Default()")] RotationsPlasticLimits rotationsPlasticLimits, [DefaultArgument("S")] string identifier)
{
- return new PointSupport(Geometry.FdPoint3d.FromDynamo(point), motions, motionsPlasticLimits, rotations, rotationsPlasticLimits, identifier);
+ return new PointSupport(Geometry.Point3d.FromDynamo(point), motions, motionsPlasticLimits, rotations, rotationsPlasticLimits, identifier);
}
internal Autodesk.DesignScript.Geometry.Point GetDynamoGeometry()
diff --git a/FemDesign.Dynamo/Dynamo/Supports/SurfaceSupport.cs b/FemDesign.Dynamo/Dynamo/Supports/SurfaceSupport.cs
index 8539675eb..63186461b 100644
--- a/FemDesign.Dynamo/Dynamo/Supports/SurfaceSupport.cs
+++ b/FemDesign.Dynamo/Dynamo/Supports/SurfaceSupport.cs
@@ -7,7 +7,7 @@
namespace FemDesign.Supports
{
[IsVisibleInDynamoLibrary(false)]
- public partial class SurfaceSupport: EntityBase
+ public partial class SurfaceSupport: NamedEntityBase
{
///
/// Create a SurfaceSupport element.
@@ -29,13 +29,13 @@ public static SurfaceSupport SurfaceSupportDefine(Autodesk.DesignScript.Geometry
// set local x-axis
if (!localX.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.CoordinateSystem.SetXAroundZ(FemDesign.Geometry.FdVector3d.FromDynamo(localX));
+ obj.CoordinateSystem.SetXAroundZ(FemDesign.Geometry.Vector3d.FromDynamo(localX));
}
// set local z-axis
if (!localZ.Equals(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0,0,0)))
{
- obj.CoordinateSystem.SetZAroundX(FemDesign.Geometry.FdVector3d.FromDynamo(localZ));
+ obj.CoordinateSystem.SetZAroundX(FemDesign.Geometry.Vector3d.FromDynamo(localZ));
}
return obj;
diff --git a/FemDesign.Dynamo/FemDesign.Dynamo.csproj b/FemDesign.Dynamo/FemDesign.Dynamo.csproj
index ebdd4d133..2d6b0ed0e 100644
--- a/FemDesign.Dynamo/FemDesign.Dynamo.csproj
+++ b/FemDesign.Dynamo/FemDesign.Dynamo.csproj
@@ -83,6 +83,9 @@
Core\Bars\BarPart.cs
+
+ Core\Bars\BarStiffnessFactors.cs
+
Core\Bars\Beam.cs
@@ -128,6 +131,9 @@
Core\Calculate\Bsc.cs
+
+ Core\Calculate\CmdApplyDesignChanges.cs
+
Core\Calculate\CmdCalculation.cs
@@ -161,9 +167,6 @@
Core\Calculate\CombItem.cs
-
- Core\Calculate\ConstructionStage.cs
-
Core\Calculate\Design.cs
@@ -194,6 +197,9 @@
Core\Calculate\Options.cs
+
+ Core\Calculate\Stage.cs
+
Core\GenericClasses\Camber.cs
@@ -224,6 +230,9 @@
Core\GenericClasses\ILoadElement.cs
+
+ Core\GenericClasses\INamedEntity.cs
+
Core\GenericClasses\IStageElement.cs
@@ -239,6 +248,9 @@
Core\GenericClasses\LocationValue.cs
+
+ Core\GenericClasses\NamedEntityBase.cs
+
Core\GenericClasses\RestrictedDouble.cs
@@ -254,12 +266,21 @@
Core\GenericClasses\StartEndType.cs
+
+ Core\GenericClasses\TextFormatting.cs
+
Core\GenericClasses\Tolerance.cs
Core\GenericClasses\VerticalAlignmentEnum.cs
+
+ Core\Geometry\ArcEdge.cs
+
+
+ Core\Geometry\CircleEdge.cs
+
Core\Geometry\Contour.cs
@@ -272,20 +293,26 @@
Core\Geometry\Face.cs
-
- Core\Geometry\FdCoordinateSystem.cs
+
+ Core\Geometry\CoordinateSystem.cs
+
+
+ Core\Geometry\LineEdge.cs
-
- Core\Geometry\FdPoint2d.cs
+
+ Core\Geometry\Point2d.cs
-
- Core\Geometry\FdPoint3d.cs
+
+ Core\Geometry\Point3d.cs
-
- Core\Geometry\FdVector2d.cs
+
+ Core\Geometry\Proximity.cs
-
- Core\Geometry\FdVector3d.cs
+
+ Core\Geometry\Vector2d.cs
+
+
+ Core\Geometry\Vector3d.cs
Core\Geometry\LineSegment.cs
@@ -344,6 +371,9 @@
Core\Loads\LoadCombination.cs
+
+ Core\Loads\LoadCombinationCaseBase.cs
+
Core\Loads\LoadCombTypeEnum.cs
@@ -392,6 +422,9 @@
Core\Loads\PressureLoad.cs
+
+ Core\Loads\StageLoadCase.cs
+
Core\Loads\SurfaceLoad.cs
@@ -596,6 +629,9 @@
Core\Releases\RigidityDataLibType3.cs
+
+ Core\Releases\RigidityDataType0.cs
+
Core\Releases\RigidityDataType1.cs
@@ -686,6 +722,9 @@
Core\Results\PointSupportReaction.cs
+
+ Core\Results\PointSupportReactionMinMax.cs
+
Core\Results\QuantityEstimation.cs
@@ -695,9 +734,6 @@
Core\Results\ResultsReader.cs
-
- Core\Results\ResultTypeEnum.cs
-
Core\Results\ShellDerivedForce.cs
@@ -761,6 +797,9 @@
Core\Shells\SlabPart.cs
+
+ Core\Shells\SlabStiffnessFactors.cs
+
Core\Shells\SlabTypeEnum.cs
@@ -770,15 +809,6 @@
Core\Shells\WallCorbel.cs
-
- Core\AdvancedFem\ActivatedLoadCase.cs
-
-
- Core\AdvancedFem\ConstructionStages.cs
-
-
- Core\AdvancedFem\Stage.cs
-
Core\StructureGrid\Axes.cs
@@ -812,9 +842,21 @@
Core\Supports\PointSupport.cs
+
+ Core\Supports\StiffnessPoints.cs
+
Core\Supports\Supports.cs
+
+ Core\Stage\Stage.cs
+
+
+ Core\Stage\ConstructionStages.cs
+
+
+ Core\Stage\ActivatedLoadCase.cs
+
Core\Supports\SurfaceSupport.cs
@@ -865,17 +907,18 @@
+
-
-
-
-
-
+
+
+
+
+
@@ -983,6 +1026,7 @@
+
@@ -1007,6 +1051,8 @@
+
+
@@ -1017,6 +1063,7 @@
+
True
diff --git a/FemDesign.Examples/C#/Example 1 - Creating a simple beam/Program.cs b/FemDesign.Examples/C#/Example 1 - Creating a simple beam/Program.cs
index 9c5b3c7d4..3efa994a6 100644
--- a/FemDesign.Examples/C#/Example 1 - Creating a simple beam/Program.cs
+++ b/FemDesign.Examples/C#/Example 1 - Creating a simple beam/Program.cs
@@ -50,7 +50,8 @@ static void Main()
// Create load cases
var deadload = new Loads.LoadCase("Deadload", Loads.LoadCaseType.DeadLoad, Loads.LoadCaseDuration.Permanent);
var liveload = new Loads.LoadCase("Liveload", Loads.LoadCaseType.Static, Loads.LoadCaseDuration.Permanent);
- var loadcases = new List() { deadload, liveload };
+ var stressload = new Loads.LoadCase("Stresses", Loads.LoadCaseType.Static, Loads.LoadCaseDuration.Permanent);
+ var loadcases = new List() { deadload, liveload, stressload };
// Create load combinations
@@ -71,10 +72,13 @@ static void Main()
var lineLoadEnd = new Geometry.Vector3d(0.0, 0.0, -4.0);
var lineLoad = Loads.LineLoad.VariableForce(edge, lineLoadStart, lineLoadEnd, liveload);
+ var lineStress = new Loads.LineStressLoad(edge, 10, stressload);
+
var loads = new List() {
pointForce,
pointMoment,
- lineLoad
+ lineLoad,
+ lineStress
};
diff --git a/FemDesign.Examples/C#/Example 3 - Analyse a beam/Program.cs b/FemDesign.Examples/C#/Example 3 - Analyse a beam/Program.cs
index fa1a4edba..f9b9091e4 100644
--- a/FemDesign.Examples/C#/Example 3 - Analyse a beam/Program.cs
+++ b/FemDesign.Examples/C#/Example 3 - Analyse a beam/Program.cs
@@ -123,11 +123,6 @@ static void Main()
// Run a specific analysis
model.RunAnalysis(analysisType, resultTypes: results, cmdGlobalCfg: config, endSession: true);
-
-
-
- // TO DO
- //model.ReadResult(ResultType);
}
}
-}
+}
\ No newline at end of file
diff --git a/FemDesign.Examples/C#/Example10 - ConstructionStages/Program.cs b/FemDesign.Examples/C#/Example10 - ConstructionStages/Program.cs
index 80a40fb91..92cface1f 100644
--- a/FemDesign.Examples/C#/Example10 - ConstructionStages/Program.cs
+++ b/FemDesign.Examples/C#/Example10 - ConstructionStages/Program.cs
@@ -90,13 +90,6 @@ static void Main(string[] args)
var imposedCase = new Loads.LoadCase("IMPOSED", Loads.LoadCaseType.Static, Loads.LoadCaseDuration.Permanent);
var loadcases = new List() { deadLoadCase, windCase, imposedCase };
- // Create load combinations
- var slsFactors = new List() { 1.0, 1.0, 1.0 };
- var SLS = new Loads.LoadCombination("SLS", Loads.LoadCombType.ServiceabilityCharacteristic, loadcases, slsFactors);
- var ulsFactors = new List() { 1.35, 1.5, 1.2 };
- var ULS = new Loads.LoadCombination("ULS", Loads.LoadCombType.UltimateOrdinary, loadcases, ulsFactors);
- var loadCombinations = new List() { SLS, ULS };
-
// Create loads
var pointMoment = new Loads.PointLoad(p2, new Geometry.Vector3d(0.0, 5.0, 0.0), deadLoadCase, null, Loads.ForceLoadType.Moment);
@@ -123,12 +116,22 @@ static void Main(string[] args)
// Create the stages
var stage1 = new Stage(1, "STAGE_1", stageOneLoadCases, elementsStageOne);
var stage2 = new Stage(2, "STAGE_2", stageTwoLoadCases, elementsStageTwo);
- var stage3 = new Stage(3, "STAGE_3", null, elementsStageThree);
- var stage4 = new Stage(4, "STAGE_4", null, null);
- var stage5 = new Stage(5, "STAGE_5", null, null);
+ var stage3 = new Stage(3, "STAGE_3", elements: elementsStageThree);
+ var stage4 = new Stage(4, "STAGE_4");
+ var stage5 = new Stage(5, "STAGE_5");
var stages = new List() { stage1, stage2, stage3, stage4, stage5 };
+
+ // Create load combinations
+ var slsFactors = new List() { 1.0, 1.0, 1.0 };
+ var SLS = new Loads.LoadCombination("SLS", Loads.LoadCombType.ServiceabilityCharacteristic, loadcases, slsFactors);
+ var ulsFactors = new List() { 1.35, 1.5, 1.2 };
+ var ULS = new Loads.LoadCombination("ULS", Loads.LoadCombType.UltimateOrdinary, loadcases, ulsFactors);
+ var CSCombination = new Loads.LoadCombination("Stage combination", Loads.LoadCombType.UltimateOrdinary, loadcases, ulsFactors);
+ CSCombination.SetStageLoadCase(stage1, 1.0);
+ var loadCombinations = new List() { SLS, ULS, CSCombination };
+
// Create the model
Model model = new Model(Country.S);
model.AddElements(elements);
diff --git a/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/CreateStiffnessPoints.sln b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/CreateStiffnessPoints.sln
new file mode 100644
index 000000000..6ecc539cf
--- /dev/null
+++ b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/CreateStiffnessPoints.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32421.90
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateStiffnessPoints", "CreateStiffnessPoints.csproj", "{BE21154D-59B3-40F1-A567-14312741EFD5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BE21154D-59B3-40F1-A567-14312741EFD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE21154D-59B3-40F1-A567-14312741EFD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE21154D-59B3-40F1-A567-14312741EFD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE21154D-59B3-40F1-A567-14312741EFD5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {46A8FE65-03A3-490A-9D1A-E2503F24BD9B}
+ EndGlobalSection
+EndGlobal
diff --git a/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Parse.cs b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Parse.cs
new file mode 100644
index 000000000..8db84c234
--- /dev/null
+++ b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Parse.cs
@@ -0,0 +1,30 @@
+using Newtonsoft.Json;
+
+namespace FemDesign.Examples
+{
+ public class DataParser
+ {
+ public static string ConvertCsvFileToJsonObject(string path)
+ {
+ var csv = new List();
+ var lines = File.ReadAllLines(path);
+
+ foreach (string line in lines)
+ csv.Add(line.Split(','));
+
+ var properties = lines[0].Split(',');
+
+ var listObjResult = new List>();
+
+ for (int i = 1; i < lines.Length; i++)
+ {
+ var objResult = new Dictionary();
+ for (int j = 0; j < properties.Length; j++)
+ objResult.Add(properties[j], csv[i][j]);
+
+ listObjResult.Add(objResult);
+ }
+ return JsonConvert.SerializeObject(listObjResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/PointLocation.txt b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/PointLocation.txt
new file mode 100644
index 000000000..a80667373
--- /dev/null
+++ b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/PointLocation.txt
@@ -0,0 +1,6 @@
+X,Y,Z
+1,1,0
+3,1,0
+3,3,0
+1,3,0
+2,2,0
\ No newline at end of file
diff --git a/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Practical example - Stiffness Point from CSV.csproj b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Practical example - Stiffness Point from CSV.csproj
new file mode 100644
index 000000000..d471b5bbf
--- /dev/null
+++ b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Practical example - Stiffness Point from CSV.csproj
@@ -0,0 +1,24 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Program.cs b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Program.cs
new file mode 100644
index 000000000..401e06422
--- /dev/null
+++ b/FemDesign.Examples/C#/Practical example - Create Stiffness Point from a CSV/Program.cs
@@ -0,0 +1,38 @@
+using FemDesign.Examples;
+using FemDesign;
+using Newtonsoft.Json;
+
+// Convert the csv file data to a Point3d object
+var jsonObject = DataParser.ConvertCsvFileToJsonObject("PointLocation.txt");
+var points = JsonConvert.DeserializeObject(jsonObject);
+if (points is null || points.Length < 1)
+ throw new Exception("Empty json file.");
+
+// Empty List to contain all the Structural Elements
+var struElements = new List();
+
+// Define Stiffness
+var motionsSurface = new FemDesign.Releases.Motions(10000, 10000, 10000, 10000, 10000, 10000);
+var motionsPoint = new FemDesign.Releases.Motions(10, 10, 10, 10, 10, 10);
+
+
+// Define Geometry
+var region = FemDesign.Geometry.Region.RectangleXY(FemDesign.Geometry.Point3d.Origin, 4, 4);
+
+// Create a Surface Support
+var surfaceSupport = new FemDesign.Supports.SurfaceSupport(region, motionsSurface, null);
+struElements.Add(surfaceSupport);
+
+
+// Create the stiffness points
+foreach (var point in points)
+{
+ var stiffPoints = new FemDesign.Supports.StiffnessPoint(surfaceSupport, point, motionsPoint);
+ struElements.Add(stiffPoints);
+}
+
+// Create Model
+var model = new FemDesign.Model(FemDesign.Country.S);
+model.AddElements(struElements);
+
+model.Open();
\ No newline at end of file
diff --git a/FemDesign.Examples/Grasshopper/Example 5 - Using custom sections.gh b/FemDesign.Examples/Grasshopper/Example 5 - Using custom sections.gh
index e18b394df..d2cfaa81c 100644
Binary files a/FemDesign.Examples/Grasshopper/Example 5 - Using custom sections.gh and b/FemDesign.Examples/Grasshopper/Example 5 - Using custom sections.gh differ
diff --git a/FemDesign.Examples/Grasshopper/Example 5 - my example section.struxml b/FemDesign.Examples/Grasshopper/Example 5 - my example section.struxml
index 02d1e9b65..2db17c540 100644
--- a/FemDesign.Examples/Grasshopper/Example 5 - my example section.struxml
+++ b/FemDesign.Examples/Grasshopper/Example 5 - my example section.struxml
@@ -1,90427 +1,93 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
diff --git a/FemDesign.Grasshopper/Bars/BarsBeam.cs b/FemDesign.Grasshopper/Bars/BarsBeam.cs
index b2f30d91c..4d146fd73 100644
--- a/FemDesign.Grasshopper/Bars/BarsBeam.cs
+++ b/FemDesign.Grasshopper/Bars/BarsBeam.cs
@@ -19,9 +19,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddCurveParameter("Curve", "Curve", "LineCurve or ArcCurve", GH_ParamAccess.item);
pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
- pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Section", "Section", "Section. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end.", GH_ParamAccess.list);
- pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Connectivity", "Connectivity", "Connectivity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Eccentricity", "Eccentricity", "Eccentricity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
@@ -44,17 +42,10 @@ protected override void SolveInstance(IGH_DataAccess DA)
if (!DA.GetData(0, ref curve)) { return; }
FemDesign.Materials.Material material = null;
- if (!DA.GetData(1, ref material))
- {
- material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
- }
+ if (!DA.GetData(1, ref material)) { return; }
List sections = new List();
- if (!DA.GetDataList(2, sections))
- {
- sections = new List();
- sections.Add(FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600"));
- }
+ if (!DA.GetDataList(2, sections)) { return; }
List connectivities = new List();
if (!DA.GetDataList(3, connectivities))
@@ -122,7 +113,7 @@ protected override System.Drawing.Bitmap Icon
}
public override Guid ComponentGuid
{
- get { return new Guid("135b6331-bf19-4d89-9e81-9e5e0d137f67"); }
+ get { return new Guid("{ED5BB11A-1A9A-438E-9BD3-A2283DB9C025}"); }
}
public override GH_Exposure Exposure => GH_Exposure.primary;
diff --git a/FemDesign.Grasshopper/Bars/BarsColumn.cs b/FemDesign.Grasshopper/Bars/BarsColumn.cs
index 32ddb83ff..db54697b4 100644
--- a/FemDesign.Grasshopper/Bars/BarsColumn.cs
+++ b/FemDesign.Grasshopper/Bars/BarsColumn.cs
@@ -7,63 +7,54 @@
namespace FemDesign.Grasshopper
{
- public class BarsColumn: GH_Component
+ public class BarsColumn : GH_Component
{
- public BarsColumn(): base("Bars.Column", "Column", "Create a bar element of type column.", CategoryName.Name(),
- SubCategoryName.Cat2a())
+ public BarsColumn() : base("Bars.Column", "Column", "Create a bar element of type column.", CategoryName.Name(),
+ SubCategoryName.Cat2a())
{
- }
- protected override void RegisterInputParams(GH_InputParamManager pManager)
- {
- pManager.AddCurveParameter("Line", "Line", "Line. Local x of line must equal positive global Z.", GH_ParamAccess.item);
- pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
- pManager[pManager.ParamCount - 1].Optional = true;
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddCurveParameter("Line", "Line", "Line. Local x of line must equal positive global Z.", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
pManager.AddGenericParameter("Section", "Section", "Section. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end.", GH_ParamAccess.list);
- pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Connectivity", "Connectivity", "Connectivity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
- pManager[pManager.ParamCount - 1].Optional = true;
- pManager.AddGenericParameter("Eccentricity", "Eccentricity", "Eccentricity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
- pManager[pManager.ParamCount - 1].Optional = true;
- pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
- pManager[pManager.ParamCount - 1].Optional = true;
- pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
- pManager.AddTextParameter("Identifier", "Identifier", "Identifier. Optional, default value if undefined.", GH_ParamAccess.item, "C");
- pManager[pManager.ParamCount - 1].Optional = true;
- }
- protected override void RegisterOutputParams(GH_OutputParamManager pManager)
- {
- pManager.AddGenericParameter("Bar", "Bar", "Bar.", GH_ParamAccess.item);
- }
- protected override void SolveInstance(IGH_DataAccess DA)
- {
- // get input
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Eccentricity", "Eccentricity", "Eccentricity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
+ pManager.AddTextParameter("Identifier", "Identifier", "Identifier. Optional, default value if undefined.", GH_ParamAccess.item, "C");
+ pManager[pManager.ParamCount - 1].Optional = true;
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddGenericParameter("Bar", "Bar", "Bar.", GH_ParamAccess.item);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ // get input
Curve curve = null;
if (!DA.GetData(0, ref curve)) { return; }
FemDesign.Materials.Material material = null;
- if (!DA.GetData(1, ref material))
- {
- material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
- }
+ if (!DA.GetData(1, ref material)) { return; }
List sections = new List();
- if (!DA.GetDataList(2, sections))
- {
- sections = new List();
- sections.Add(FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600"));
- }
+ if (!DA.GetDataList(2, sections)) { return; }
List connectivities = new List();
if (!DA.GetDataList(3, connectivities))
{
- connectivities = new List{FemDesign.Bars.Connectivity.Rigid};
+ connectivities = new List { FemDesign.Bars.Connectivity.Rigid };
}
List eccentricities = new List();
if (!DA.GetDataList(4, eccentricities))
{
- eccentricities = new List{FemDesign.Bars.Eccentricity.Default};
+ eccentricities = new List { FemDesign.Bars.Eccentricity.Default };
}
Vector3d v = Vector3d.Zero;
@@ -92,9 +83,9 @@ protected override void SolveInstance(IGH_DataAccess DA)
FemDesign.Geometry.Edge edge = Convert.FromRhinoLineCurve((LineCurve)curve);
// create bar
- var type = FemDesign.Bars.BarType.Column;
+ var type = FemDesign.Bars.BarType.Column;
FemDesign.Bars.Bar bar = new FemDesign.Bars.Bar(edge, type, material, sections.ToArray(), eccentricities.ToArray(), connectivities.ToArray(), identifier);
-
+
// set local y-axis
if (!v.Equals(Vector3d.Zero))
{
@@ -105,26 +96,26 @@ protected override void SolveInstance(IGH_DataAccess DA)
else
{
if (orientLCS)
- {
+ {
bar.BarPart.OrientCoordinateSystemToGCS();
}
}
-
+
// output
DA.SetData(0, bar);
- }
- protected override System.Drawing.Bitmap Icon
- {
- get
- {
+ }
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
return FemDesign.Properties.Resources.ColumnDefine;
- }
- }
- public override Guid ComponentGuid
- {
- get { return new Guid("3105b98e-ed85-46f4-9295-ed1d0d1af432"); }
- }
+ }
+ }
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("{5001B207-03E3-4571-A012-A05B7AC3F717}"); }
+ }
public override GH_Exposure Exposure => GH_Exposure.primary;
}
diff --git a/FemDesign.Grasshopper/Bars/BarsConnectivityConstruct.cs b/FemDesign.Grasshopper/Bars/BarsConnectivityConstruct.cs
index 6da8f3b04..2694cda70 100644
--- a/FemDesign.Grasshopper/Bars/BarsConnectivityConstruct.cs
+++ b/FemDesign.Grasshopper/Bars/BarsConnectivityConstruct.cs
@@ -14,9 +14,9 @@ public class BarsConnectivityConstruct: GH_Component
}
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
- pManager.AddBooleanParameter("m_x", "m_x", "Translation local-x axis. True if rigid, false if free.", GH_ParamAccess.item);
- pManager.AddBooleanParameter("m_y", "m_z", "Translation local-y axis. True if rigid, false if free.", GH_ParamAccess.item);
- pManager.AddBooleanParameter("m_z", "m_z", "Translation local-z axis. True if rigid, false if free.", GH_ParamAccess.item);
+ pManager.AddBooleanParameter("t_x", "t_x", "Translation local-x axis. True if rigid, false if free.", GH_ParamAccess.item);
+ pManager.AddBooleanParameter("t_y", "t_y", "Translation local-y axis. True if rigid, false if free.", GH_ParamAccess.item);
+ pManager.AddBooleanParameter("t_z", "t_z", "Translation local-z axis. True if rigid, false if free.", GH_ParamAccess.item);
pManager.AddBooleanParameter("r_x", "r_x", "Rotation around local-x axis. True if rigid, false if free.", GH_ParamAccess.item);
pManager.AddBooleanParameter("r_y", "r_y", "Rotation around local-y axis. True if rigid, false if free.", GH_ParamAccess.item);
pManager.AddBooleanParameter("r_z", "r_z", "Rotation around local-z axis. True if rigid, false if free.", GH_ParamAccess.item);
@@ -28,16 +28,16 @@ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
protected override void SolveInstance(IGH_DataAccess DA)
{
// get indata
- bool m_x = false, m_y = false, m_z = false, r_x = false, r_y = false, r_z = false;
- if (!DA.GetData(0, ref m_x)) { return; }
- if (!DA.GetData(1, ref m_y)) { return; }
- if (!DA.GetData(2, ref m_z)) { return; }
+ bool t_x = false, t_y = false, t_z = false, r_x = false, r_y = false, r_z = false;
+ if (!DA.GetData(0, ref t_x)) { return; }
+ if (!DA.GetData(1, ref t_y)) { return; }
+ if (!DA.GetData(2, ref t_z)) { return; }
if (!DA.GetData(3, ref r_x)) { return; }
if (!DA.GetData(4, ref r_y)) { return; }
if (!DA.GetData(5, ref r_z)) { return; }
// return
- DA.SetData(0, new FemDesign.Bars.Connectivity(m_x, m_y, m_z, r_x, r_y, r_z));
+ DA.SetData(0, new FemDesign.Bars.Connectivity(t_x, t_y, t_z, r_x, r_y, r_z));
}
protected override System.Drawing.Bitmap Icon
{
diff --git a/FemDesign.Grasshopper/Bars/BarsConnectivityDefineSemiRigid.cs b/FemDesign.Grasshopper/Bars/BarsConnectivityDefineSemiRigid.cs
index 410b98d1a..0431f006f 100644
--- a/FemDesign.Grasshopper/Bars/BarsConnectivityDefineSemiRigid.cs
+++ b/FemDesign.Grasshopper/Bars/BarsConnectivityDefineSemiRigid.cs
@@ -14,11 +14,11 @@ public class BarsConnectivityDefineSemiRigid: GH_Component
}
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
- pManager.AddNumberParameter("m_x", "m_x", "Release stiffness. Translation local-x axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
+ pManager.AddNumberParameter("t_x", "t_x", "Release stiffness. Translation local-x axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
pManager[pManager.ParamCount -1].Optional = true;
- pManager.AddNumberParameter("m_y", "m_z", "Release stiffness. Translation local-y axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
+ pManager.AddNumberParameter("t_y", "t_z", "Release stiffness. Translation local-y axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
pManager[pManager.ParamCount -1].Optional = true;
- pManager.AddNumberParameter("m_z", "m_z", "Release stiffness. Translation local-z axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
+ pManager.AddNumberParameter("t_z", "t_z", "Release stiffness. Translation local-z axis. Optional, default value is fully rigid. [kN/m]", GH_ParamAccess.item);
pManager[pManager.ParamCount -1].Optional = true;
pManager.AddNumberParameter("r_x", "r_x", "Release stiffness. Rotation around local-x axis. Optional, default value is fully rigid. [kNm/rad]", GH_ParamAccess.item);
pManager[pManager.ParamCount -1].Optional = true;
diff --git a/FemDesign.Grasshopper/Bars/BarsModify.cs b/FemDesign.Grasshopper/Bars/BarsModify.cs
index 0e34655f0..1a5324c38 100644
--- a/FemDesign.Grasshopper/Bars/BarsModify.cs
+++ b/FemDesign.Grasshopper/Bars/BarsModify.cs
@@ -117,8 +117,7 @@ protected override void SolveInstance(IGH_DataAccess DA)
string identifier = null;
if (DA.GetData(9, ref identifier))
{
- bar.Name = identifier;
- bar.BarPart.Name = bar.Name;
+ bar.Identifier = identifier;
}
// output
diff --git a/FemDesign.Grasshopper/Bars/BarsTruss.cs b/FemDesign.Grasshopper/Bars/BarsTruss.cs
index 53db50274..47d6200e0 100644
--- a/FemDesign.Grasshopper/Bars/BarsTruss.cs
+++ b/FemDesign.Grasshopper/Bars/BarsTruss.cs
@@ -16,9 +16,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddCurveParameter("Line", "Line", "LineCurve", GH_ParamAccess.item);
pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
- pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Section", "Section", "Section.", GH_ParamAccess.item);
- pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
@@ -37,16 +35,10 @@ protected override void SolveInstance(IGH_DataAccess DA)
if (!DA.GetData(0, ref curve)) { return; }
FemDesign.Materials.Material material = null;
- if (!DA.GetData(1, ref material))
- {
- material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
- }
+ if (!DA.GetData(1, ref material)) { return; }
FemDesign.Sections.Section section = null;
- if (!DA.GetData(2, ref section))
- {
- section = FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600");
- }
+ if (!DA.GetData(2, ref section)) { return; }
Vector3d v = Vector3d.Zero;
if (!DA.GetData(3, ref v))
@@ -103,7 +95,7 @@ protected override System.Drawing.Bitmap Icon
}
public override Guid ComponentGuid
{
- get { return new Guid("bfc07633-529a-4a98-a45b-ce657e916f83"); }
+ get { return new Guid("{EC481150-B491-406E-8549-92625E18FBEC}"); }
}
public override GH_Exposure Exposure => GH_Exposure.primary;
diff --git a/FemDesign.Grasshopper/Bars/BarsTrussLimitedCapacity.cs b/FemDesign.Grasshopper/Bars/BarsTrussLimitedCapacity.cs
index da0ea5c29..2c50279de 100644
--- a/FemDesign.Grasshopper/Bars/BarsTrussLimitedCapacity.cs
+++ b/FemDesign.Grasshopper/Bars/BarsTrussLimitedCapacity.cs
@@ -82,7 +82,7 @@ protected override void SolveInstance(IGH_DataAccess DA)
FemDesign.Geometry.Edge edge = Convert.FromRhinoLineCurve((LineCurve)curve);
// bar
- FemDesign.Bars.Bar bar = new FemDesign.Bars.Bar(edge, material, section, identifier: identifier);
+ FemDesign.Bars.Bar bar = Bars.Bar.Truss(edge, material, section, identifier);
bar.MaxCompression = maxCompression;
bar.MaxTension = maxTension;
bar.CompressionPlasticity = compressionPlasticity;
diff --git a/FemDesign.Grasshopper/Bars/OBSOLETE/BarsBeam_OBSOLETE.cs b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsBeam_OBSOLETE.cs
new file mode 100644
index 000000000..cca0bbbb4
--- /dev/null
+++ b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsBeam_OBSOLETE.cs
@@ -0,0 +1,130 @@
+// https://strusoft.com/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+
+namespace FemDesign.Grasshopper
+{
+ public class BarsBeam_OBSOLETE : GH_Component
+ {
+ public BarsBeam_OBSOLETE() : base("Bars.Beam", "Beam", "Create a bar element of type beam.",
+ CategoryName.Name(),
+ SubCategoryName.Cat2a())
+ {
+
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddCurveParameter("Curve", "Curve", "LineCurve or ArcCurve", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Section", "Section", "Section. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Connectivity", "Connectivity", "Connectivity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Eccentricity", "Eccentricity", "Eccentricity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddTextParameter("Identifier", "Identifier", "Identifier. Optional, default value if undefined.", GH_ParamAccess.item, "B");
+ pManager[pManager.ParamCount - 1].Optional = true;
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddGenericParameter("Bar", "Bar", "Bar.", GH_ParamAccess.item);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ // get input
+ Curve curve = null;
+ if (!DA.GetData(0, ref curve)) { return; }
+
+ FemDesign.Materials.Material material = null;
+ if (!DA.GetData(1, ref material))
+ {
+ material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
+ }
+
+ List sections = new List();
+ if (!DA.GetDataList(2, sections))
+ {
+ sections = new List();
+ sections.Add(FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600"));
+ }
+
+ List connectivities = new List();
+ if (!DA.GetDataList(3, connectivities))
+ {
+ connectivities = new List { FemDesign.Bars.Connectivity.Rigid };
+ }
+
+ List eccentricities = new List();
+ if (!DA.GetDataList(4, eccentricities))
+ {
+ eccentricities = new List { FemDesign.Bars.Eccentricity.Default };
+ }
+
+ Vector3d v = Vector3d.Zero;
+ if (!DA.GetData(5, ref v))
+ {
+ // pass
+ }
+
+ bool orientLCS = true;
+ if (!DA.GetData(6, ref orientLCS))
+ {
+ // pass
+ }
+
+ string identifier = "B";
+ if (!DA.GetData(7, ref identifier))
+ {
+ // pass
+ }
+
+
+ // convert geometry
+ FemDesign.Geometry.Edge edge = Convert.FromRhinoLineOrArc2(curve);
+
+ // create bar
+ var type = FemDesign.Bars.BarType.Beam;
+ FemDesign.Bars.Bar bar = new FemDesign.Bars.Bar(edge, type, material, sections.ToArray(), eccentricities.ToArray(), connectivities.ToArray(), identifier);
+
+ // set local y-axis
+ if (!v.Equals(Vector3d.Zero))
+ {
+ bar.BarPart.LocalY = v.FromRhino();
+ }
+
+ // else orient coordinate system to GCS
+ else
+ {
+ if (orientLCS)
+ {
+ bar.BarPart.OrientCoordinateSystemToGCS();
+ }
+ }
+
+ // output
+ DA.SetData(0, bar);
+
+ }
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
+ return FemDesign.Properties.Resources.BeamDefine;
+ }
+ }
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("135b6331-bf19-4d89-9e81-9e5e0d137f67"); }
+ }
+ public override GH_Exposure Exposure => GH_Exposure.hidden;
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Grasshopper/Bars/OBSOLETE/BarsColumn_OBSOLETE.cs b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsColumn_OBSOLETE.cs
new file mode 100644
index 000000000..7b36e49ff
--- /dev/null
+++ b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsColumn_OBSOLETE.cs
@@ -0,0 +1,131 @@
+// https://strusoft.com/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+
+namespace FemDesign.Grasshopper
+{
+ public class BarsColumn_OBSOLETE: GH_Component
+ {
+ public BarsColumn_OBSOLETE(): base("Bars.Column", "Column", "Create a bar element of type column.", CategoryName.Name(),
+ SubCategoryName.Cat2a())
+ {
+
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddCurveParameter("Line", "Line", "Line. Local x of line must equal positive global Z.", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Section", "Section", "Section. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Connectivity", "Connectivity", "Connectivity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Eccentricity", "Eccentricity", "Eccentricity. If 1 item this item defines both start and end. If two items the first item defines the start and the last item defines the end. Optional, default value if undefined.", GH_ParamAccess.list);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
+ pManager.AddTextParameter("Identifier", "Identifier", "Identifier. Optional, default value if undefined.", GH_ParamAccess.item, "C");
+ pManager[pManager.ParamCount - 1].Optional = true;
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddGenericParameter("Bar", "Bar", "Bar.", GH_ParamAccess.item);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ // get input
+ Curve curve = null;
+ if (!DA.GetData(0, ref curve)) { return; }
+
+ FemDesign.Materials.Material material = null;
+ if (!DA.GetData(1, ref material))
+ {
+ material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
+ }
+
+ List sections = new List();
+ if (!DA.GetDataList(2, sections))
+ {
+ sections = new List();
+ sections.Add(FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600"));
+ }
+
+ List connectivities = new List();
+ if (!DA.GetDataList(3, connectivities))
+ {
+ connectivities = new List{FemDesign.Bars.Connectivity.Rigid};
+ }
+
+ List eccentricities = new List();
+ if (!DA.GetDataList(4, eccentricities))
+ {
+ eccentricities = new List{FemDesign.Bars.Eccentricity.Default};
+ }
+
+ Vector3d v = Vector3d.Zero;
+ if (!DA.GetData(5, ref v))
+ {
+ // pass
+ }
+
+ bool orientLCS = true;
+ if (!DA.GetData(6, ref orientLCS))
+ {
+ // pass
+ }
+
+ string identifier = "C";
+ if (!DA.GetData(7, ref identifier))
+ {
+ // pass
+ }
+
+ // convert geometry
+ if (curve.GetType() != typeof(LineCurve))
+ {
+ throw new System.ArgumentException("Curve must be a LineCurve");
+ }
+ FemDesign.Geometry.Edge edge = Convert.FromRhinoLineCurve((LineCurve)curve);
+
+ // create bar
+ var type = FemDesign.Bars.BarType.Column;
+ FemDesign.Bars.Bar bar = new FemDesign.Bars.Bar(edge, type, material, sections.ToArray(), eccentricities.ToArray(), connectivities.ToArray(), identifier);
+
+ // set local y-axis
+ if (!v.Equals(Vector3d.Zero))
+ {
+ bar.BarPart.LocalY = v.FromRhino();
+ }
+
+ // else orient coordinate system to GCS
+ else
+ {
+ if (orientLCS)
+ {
+ bar.BarPart.OrientCoordinateSystemToGCS();
+ }
+ }
+
+ // output
+ DA.SetData(0, bar);
+
+ }
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
+ return FemDesign.Properties.Resources.ColumnDefine;
+ }
+ }
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("3105b98e-ed85-46f4-9295-ed1d0d1af432"); }
+ }
+
+ public override GH_Exposure Exposure => GH_Exposure.hidden;
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Grasshopper/Bars/OBSOLETE/BarsTruss_OBSOLETE.cs b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsTruss_OBSOLETE.cs
new file mode 100644
index 000000000..1193f3844
--- /dev/null
+++ b/FemDesign.Grasshopper/Bars/OBSOLETE/BarsTruss_OBSOLETE.cs
@@ -0,0 +1,111 @@
+// https://strusoft.com/
+using System;
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+
+namespace FemDesign.Grasshopper
+{
+ public class BarsTruss_OBSOLETE: GH_Component
+ {
+ public BarsTruss_OBSOLETE(): base("Bars.Truss", "Truss", "Create a bar element of type truss.", CategoryName.Name(),
+ SubCategoryName.Cat2a())
+ {
+
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddCurveParameter("Line", "Line", "LineCurve", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Material", "Material", "Material.", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddGenericParameter("Section", "Section", "Section.", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddVectorParameter("LocalY", "LocalY", "Set local y-axis. Vector must be perpendicular to Curve mid-point local x-axis. This parameter overrides OrientLCS", GH_ParamAccess.item);
+ pManager[pManager.ParamCount - 1].Optional = true;
+ pManager.AddBooleanParameter("OrientLCS", "OrientLCS", "Orient LCS to GCS? If true the LCS of this object will be oriented to the GCS trying to align local z to global z if possible or align local y to global y if possible (if object is vertical). If false local y-axis from Curve coordinate system at mid-point will be used.", GH_ParamAccess.item, true);
+ pManager.AddTextParameter("Identifier", "Identifier", "Identifier. Optional, default value if undefined.", GH_ParamAccess.item, "T");
+ pManager[pManager.ParamCount - 1].Optional = true;
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddGenericParameter("Bar", "Bar", "Bar.", GH_ParamAccess.item);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ // get input
+
+ Curve curve = null;
+ if (!DA.GetData(0, ref curve)) { return; }
+
+ FemDesign.Materials.Material material = null;
+ if (!DA.GetData(1, ref material))
+ {
+ material = FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37");
+ }
+
+ FemDesign.Sections.Section section = null;
+ if (!DA.GetData(2, ref section))
+ {
+ section = FemDesign.Sections.SectionDatabase.GetDefault().SectionByName("Concrete sections, Rectangle, 250x600");
+ }
+
+ Vector3d v = Vector3d.Zero;
+ if (!DA.GetData(3, ref v))
+ {
+ // pass
+ }
+
+ bool orientLCS = true;
+ if (!DA.GetData(4, ref orientLCS))
+ {
+ // pass
+ }
+
+ string identifier = "T";
+ if (!DA.GetData(5, ref identifier))
+ {
+ // pass
+ }
+
+ // convert geometry
+ if (curve.GetType() != typeof(LineCurve))
+ {
+ throw new System.ArgumentException("Curve must be a LineCurve");
+ }
+ FemDesign.Geometry.Edge edge = Convert.FromRhinoLineCurve((LineCurve)curve);
+
+ // bar
+ FemDesign.Bars.Bar bar = new Bars.Truss(edge, material, section, identifier);
+
+ // set local y-axis
+ if (!v.Equals(Vector3d.Zero))
+ {
+ bar.BarPart.LocalY = v.FromRhino();
+ }
+
+ // else orient coordinate system to GCS
+ else
+ {
+ if (orientLCS)
+ {
+ bar.BarPart.OrientCoordinateSystemToGCS();
+ }
+ }
+
+ // return
+ DA.SetData(0, bar);
+ }
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
+ return FemDesign.Properties.Resources.TrussDefine;
+ }
+ }
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("bfc07633-529a-4a98-a45b-ce657e916f83"); }
+ }
+ public override GH_Exposure Exposure => GH_Exposure.hidden;
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Grasshopper/Calculate/ApplicationRunAnalysis.cs b/FemDesign.Grasshopper/Calculate/ApplicationRunAnalysis.cs
index a6fff2899..d6659d023 100644
--- a/FemDesign.Grasshopper/Calculate/ApplicationRunAnalysis.cs
+++ b/FemDesign.Grasshopper/Calculate/ApplicationRunAnalysis.cs
@@ -17,7 +17,7 @@ public ModelRunAnalysis() : base("Application.RunAnalysis", "RunAnalysis", "Run
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddGenericParameter("FdModel", "FdModel", "FdModel to open.", GH_ParamAccess.item);
- pManager.AddTextParameter("FilePathStruxml", "FilePathStruxml", "File path where to save the model as .struxml.\nIf not specified, the file will be saved using the name and location folder of your .gh script.", GH_ParamAccess.item);
+ pManager.AddTextParameter("FilePathStruxml", "FilePath", "File path where to save the model as .struxml.\nIf not specified, the file will be saved using the name and location folder of your .gh script.", GH_ParamAccess.item);
pManager[pManager.ParamCount - 1].Optional = true;
pManager.AddGenericParameter("Analysis", "Analysis", "Analysis.", GH_ParamAccess.item);
pManager.AddTextParameter("ResultTypes", "ResultTypes", "Results to be extracted from model. This might require the model to have been analysed. Item or list.", GH_ParamAccess.list);
diff --git a/FemDesign.Grasshopper/ConstructionStages/ActivatedLoadCase.cs b/FemDesign.Grasshopper/ConstructionStages/ActivatedLoadCase.cs
index f28424816..a9b62b50c 100644
--- a/FemDesign.Grasshopper/ConstructionStages/ActivatedLoadCase.cs
+++ b/FemDesign.Grasshopper/ConstructionStages/ActivatedLoadCase.cs
@@ -4,6 +4,10 @@
using Grasshopper.Kernel;
using Rhino.Geometry;
using FemDesign.Loads;
+using System.Linq;
+using Grasshopper.Kernel.Special;
+
+using FemDesign.Grasshopper.Extension.ComponentExtension;
namespace FemDesign.Grasshopper
{
@@ -19,7 +23,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager)
pManager.AddGenericParameter("LoadCase", "LoadCase", "LoadCase to be activated.\n\nLoadCase may also be \"PTC T0\" or \"PTC T8\" to activate a PTC load", GH_ParamAccess.item);
pManager.AddNumberParameter("Factor", "Factor", "Factor", GH_ParamAccess.item, 1.0);
pManager[pManager.ParamCount - 1].Optional = true;
- pManager.AddIntegerParameter("Partitioning", "Partitioning", "0 - only_in_this_stage\n1 - from_this_stage_on\n2 - shifted_from_first_stage\n3 - only_stage_activated_elem.\nDefault: from_this_stage_on.", GH_ParamAccess.item, 1);
+ pManager.AddTextParameter("Partitioning", "Partitioning", "Connect 'ValueList' to get the options.\n0 - only_in_this_stage\n1 - from_this_stage_on\n2 - shifted_from_first_stage\n3 - only_stage_activated_elem.\nDefault: from_this_stage_on.", GH_ParamAccess.item, "from_this_stage_on");
pManager[pManager.ParamCount - 1].Optional = true;
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
@@ -39,14 +43,10 @@ protected override void SolveInstance(IGH_DataAccess DA)
double factor = 1;
DA.GetData(1, ref factor);
- int partitioning = 1;
- ActivationType type = (ActivationType)partitioning; //from_this_stage_on
+ string partitioning = "1";
DA.GetData(2, ref partitioning);
- if (Enum.IsDefined(typeof(ActivationType), partitioning))
- {
- type = (ActivationType)partitioning;
- }
+ ActivationType type = FemDesign.GenericClasses.EnumParser.Parse(partitioning);
FemDesign.ActivatedLoadCase activatedLoadCase;
if (isLoadCase)
@@ -61,6 +61,13 @@ protected override void SolveInstance(IGH_DataAccess DA)
DA.SetData(0, activatedLoadCase);
}
+ protected override void BeforeSolveInstance()
+ {
+ var resultTypes = Enum.GetNames(typeof(ActivationType)).ToList();
+ ValueListUtils.updateValueLists(this, 2, resultTypes, null);
+
+ }
+
protected override System.Drawing.Bitmap Icon
{
get
diff --git a/FemDesign.Grasshopper/ConstructionStages/Stage.cs b/FemDesign.Grasshopper/ConstructionStages/Stage.cs
index 8f0f1f21b..11d6db5ef 100644
--- a/FemDesign.Grasshopper/ConstructionStages/Stage.cs
+++ b/FemDesign.Grasshopper/ConstructionStages/Stage.cs
@@ -9,9 +9,9 @@
namespace FemDesign.Grasshopper
{
- public class Stage : GH_Component
+ public class StageComponent : GH_Component
{
- public Stage() : base("Stage", "Stage", "Creates a construction stage.", CategoryName.Name(),
+ public StageComponent() : base("Stage", "Stage", "Creates a construction stage.", CategoryName.Name(),
SubCategoryName.Cat7a())
{
@@ -30,7 +30,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager)
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
- pManager.AddGenericParameter("Stages", "Stages", "", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Stage", "Stage", "", GH_ParamAccess.item);
}
protected override void SolveInstance(IGH_DataAccess DA)
{
diff --git a/FemDesign.Grasshopper/Deconstruct/LineStressLoadDeconstruct.cs b/FemDesign.Grasshopper/Deconstruct/LineStressLoadDeconstruct.cs
new file mode 100644
index 000000000..4be0755db
--- /dev/null
+++ b/FemDesign.Grasshopper/Deconstruct/LineStressLoadDeconstruct.cs
@@ -0,0 +1,57 @@
+// https://strusoft.com/
+using System;
+using Grasshopper.Kernel;
+
+namespace FemDesign.Grasshopper
+{
+ public class LineStressLoadDeconstruct : GH_Component
+ {
+ public LineStressLoadDeconstruct() : base("LineStressLoad.Deconstruct", "Deconstruct", "Deconstruct a LineStressLoad.", "FEM-Design", "Deconstruct")
+ {
+
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddGenericParameter("LineStressLoad", "LineStressLoad", "Line stress load. Use SortLoads to extract LineStressLoads.", GH_ParamAccess.item);
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddTextParameter("Guid", "Guid", "Guid.", GH_ParamAccess.item);
+ pManager.AddCurveParameter("Curve", "Curve", "Curve.", GH_ParamAccess.item);
+ pManager.AddVectorParameter("Direction", "Direction", "Direction.", GH_ParamAccess.item);
+ pManager.AddNumberParameter("n1", "n1", "Force at start.", GH_ParamAccess.item);
+ pManager.AddNumberParameter("n2", "n2", "Force at end.", GH_ParamAccess.item);
+ pManager.AddNumberParameter("m1", "m1", "Moment at start.", GH_ParamAccess.item);
+ pManager.AddNumberParameter("m2", "m2", "Moment at end.", GH_ParamAccess.item);
+ pManager.AddTextParameter("LoadCaseGuid", "LoadCaseGuid", "LoadCase guid reference.", GH_ParamAccess.item);
+ pManager.AddTextParameter("Comment", "Comment", "Comment.", GH_ParamAccess.item);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ // get input
+ FemDesign.Loads.LineStressLoad stressLoad = null;
+ if (!DA.GetData(0, ref stressLoad))
+ {
+ return;
+ }
+ if (stressLoad == null)
+ {
+ return;
+ }
+
+ DA.SetData("Guid", stressLoad.LoadCaseGuid);
+ DA.SetData("Curve", stressLoad.Edge.ToRhino());
+ DA.SetData("Direction", stressLoad.Direction.ToRhino());
+ DA.SetData("n1", stressLoad.TopBotLocVal[0].TopVal);
+ DA.SetData("m1", stressLoad.TopBotLocVal[0].BottomVal);
+ DA.SetData("n2", stressLoad.TopBotLocVal[1].TopVal);
+ DA.SetData("m2", stressLoad.TopBotLocVal[1].BottomVal);
+ DA.SetData("LoadCaseGuid", stressLoad.LoadCaseGuid);
+ DA.SetData("Comment", stressLoad.Comment);
+ }
+ protected override System.Drawing.Bitmap Icon => FemDesign.Properties.Resources.LineStressLoadDeconstruct;
+ public override Guid ComponentGuid => new Guid("6b4b792a-a7cc-44de-af6a-5e30a9429fa1");
+ public override GH_Exposure Exposure => GH_Exposure.quarternary;
+
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Grasshopper/Deconstruct/LoadCombinationDeconstruct.cs b/FemDesign.Grasshopper/Deconstruct/LoadCombinationDeconstruct.cs
index b1fe2f47b..7d725dc45 100644
--- a/FemDesign.Grasshopper/Deconstruct/LoadCombinationDeconstruct.cs
+++ b/FemDesign.Grasshopper/Deconstruct/LoadCombinationDeconstruct.cs
@@ -1,30 +1,32 @@
// https://strusoft.com/
using System;
+using System.Linq;
using System.Collections.Generic;
using Grasshopper.Kernel;
namespace FemDesign.Grasshopper
{
- public class LoadCombinationDeconstruct: GH_Component
+ public class LoadCombinationDeconstruct : GH_Component
{
- public LoadCombinationDeconstruct(): base("LoadCombination.Deconstruct", "Deconstruct", "Deconstruct a LoadCombination.", "FEM-Design", "Deconstruct")
- {
+ public LoadCombinationDeconstruct() : base("LoadCombination.Deconstruct", "Deconstruct", "Deconstruct a LoadCombination.", "FEM-Design", "Deconstruct")
+ {
- }
- protected override void RegisterInputParams(GH_InputParamManager pManager)
- {
- pManager.AddGenericParameter("LoadCombination", "LoadCombination", "LoadCombination.", GH_ParamAccess.item);
- }
- protected override void RegisterOutputParams(GH_OutputParamManager pManager)
- {
- pManager.AddTextParameter("Guid", "Guid", "Guid.", GH_ParamAccess.list);
- pManager.AddTextParameter("Name", "Name", "Name.", GH_ParamAccess.list);
- pManager.AddTextParameter("Type", "Type", "Type." , GH_ParamAccess.list);
- pManager.AddTextParameter("LoadCases", "LoadCases", "LoadCases.", GH_ParamAccess.list);
- pManager.AddNumberParameter("Gammas", "Gammas", "Gammas.", GH_ParamAccess.list);
- }
- protected override void SolveInstance(IGH_DataAccess DA)
- {
+ }
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {
+ pManager.AddGenericParameter("LoadCombination", "LoadCombination", "LoadCombination.", GH_ParamAccess.item);
+ }
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddTextParameter("Guid", "Guid", "Guid.", GH_ParamAccess.list);
+ pManager.AddTextParameter("Name", "Name", "Name.", GH_ParamAccess.list);
+ pManager.AddTextParameter("Type", "Type", "Type.", GH_ParamAccess.list);
+ pManager.AddGenericParameter("LoadCases", "LoadCases", "LoadCases. Note that load cases may also include a single construction stage and any single of the special load cases such as seisemic, PTC or Neg. shaft friction load case.", GH_ParamAccess.list);
+ pManager.AddNumberParameter("Gammas", "Gammas", "Gammas.", GH_ParamAccess.list);
+ pManager.AddTextParameter("LoadCaseTypes", "LoadCaseTypes", "Load case types. One of 'Load case', 'stage' or 'Special load case'.", GH_ParamAccess.list);
+ }
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
// get input
FemDesign.Loads.LoadCombination obj = null;
if (!DA.GetData(0, ref obj))
@@ -39,33 +41,26 @@ protected override void SolveInstance(IGH_DataAccess DA)
// The following code is to convert 'item' to 'list object'
// It is required to construct the Load Combination without graftening the data
- var guidList = new List
-
+
+
+
+
-
+
@@ -117,6 +120,9 @@
Always
+
+ Always
+
Always
diff --git a/FemDesign.Tests/GenericClasses/EnumHelpersTests.cs b/FemDesign.Tests/GenericClasses/EnumHelpersTests.cs
index 6bfe361ba..b81c2c5de 100644
--- a/FemDesign.Tests/GenericClasses/EnumHelpersTests.cs
+++ b/FemDesign.Tests/GenericClasses/EnumHelpersTests.cs
@@ -27,5 +27,17 @@ public void ParseCountryTest()
Assert.Fail($"Should be able to parse country \"{countryCode}\" successfully");
}
}
+
+ [TestMethod("Parse Activation Type")]
+ public void ParseLoadActivation()
+ {
+ Assert.IsTrue(EnumParser.Parse("0") == ActivationType.OnlyInThisStage);
+ Assert.IsTrue(EnumParser.Parse("1") == ActivationType.FromThisStageOn);
+ Assert.IsTrue(EnumParser.Parse("2") == ActivationType.ShiftedFromFirstStage);
+ Assert.IsTrue(EnumParser.Parse("3") == ActivationType.OnlyStageActivatedElements);
+
+ Assert.IsTrue(EnumParser.Parse("only_in_this_stage") == ActivationType.OnlyInThisStage);
+ Assert.IsTrue(EnumParser.Parse("only_stage_activated_elem") == ActivationType.OnlyStageActivatedElements);
+ }
}
}
\ No newline at end of file
diff --git a/FemDesign.Tests/Geometry/RegionTest.cs b/FemDesign.Tests/Geometry/RegionTest.cs
index 3b3f6ff2e..304d18a09 100644
--- a/FemDesign.Tests/Geometry/RegionTest.cs
+++ b/FemDesign.Tests/Geometry/RegionTest.cs
@@ -12,14 +12,15 @@ public class RegionTest
[TestMethod("Create Rectangle Slab")]
public void CreateRectangle()
{
- //
var rectangleWall = FemDesign.Shells.Slab.Wall(
+ Point3d.Origin,
+ new Point3d(10, 10, 0),
10.0,
- 20.0,
0.1,
FemDesign.Materials.MaterialDatabase.GetDefault().MaterialByName("C30/37"));
var rectangleWall2 = FemDesign.Shells.Slab.Plate(
+ Point3d.Origin,
10.0,
20.0,
0.1,
diff --git a/FemDesign.Tests/Loads/Load combination case types.struxml b/FemDesign.Tests/Loads/Load combination case types.struxml
new file mode 100644
index 000000000..627181801
--- /dev/null
+++ b/FemDesign.Tests/Loads/Load combination case types.struxml
@@ -0,0 +1,440 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ -10
+
+
+
+
+ 0
+ -10
+
+
+
+
+ 0
+ -10
+
+
+
+
+ 0
+ -10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 0.142593308852768 0.285186617705536 0.500000001781668 0.712966544263839 0.855559853116607 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FemDesign.Tests/Loads/LoadCombinationTests.cs b/FemDesign.Tests/Loads/LoadCombinationTests.cs
new file mode 100644
index 000000000..eac32ec1d
--- /dev/null
+++ b/FemDesign.Tests/Loads/LoadCombinationTests.cs
@@ -0,0 +1,108 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using FemDesign.Loads;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FemDesign.Loads
+{
+ [TestClass()]
+ public class LoadCombinationTests
+ {
+ [TestCategory("FEM-Design required")]
+ [TestMethod("Load combinations - Deserialize")]
+ public void LoadCombinationTest1()
+ {
+ Model model = Model.DeserializeFromFilePath("Loads/Load combination case types.struxml");
+
+ Assert.AreEqual(4, model.Entities.Loads.LoadCombinations.Count);
+ var comb1 = model.Entities.Loads.LoadCombinations[0];
+ var comb2 = model.Entities.Loads.LoadCombinations[1];
+ var comb3 = model.Entities.Loads.LoadCombinations[2];
+ var comb4 = model.Entities.Loads.LoadCombinations[3];
+
+ // LoadCase and moving load load cases
+ Assert.AreEqual(1, comb1.ModelLoadCase.Count);
+ Assert.AreEqual(1, comb2.ModelLoadCase.Count);
+ Assert.AreEqual(1, comb3.ModelLoadCase.Count);
+ Assert.AreEqual(1, comb4.ModelLoadCase.Count);
+
+ Assert.IsFalse(comb1.ModelLoadCase[0].IsMovingLoadLoadCase);
+ Assert.IsFalse(comb2.ModelLoadCase[0].IsMovingLoadLoadCase);
+ Assert.IsFalse(comb3.ModelLoadCase[0].IsMovingLoadLoadCase);
+ Assert.IsTrue(comb4.ModelLoadCase[0].IsMovingLoadLoadCase);
+
+ Assert.IsNotNull(comb1.ModelLoadCase[0].LoadCase);
+ Assert.IsNotNull(comb2.ModelLoadCase[0].LoadCase);
+ Assert.IsNotNull(comb3.ModelLoadCase[0].LoadCase);
+ Assert.IsNull(comb4.ModelLoadCase[0].LoadCase);
+
+ // Seismic
+ Assert.IsNotNull(comb2.SeismicMax);
+ Assert.IsNotNull(comb2.SeismicResFxMinusMx);
+ Assert.IsNotNull(comb2.SeismicResFxPlusMx);
+ Assert.IsNotNull(comb2.SeismicResFyMinusMy);
+ Assert.IsNotNull(comb2.SeismicResFyPlusMy);
+ Assert.IsNotNull(comb2.SeismicResFz);
+
+ // PTC
+ Assert.IsNotNull(comb3.PtcT0);
+ Assert.IsNotNull(comb3.PtcT8);
+
+ // Pile
+ Assert.IsNotNull(comb3.PileLoadCase);
+
+ // Construction stages
+ Assert.AreEqual("cs.1", comb1.StageLoadCase._stageType);
+ Assert.AreEqual(1, comb1.StageLoadCase.StageIndex);
+ Assert.IsFalse(comb1.StageLoadCase.IsFinalStage);
+ Assert.IsNotNull(comb1.StageLoadCase.Stage);
+
+ Assert.AreEqual("cs.2", comb2.StageLoadCase._stageType);
+ Assert.AreEqual(2, comb2.StageLoadCase.StageIndex);
+ Assert.IsFalse(comb2.StageLoadCase.IsFinalStage);
+ Assert.IsNotNull(comb2.StageLoadCase.Stage);
+
+ Assert.AreEqual("final_cs", comb3.StageLoadCase._stageType);
+ Assert.AreEqual(-1, comb3.StageLoadCase.StageIndex);
+ Assert.IsTrue(comb3.StageLoadCase.IsFinalStage);
+ Assert.IsNull(comb3.StageLoadCase.Stage);
+ }
+
+ [TestCategory("FEM-Design required")]
+ [TestMethod("Load combinations - Serialize")]
+ public void LoadCombinationTest2()
+ {
+ Model expected = Model.DeserializeFromFilePath("Loads/Load combination case types.struxml");
+ expected.SerializeModel("Loads/out.struxml");
+ Model actual = Model.DeserializeFromFilePath("Loads/out.struxml");
+
+ Assert.AreEqual(expected.Entities.Loads.LoadCombinations.Count, actual.Entities.Loads.LoadCombinations.Count);
+ var e = expected.Entities.Loads.LoadCombinations;
+ var a = actual.Entities.Loads.LoadCombinations;
+
+ for (int i = 0; i < a.Count; i++)
+ {
+ Assert.AreEqual(e[i].ModelLoadCase.Count, a[i].ModelLoadCase.Count);
+ for (int j = 0; j < a[i].ModelLoadCase.Count; j++)
+ Assert.AreEqual(e[i].ModelLoadCase[j].Gamma, a[i].ModelLoadCase[j].Gamma);
+
+ Assert.AreEqual(e[i].SeismicMax?.Gamma, a[i].SeismicMax?.Gamma);
+ Assert.AreEqual(e[i].SeismicResFxPlusMx?.Gamma, a[i].SeismicResFxPlusMx?.Gamma);
+ Assert.AreEqual(e[i].SeismicResFxMinusMx?.Gamma, a[i].SeismicResFxMinusMx?.Gamma);
+ Assert.AreEqual(e[i].SeismicResFyPlusMy?.Gamma, a[i].SeismicResFyPlusMy?.Gamma);
+ Assert.AreEqual(e[i].SeismicResFyMinusMy?.Gamma, a[i].SeismicResFyMinusMy?.Gamma);
+ Assert.AreEqual(e[i].SeismicResFz?.Gamma, a[i].SeismicResFz?.Gamma);
+
+ Assert.AreEqual(e[i].PtcT0?.Gamma, a[i].PtcT0?.Gamma);
+ Assert.AreEqual(e[i].PtcT8?.Gamma, a[i].PtcT8?.Gamma);
+
+ Assert.AreEqual(e[i].PileLoadCase?.Gamma, a[i].PileLoadCase?.Gamma);
+
+ Assert.AreEqual(e[i].StageLoadCase?._stageType, a[i].StageLoadCase?._stageType);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/FemDesign.Tests/Performance/BeamGeneration.cs b/FemDesign.Tests/Performance/BeamGenerationTests.cs
similarity index 98%
rename from FemDesign.Tests/Performance/BeamGeneration.cs
rename to FemDesign.Tests/Performance/BeamGenerationTests.cs
index 447fec18c..47ac53933 100644
--- a/FemDesign.Tests/Performance/BeamGeneration.cs
+++ b/FemDesign.Tests/Performance/BeamGenerationTests.cs
@@ -12,7 +12,7 @@
namespace FemDesign.Performance
{
[TestClass()]
- public class BeamGeneration
+ public class BeamGenerationTests
{
[TestMethod("GenerateBeam")]
[TestCategory("FEM-Design required"), TestCategory("Performance")]
diff --git a/femdesign-api.sln b/femdesign-api.sln
index 973082be1..254b656bf 100644
--- a/femdesign-api.sln
+++ b/femdesign-api.sln
@@ -10,6 +10,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FemDesign.Dynamo", "FemDesign.Dynamo\FemDesign.Dynamo.csproj", "{419CA97B-DCA5-40EF-A640-7691622E3BE5}"
ProjectSection(ProjectDependencies) = postProject
{81B4BC3B-8FC7-46FA-8C79-DFAA1C16FE21} = {81B4BC3B-8FC7-46FA-8C79-DFAA1C16FE21}
+ {1D91EBF4-A473-4C5B-A171-AB2DA1B7017B} = {1D91EBF4-A473-4C5B-A171-AB2DA1B7017B}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FemDesign.Examples", "FemDesign.Examples", "{C68FA42C-7B20-4FE3-AED6-8B6619EE5410}"
@@ -46,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example 5 - Design a beam",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FemDesign.Tests", "FemDesign.Tests\FemDesign.Tests.csproj", "{CCADA385-E5FB-4F08-BC50-1826BBEF9794}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Practical example - Stiffness Point from CSV", "FemDesign.Examples\C#\Practical example - Create Stiffness Point from a CSV\Practical example - Stiffness Point from CSV.csproj", "{CA1CEF5F-1122-4D9B-B21D-3FB260335598}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -61,6 +64,7 @@ Global
{04F35658-7446-4513-AA4D-17B4782D3D00}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04F35658-7446-4513-AA4D-17B4782D3D00}.Release|Any CPU.Build.0 = Release|Any CPU
{419CA97B-DCA5-40EF-A640-7691622E3BE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {419CA97B-DCA5-40EF-A640-7691622E3BE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{419CA97B-DCA5-40EF-A640-7691622E3BE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{419CA97B-DCA5-40EF-A640-7691622E3BE5}.Release|Any CPU.Build.0 = Release|Any CPU
{1E5D535D-C21B-454B-A62E-1DF4D968E677}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -127,6 +131,10 @@ Global
{CCADA385-E5FB-4F08-BC50-1826BBEF9794}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCADA385-E5FB-4F08-BC50-1826BBEF9794}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCADA385-E5FB-4F08-BC50-1826BBEF9794}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CA1CEF5F-1122-4D9B-B21D-3FB260335598}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CA1CEF5F-1122-4D9B-B21D-3FB260335598}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CA1CEF5F-1122-4D9B-B21D-3FB260335598}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CA1CEF5F-1122-4D9B-B21D-3FB260335598}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -146,6 +154,7 @@ Global
{8954D8AD-051F-4B44-87A4-559C00DB1CD6} = {C68FA42C-7B20-4FE3-AED6-8B6619EE5410}
{A261E23F-DF9D-4ED5-8DC6-0DB6ECB06B9F} = {C68FA42C-7B20-4FE3-AED6-8B6619EE5410}
{04FA45B2-F2AF-4394-99F8-E50A82E91658} = {C68FA42C-7B20-4FE3-AED6-8B6619EE5410}
+ {CA1CEF5F-1122-4D9B-B21D-3FB260335598} = {C68FA42C-7B20-4FE3-AED6-8B6619EE5410}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DDF9D949-F79B-4EA6-A766-976B0BE0BC79}