예제 #1
0
 public static string ToXml(object obj)
 {
     WriteSettings settings = new WriteSettings
     {
         CloseInput = true,
         Encoding = new UTF8Encoding(false),
         OmitHead = true
     };
     string xml = obj.WriteXml(settings, WePayConst.QNAME_XML);
     return xml;
 }
 public string ConvertToString(object value, WriteSettings settings)
 {
     try
     {
         bool boolValue = (bool)value;
         return boolValue ? "Y" : "N";
     }
     catch
     {
         return "N";
     }
 }
 public string ConvertToString(object value, WriteSettings settings)
 {
     try
     {
         DateTime date = (DateTime)value;
         return WeUtil.ToCreateTime(date).ToString(ObjectUtil.SysCulture);
     }
     catch
     {
         return DefaultValue;
     }
 }
 public string ConvertToString(object value, WriteSettings settings)
 {
     ProductStatusType msg = (ProductStatusType)value;
     switch (msg)
     {
         case ProductStatusType.On:
             return "0";
         case ProductStatusType.Down:
             return "1";
         default:
             return "0";
     }
 }
예제 #5
0
 public string ConvertToString(object value, WriteSettings settings)
 {
     try
     {
         Color c = (Color)value;
         return "#" + c.R.ToString("X2", null) + c.G.ToString("X2", null)
             + c.B.ToString("X2", null);
     }
     catch
     {
         return DefaultValue;
     }
 }
예제 #6
0
 public string ConvertToString(object value, WriteSettings settings)
 {
     List<ProductProperty> lp = (List<ProductProperty>)value;
     //List<string> ls = new List<string>();
     //foreach (var n in lp)
     //{
     //    ls.Add(n.ToString());
     //}
     //Join<T>(String, IEnumerable<T>) 是一个便利方法,通过它可以串联 IEnumerable<T> 
     //集合的每个成员,无需事先将它们转换为字符串。 IEnumerable<T> 
     //集合中每个对象的字符串表示形式通过调用对象的ToString 方法派生。
     string result = string.Join(";", lp);
     return result;
 }
예제 #7
0
        public void LoadPollyModel()
        {
            // load Polly model
            var model = ModelRoot.Load(TestFiles.GetPollyFileModelPath(), Validation.ValidationMode.TryFix);

            Assert.NotNull(model);

            var triangles = model.DefaultScene
                            .EvaluateTriangles <Geometry.VertexTypes.VertexPosition, Geometry.VertexTypes.VertexTexture1>(null, model.LogicalAnimations[0], 0.5f)
                            .ToList();

            // Save as GLB, and also evaluate all triangles and save as Wavefront OBJ
            model.AttachToCurrentTest("polly_out.glb");
            model.AttachToCurrentTest("polly_out.obj");

            // hierarchically browse some elements of the model:

            var scene = model.DefaultScene;

            var pollyNode = scene.FindNode(n => n.Name == "Polly_Display");

            var pollyPrimitive = pollyNode.Mesh.Primitives[0];

            var pollyIndices   = pollyPrimitive.GetIndices();
            var pollyPositions = pollyPrimitive.GetVertices("POSITION").AsVector3Array();
            var pollyNormals   = pollyPrimitive.GetVertices("NORMAL").AsVector3Array();

            for (int i = 0; i < pollyIndices.Count; i += 3)
            {
                var a = (int)pollyIndices[i + 0];
                var b = (int)pollyIndices[i + 1];
                var c = (int)pollyIndices[i + 2];

                var ap = pollyPositions[a];
                var bp = pollyPositions[b];
                var cp = pollyPositions[c];

                var an = pollyNormals[a];
                var bn = pollyNormals[b];
                var cn = pollyNormals[c];

                TestContext.WriteLine($"Triangle {ap} {an} {bp} {bn} {cp} {cn}");
            }

            // create a clone and apply a global axis transform.

            var clonedModel = model.DeepClone();

            var basisTransform
                = Matrix4x4.CreateScale(1, 2, 1)
                  * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3)
                  * Matrix4x4.CreateTranslation(10, 5, 2);

            clonedModel.ApplyBasisTransform(basisTransform);

            clonedModel.AttachToCurrentTest("polly_out_transformed.glb");

            var wsettings = new WriteSettings();

            wsettings.ImageWriting   = ResourceWriteMode.BufferView;
            wsettings.MergeBuffers   = true;
            wsettings.BuffersMaxSize = 1024 * 1024 * 10;
            clonedModel.AttachToCurrentTest("polly_out_merged_10mb.gltf", wsettings);
        }
예제 #8
0
        public static string AttachToCurrentTest(this ModelRoot model, string fileName, WriteSettings settings = null)
        {
            // find the output path for the current test
            fileName = TestContext.CurrentContext.GetAttachmentPath(fileName, true);

            string validationPath = null;

            if (fileName.ToLower().EndsWith(".glb"))
            {
                model.SaveGLB(fileName, settings);
                validationPath = fileName;
            }
            else if (fileName.ToLower().EndsWith(".gltf"))
            {
                if (settings == null)
                {
                    settings = new WriteSettings {
                        JsonIndented = true
                    }
                }
                ;

                model.Save(fileName, settings);
                validationPath = fileName;
            }
            else if (fileName.ToLower().EndsWith(".obj"))
            {
                fileName = fileName.Replace(" ", "_");
                model.SaveAsWavefront(fileName);
            }
            else if (fileName.ToLower().EndsWith(".plotly"))
            {
                fileName = fileName.Replace(".plotly", ".html");

                var html = model.DefaultScene
                           .ToPlotly()
                           .ToHtml();

                System.IO.File.WriteAllText(fileName, html);
            }

            // Attach the saved file to the current test
            TestContext.AddTestAttachment(fileName);

            if (validationPath != null)
            {
                var report = gltf_validator.ValidateFile(fileName);
                if (report == null)
                {
                    return(fileName);
                }

                if (report.HasErrors || report.HasWarnings)
                {
                    TestContext.WriteLine(report.ToString());
                }

                Assert.IsFalse(report.HasErrors);
            }

            return(fileName);
        }
    }
예제 #9
0
        public static string AttachToCurrentTest(this ModelRoot model, string fileName, WriteSettings settings = null)
        {
            string validationPath = null;

            if (fileName.ToLowerInvariant().EndsWith(".glb"))
            {
                validationPath = fileName = AttachmentInfo
                                            .From(fileName)
                                            .WriteObject(f => model.SaveGLB(f.FullName, settings))
                                            .FullName;
            }
            else if (fileName.ToLowerInvariant().EndsWith(".gltf"))
            {
                if (settings == null)
                {
                    settings = new WriteSettings {
                        JsonIndented = true
                    }
                }
                ;

                validationPath = fileName = AttachmentInfo
                                            .From(fileName)
                                            .WriteObject(f => model.Save(f.FullName, settings))
                                            .FullName;
            }
            else if (fileName.ToLowerInvariant().EndsWith(".obj"))
            {
                // skip exporting to obj if gpu instancing is there
                if (Node.Flatten(model.DefaultScene).Any(n => n.GetGpuInstancing() != null))
                {
                    return(fileName);
                }

                fileName = fileName.Replace(" ", "_");

                fileName = AttachmentInfo
                           .From(fileName)
                           .WriteObject(f => model.SaveAsWavefront(f.FullName))
                           .FullName;
            }
            else if (fileName.ToLowerInvariant().EndsWith(".plotly"))
            {
                fileName = fileName.Replace(".plotly", ".html");

                var html = model.DefaultScene
                           .ToPlotly()
                           .ToHtml();

                fileName = AttachmentInfo
                           .From(fileName)
                           .WriteAllText(html)
                           .FullName;
            }

            if (validationPath != null)
            {
                var report = GltfValidator.ValidationReport.Validate(fileName);

                if (report == null)
                {
                    return(fileName);
                }

                if (report.Severity == GltfValidator.Severity.Error || report.Severity == GltfValidator.Severity.Warning)
                {
                    TestContext.WriteLine(report.ToString());
                }

                Assert.AreNotEqual(GltfValidator.Severity.Error, report.Severity);
            }

            return(fileName);
        }
    }
예제 #10
0
        public string ConvertToString(object value, WriteSettings settings)
        {
            bool boolValue = (bool)value;

            return(boolValue ? "1" : "0");
        }
예제 #11
0
        /// <summary>
        /// Export a Valve VMDL to GLTF.
        /// </summary>
        /// <param name="resourceName">The name of the resource being exported.</param>
        /// <param name="fileName">Target file name.</param>
        /// <param name="model">The model resource to export.</param>
        public void ExportToFile(string resourceName, string fileName, VModel model)
        {
            if (FileLoader == null)
            {
                throw new InvalidOperationException(nameof(FileLoader) + " must be set first.");
            }

            DstDir = Path.GetDirectoryName(fileName);

            var exportedModel = ModelRoot.CreateModel();

            exportedModel.Asset.Generator = GENERATOR;
            var scene = exportedModel.UseScene(Path.GetFileName(resourceName));

            void AddMeshNode(string name, VMesh mesh, Skeleton skeleton)
            {
                if (mesh.GetData().GetArray("m_sceneObjects").Length == 0)
                {
                    return;
                }

                var hasJoints       = skeleton.AnimationTextureSize > 0;
                var exportedMesh    = CreateGltfMesh(name, mesh, exportedModel, hasJoints);
                var hasVertexJoints = exportedMesh.Primitives.All(primitive => primitive.GetVertexAccessor("JOINTS_0") != null);

                if (hasJoints && hasVertexJoints)
                {
                    var skeletonNode = scene.CreateNode(name);
                    var joints       = CreateGltfSkeleton(skeleton, skeletonNode);

                    scene.CreateNode(name)
                    .WithSkinnedMesh(exportedMesh, Matrix4x4.Identity, joints);

                    // Rotate upright, scale inches to meters.
                    skeletonNode.WorldMatrix = TRANSFORMSOURCETOGLTF;

                    // Add animations
                    var animations = GetAllAnimations(model);
                    foreach (var animation in animations)
                    {
                        var exportedAnimation = exportedModel.CreateAnimation(animation.Name);
                        var rotationDict      = new Dictionary <string, Dictionary <float, Quaternion> >();
                        var translationDict   = new Dictionary <string, Dictionary <float, Vector3> >();

                        var time = 0f;
                        foreach (var frame in animation.Frames)
                        {
                            foreach (var boneFrame in frame.Bones)
                            {
                                var bone = boneFrame.Key;
                                if (!rotationDict.ContainsKey(bone))
                                {
                                    rotationDict[bone]    = new Dictionary <float, Quaternion>();
                                    translationDict[bone] = new Dictionary <float, Vector3>();
                                }
                                rotationDict[bone].Add(time, boneFrame.Value.Angle);
                                translationDict[bone].Add(time, boneFrame.Value.Position);
                            }
                            time += 1 / animation.Fps;
                        }

                        foreach (var bone in rotationDict.Keys)
                        {
                            var node = joints.FirstOrDefault(n => n.Name == bone);
                            if (node != null)
                            {
                                exportedAnimation.CreateRotationChannel(node, rotationDict[bone], true);
                                exportedAnimation.CreateTranslationChannel(node, translationDict[bone], true);
                            }
                        }
                    }
                }
                else
                {
                    var meshNode = scene.CreateNode(name)
                                   .WithMesh(exportedMesh);

                    // Rotate upright, scale inches to meters.
                    meshNode.WorldMatrix = TRANSFORMSOURCETOGLTF;
                }
            }

            // Add meshes and their skeletons
            var meshes = LoadModelMeshes(model);

            for (var i = 0; i < meshes.Length; i++)
            {
                AddMeshNode(meshes[i].Name, meshes[i].Mesh, model.GetSkeleton(i));
            }

            var settings = new WriteSettings();

            settings.ImageWriting       = ResourceWriteMode.SatelliteFile;
            settings.ImageWriteCallback = ImageWriteCallback;
            settings.JsonIndented       = true;

            exportedModel.Save(fileName, settings);
        }
예제 #12
0
 public virtual string ConvertToString(object value, WriteSettings settings)
 {
     return(value.ConvertToString());
 }
예제 #13
0
        public void WriteTwoModelsWithSharedTexture()
        {
            TestContext.CurrentContext.AttachShowDirLink();
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var tex1Bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AssetsPath, "shannon.png"));
            var tex2Bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AssetsPath, "Texture1.jpg"));

            var tex1 = tex1Bytes.AttachToCurrentTest("shared-shannon.png");
            var tex2 = tex2Bytes.AttachToCurrentTest("subdir\\shared-in-dir-Texture1.jpg");

            // create a material using our shared texture
            var material1 = new MaterialBuilder()
                            .WithUnlitShader()
                            .WithBaseColor(tex1);

            // create a material using our shared texture
            var material2 = new MaterialBuilder()
                            .WithUnlitShader()
                            .WithBaseColor(tex2);

            // create a simple cube mesh
            var mesh1 = new Cube <MaterialBuilder>(material1).ToMesh(Matrix4x4.Identity);
            var mesh2 = new Cube <MaterialBuilder>(material2).ToMesh(Matrix4x4.Identity);
            var scene = new SceneBuilder();

            scene.AddRigidMesh(mesh1, Matrix4x4.CreateTranslation(-2, 0, 0));
            scene.AddRigidMesh(mesh2, Matrix4x4.CreateTranslation(2, 0, 0));

            var gltf = scene.ToGltf2();

            // define the texture sharing hook; this is a pretty naive approach, but it's good
            // enough to demonstrate how it works.

            string imageSharingHook(WriteContext ctx, string uri, Memory.MemoryImage image)
            {
                Assert.IsTrue(new string[] { tex1, tex2 }.Contains(image.SourcePath));

                if (File.Exists(image.SourcePath))
                {
                    // image.SourcePath is an absolute path, we must make it relative to ctx.CurrentDirectory

                    var currDir = ctx.CurrentDirectory.FullName + "\\";

                    // if the shared texture can be reached by the model in its directory, reuse the texture.
                    if (image.SourcePath.StartsWith(currDir, StringComparison.OrdinalIgnoreCase))
                    {
                        // we've found the shared texture!, return the uri relative to the model:
                        return(image.SourcePath.Substring(currDir.Length));
                    }

                    // TODO: Here we could also try to find a texture equivalent to MemoryImage in the
                    // CurrentDirectory even if it has a different name, to minimize texture duplication.
                }

                // we were unable to reuse the shared texture,
                // default to write our own texture.

                image.SaveToFile(Path.Combine(ctx.CurrentDirectory.FullName, uri));

                return(uri);
            }

            var settings = new WriteSettings();

            settings.ImageWriting       = ResourceWriteMode.SatelliteFile;
            settings.ImageWriteCallback = imageSharingHook;

            // save the model several times:

            var path1 = gltf.AttachToCurrentTest("model1.glb", settings);
            var path2 = gltf.AttachToCurrentTest("model2.glb", settings);
            var path3 = gltf.AttachToCurrentTest("model3.gltf", settings);

            var satellites1 = ModelRoot.GetSatellitePaths(path1);
            var satellites2 = ModelRoot.GetSatellitePaths(path2);
            var satellites3 = ModelRoot.GetSatellitePaths(path3);

            Assert.IsTrue(satellites1.Contains("shared-shannon.png"));
            Assert.IsTrue(satellites1.Contains("subdir/shared-in-dir-Texture1.jpg"));

            Assert.IsTrue(satellites2.Contains("shared-shannon.png"));
            Assert.IsTrue(satellites2.Contains("subdir/shared-in-dir-Texture1.jpg"));

            Assert.IsTrue(satellites3.Contains("shared-shannon.png"));
            Assert.IsTrue(satellites3.Contains("subdir/shared-in-dir-Texture1.jpg"));
        }
예제 #14
0
 public override string ConvertToString(object value, WriteSettings settings)
 {
     return(value.ConvertToString().ToLowerInvariant());
 }
예제 #15
0
 public InternalJsonObjectPageMaker(string modelName, WriteSettings settings)
 {
     fModelName = modelName;
     fSettings  = settings ?? ObjectUtil.WriteSettings;
 }
예제 #16
0
 public JsonpObjectPageMaker(string modelName, WriteSettings settings)
     : base(modelName, settings)
 {
 }
예제 #17
0
        async Task <string> ExportGLTF(string path, string payloadString, List <_Geometry> geometries, List <string> objectNames, List <string> materialNames, bool flip, double tolerance, double resolutionFactor, double angleTolerance)
        {
            var tcs = new TaskCompletionSource <string>();
            //comment this whole this is just used for testing
            await Task.Factory.StartNew(() =>
            {
                //Capture the thread
                threadToCancel = Thread.CurrentThread;
                var _model     = SharpGLTF.Schema2.ModelRoot.CreateModel();
                var _scene     = _model.UseScene(0);
                var names      = new List <String>();
                var pointName  = "Point";
                //Console.WriteLine("Task starting for " + geometries.Count);

                for (int j = 0; j < geometries.Count; j++)
                {
                    //Console.WriteLine("Counting geometries " + j);

                    var name = objectNames.Count > j ? objectNames[j] : ("object-" + j);
                    names.Add(name);

                    if (geometries[j] is _Mesh)
                    {
                        _Mesh mesh = geometries[j] as _Mesh;
                        //Console.WriteLine(mesh + " " + j);

                        var materialName = materialNames.Count > j ? materialNames[j] : "Default";

                        if (flip)
                        {
                            for (var n = 0; n < mesh.vertices.Length / 3; n++)
                            {
                                var tmpY = mesh.vertices[n * 3 + 1];
                                mesh.vertices[n * 3 + 1] = mesh.vertices[n * 3 + 2];
                                mesh.vertices[n * 3 + 2] = -tmpY;
                            }
                            for (var n = 0; n < mesh.normals.Length / 3; n++)
                            {
                                var tmpY = mesh.normals[n * 3 + 1];
                                mesh.normals[n * 3 + 1] = mesh.normals[n * 3 + 2];
                                mesh.normals[n * 3 + 2] = -tmpY;
                            }
                        }

                        var _node             = _scene.CreateNode(name);
                        var _mesh             = _model.CreateMesh();
                        var _mat              = _model.CreateMaterial(materialName);
                        var _accessors        = new List <Accessor>();
                        var _bufferComponents = new List <int> {
                            1, 3, 2, 3
                        };
                        var _bufferDimensionTypes = new List <DimensionType> {
                            DimensionType.SCALAR, DimensionType.VEC3, DimensionType.VEC2, DimensionType.VEC3
                        };
                        var _bufferCount = new List <int> {
                            mesh.faces.Length, mesh.vertices.Length / 3, mesh.uvs.Length / 2, mesh.normals.Length / 3
                        };
                        var _numberOfBytes = new List <int> {
                            sizeof(int), sizeof(float), sizeof(float), sizeof(float)
                        };

                        for (var i = 0; i < 4; i++)
                        {
                            var _itemCount = _bufferCount[i];
                            var _accessor  = _model.CreateAccessor();
                            var count      = _itemCount *_numberOfBytes[i] * _bufferComponents[i];
                            var bytes      = new byte[count];
                            switch (i)
                            {
                            case 0: System.Buffer.BlockCopy(mesh.faces, 0, bytes, 0, count); break;

                            case 1: System.Buffer.BlockCopy(mesh.vertices, 0, bytes, 0, count); break;

                            case 2: System.Buffer.BlockCopy(mesh.uvs, 0, bytes, 0, count); break;

                            case 3: System.Buffer.BlockCopy(mesh.normals, 0, bytes, 0, count); break;
                            }
                            BYTES content            = new ArraySegment <byte>(bytes, 0, count);
                            var _bufferView          = _model.UseBufferView(content);
                            var _bufferDimensionType = _bufferDimensionTypes[i];
                            if (i == 0)
                            {
                                _accessor.SetIndexData(_bufferView, 0, _itemCount, IndexEncodingType.UNSIGNED_INT);
                            }
                            else
                            {
                                _accessor.SetVertexData(_bufferView, 0, _itemCount, _bufferDimensionType);
                            }
                            _accessors.Add(_accessor);
                        }

                        var _primitive = _mesh.CreatePrimitive();
                        _primitive.SetIndexAccessor(_accessors[0]);
                        _primitive.SetVertexAccessor("POSITION", _accessors[1]);
                        _primitive.SetVertexAccessor("TEXCOORD_0", _accessors[2]);
                        _primitive.SetVertexAccessor("NORMAL", _accessors[3]);
                        _primitive.DrawPrimitiveType = PrimitiveType.TRIANGLES;
                        _node.Mesh = _mesh;
                        //Console.WriteLine("Constructed mesh " + j);
                    }
                    else if (geometries[j] is _Curve)
                    {
                        var curve = geometries[j] as _Curve;
                        //Console.WriteLine("curve " + j);
                        var materialName = materialNames.Count > j ? materialNames[j] : "Default";

                        var _node             = _scene.CreateNode(name);
                        var _mesh             = _model.CreateMesh();
                        var _mat              = _model.CreateMaterial(materialName);
                        var _accessors        = new List <Accessor>();
                        var _bufferComponents = new List <int> {
                            3
                        };
                        var _bufferDimensionTypes = new List <DimensionType> {
                            DimensionType.VEC3
                        };
                        var _bufferCount = new List <int> {
                            curve.vertices.Length / 3
                        };
                        var _numberOfBytes = new List <int> {
                            sizeof(float)
                        };
                        var _itemCount = _bufferCount[0];
                        var _accessor  = _model.CreateAccessor();
                        var count      = _itemCount *_numberOfBytes[0] * _bufferComponents[0];
                        var bytes      = new byte[count];
                        System.Buffer.BlockCopy(curve.vertices.ToArray(), 0, bytes, 0, count);
                        BYTES content            = new ArraySegment <byte>(bytes, 0, count);
                        var _bufferView          = _model.UseBufferView(content);
                        var _bufferDimensionType = _bufferDimensionTypes[0];
                        _accessor.SetVertexData(_bufferView, 0, _itemCount, _bufferDimensionType);
                        _accessors.Add(_accessor);
                        var _primitive = _mesh.CreatePrimitive();
                        _primitive.SetVertexAccessor("POSITION", _accessors[0]);
                        _primitive.DrawPrimitiveType = curve.isClosed ? PrimitiveType.LINE_LOOP : PrimitiveType.LINE_STRIP;
                        _node.Mesh = _mesh;
                    }
                    else if (geometries[j] is _Points)
                    {
                        var points            = geometries[j] as _Points;
                        var _node             = _scene.CreateNode(pointName);
                        var _mesh             = _model.CreateMesh();
                        var _mat              = _model.CreateMaterial("Point");
                        var _accessors        = new List <Accessor>();
                        var _bufferComponents = new List <int> {
                            3
                        };
                        var _bufferDimensionTypes = new List <DimensionType> {
                            DimensionType.VEC3
                        };
                        var _bufferCount = new List <int> {
                            points.vertices.Length / 3
                        };
                        var _numberOfBytes = new List <int> {
                            sizeof(float)
                        };
                        var _itemCount = _bufferCount[0];
                        var _accessor  = _model.CreateAccessor();
                        var count      = _itemCount *_numberOfBytes[0] * _bufferComponents[0];
                        var bytes      = new byte[count];
                        System.Buffer.BlockCopy(points.vertices, 0, bytes, 0, count);
                        BYTES content            = new ArraySegment <byte>(bytes, 0, count);
                        var _bufferView          = _model.UseBufferView(content);
                        var _bufferDimensionType = _bufferDimensionTypes[0];
                        _accessor.SetVertexData(_bufferView, 0, _itemCount, _bufferDimensionType);
                        _accessors.Add(_accessor);
                        var _primitive = _mesh.CreatePrimitive();
                        _primitive.SetVertexAccessor("POSITION", _accessors[0]);
                        _primitive.DrawPrimitiveType = PrimitiveType.POINTS;
                        _node.Mesh = _mesh;
                    }
                }

                var _writeSetting          = new WriteSettings();
                _writeSetting.MergeBuffers = true;
                //Console.WriteLine("writing to stream " + path);

                using (var stream = File.Create(path))
                {
                    _model.WriteGLB(stream, _writeSetting);
                }

                if (socket != null)
                {
                    if (payloadString == null)
                    {
                        payloadString = String.Format("{{\"action\":\"broadcast\",\"data\": \"{0}\"}}", path);
                    }
                    socket.Send(payloadString);
                }
                //Console.WriteLine("Task finished!");
            });

            //return "done";
            tcs.SetResult("Completed");
            return(tcs.Task.Result);
        }
예제 #18
0
 public XmlObjectPageMaker(WriteSettings settings, QName root)
 {
     fSettings = settings ?? ObjectUtil.WriteSettings;
     fRoot = root ?? QName.Get(ToolkitConst.TOOLKIT);
 }