예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="VertexInfo"></param>
        /// <param name="VertexType"></param>
        private void PutVertex(ref VertexInfo VertexInfo, ref VertexTypeStruct VertexType)
        {
            /*
             * if (GpuState->ClearingMode)
             * {
             *      Console.WriteLine(VertexInfo);
             * }
             */
            //Console.WriteLine(VertexInfo);

            //Console.WriteLine(VertexInfo);
            //Console.WriteLine(VertexInfo);
            if (VertexType.Color != VertexTypeStruct.ColorEnum.Void)
            {
                GL.Color4((float)VertexInfo.R, (float)VertexInfo.G, (float)VertexInfo.B, (float)VertexInfo.A);
            }
            if (VertexType.Texture != VertexTypeStruct.NumericEnum.Void)
            {
                //Console.WriteLine("{0}, {1}", VertexInfo.U, VertexInfo.V);
                GL.TexCoord2(VertexInfo.U, VertexInfo.V);
            }
            if (VertexType.Normal != VertexTypeStruct.NumericEnum.Void)
            {
                GL.Normal3(VertexInfo.NX, VertexInfo.NY, VertexInfo.NZ);
            }
            if (VertexType.Position != VertexTypeStruct.NumericEnum.Void)
            {
                GL.Vertex3(VertexInfo.PX, VertexInfo.PY, VertexInfo.PZ);
            }
        }
예제 #2
0
        public void SetVertexTypeStruct(VertexTypeStruct vertexType, byte *basePointer)
        {
            VertexType  = vertexType;
            Transform2D = vertexType.Transform2D;

            //Console.Error.WriteLine("SetVertexTypeStruct: " + VertexTypeStruct);
            SkinningWeightCount = vertexType.RealSkinningWeightCount;
            //Console.WriteLine(SkinningWeightCount);
            VertexSize = vertexType.GetVertexSize();
            {
                ReadWeights            = ReadWeightsList[(int)vertexType.Weight];
                ReadTextureCoordinates = ReadTextureCoordinatesList[(int)vertexType.Texture];
                ReadColor    = ReadColorList[(int)vertexType.Color];
                ReadNormal   = ReadNormalList[(int)vertexType.Normal];
                ReadPosition = ReadPositionList[(int)vertexType.Position];

                VertexAlignment = vertexType.StructAlignment switch
                {
                    4 => (Action)Align4,
                    2 => (Action)Align2,
                    _ => (Action)Align1
                };
            }
            //public VertexTypeStruct VertexTypeStruct;
            BasePointer   = basePointer;
            PointerOffset = 0;
        }
예제 #3
0
 private void _CapturePrimitive(GuPrimitiveType primitiveType, uint vertexAddress, int vetexCount,
                                ref VertexTypeStruct vertexType, Action action)
 {
     if (_pspWavefrontObjWriter != null)
     {
         lock (PspWavefrontObjWriterLock)
             _pspWavefrontObjWriter.StartPrimitive(GpuState, primitiveType, vertexAddress, vetexCount,
                                                   ref vertexType);
         try
         {
             action();
         }
         finally
         {
             lock (PspWavefrontObjWriterLock) _pspWavefrontObjWriter.EndPrimitive();
         }
     }
     else
     {
         action();
     }
 }
예제 #4
0
        public void SetVertexTypeStruct(VertexTypeStruct VertexTypeStruct, byte *BasePointer)
        {
            SkinningWeightCount = VertexTypeStruct.SkinningWeightCount;
            //Console.WriteLine(SkinningWeightCount);
            VertexSize = VertexTypeStruct.GetVertexSize();
            {
                ReadWeights            = ReadWeightsList[(int)VertexTypeStruct.Weight];
                ReadTextureCoordinates = ReadTextureCoordinatesList[(int)VertexTypeStruct.Texture];
                ReadColor    = ReadColorList[(int)VertexTypeStruct.Color];
                ReadNormal   = ReadNormalList[(int)VertexTypeStruct.Normal];
                ReadPosition = ReadPositionList[(int)VertexTypeStruct.Position];
                switch (VertexAlignSize)
                {
                case 4: VertexAlignment = Align4; break;

                case 2: VertexAlignment = Align2; break;

                default: VertexAlignment = Align1; break;
                }
            }
            //public VertexTypeStruct VertexTypeStruct;
            this.BasePointer = BasePointer;
        }
예제 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="GpuState"></param>
        override public unsafe void Prim(GpuStateStruct *GpuState, PrimitiveType PrimitiveType, ushort VertexCount)
        {
            this.GpuState = GpuState;

            if (!IsCurrentWindow)
            {
                IsCurrentWindow = true;
                GraphicsContext.MakeCurrent(NativeWindow.WindowInfo);
            }

            //Console.WriteLine("--------------------------------------------------------");
            VertexType = GpuState->VertexState.Type;

            VertexReader.SetVertexTypeStruct(VertexType, (byte *)Memory.PspAddressToPointerSafe(GpuState->VertexAddress));
            //IndexReader.SetVertexTypeStruct(VertexType, VertexCount, (byte*)Memory.PspAddressToPointerSafe(GpuState->IndexAddress));

            int TotalVerticesWithoutMorphing = VertexCount;

            void *IndexAddress = Memory.PspAddressToPointerSafe(GpuState->IndexAddress);

            switch (VertexType.Index)
            {
            case VertexTypeStruct.IndexEnum.Void:
                break;

            case VertexTypeStruct.IndexEnum.Byte:
                Marshal.Copy(new IntPtr(IndexAddress), IndexListByte, 0, VertexCount);
                TotalVerticesWithoutMorphing = IndexListByte.Take(VertexCount).Max() + 1;
                break;

            case VertexTypeStruct.IndexEnum.Short:
                Marshal.Copy(new IntPtr(IndexAddress), IndexListShort, 0, VertexCount);
                TotalVerticesWithoutMorphing = IndexListShort.Take(VertexCount).Max() + 1;
                break;

            default:
                throw (new NotImplementedException());
            }

            //Console.WriteLine(TotalVerticesWithoutMorphing);

            int        MorpingVertexCount = (int)VertexType.MorphingVertexCount + 1;
            int        z = 0;
            VertexInfo TempVertexInfo;

            float *Morphs = &GpuState->MorphingState.MorphWeight0;

            //for (int n = 0; n < MorpingVertexCount; n++) Console.Write("{0}, ", Morphs[n]); Console.WriteLine("");

            fixed(VertexInfo *VerticesPtr = Vertices)
            {
                for (int n = 0; n < TotalVerticesWithoutMorphing; n++)
                {
                    //Console.WriteLine(MorpingVertexCount);
                    if (MorpingVertexCount == 1)
                    {
                        VertexReader.ReadVertex(z++, &TempVertexInfo);
                        //Console.WriteLine(TempVertexInfo);
                        VerticesPtr[n] = TempVertexInfo;
                    }
                    else
                    {
                        var ComponentsIn  = (float *)&TempVertexInfo;
                        var ComponentsOut = (float *)&VerticesPtr[n];
                        for (int cc = 0; cc < 20; cc++)
                        {
                            ComponentsOut[cc] = 0;
                        }
                        for (int m = 0; m < MorpingVertexCount; m++)
                        {
                            VertexReader.ReadVertex(z++, &TempVertexInfo);
                            for (int cc = 0; cc < 20; cc++)
                            {
                                ComponentsOut[cc] += ComponentsIn[cc] * Morphs[m];
                            }
                        }
                    }
                }
            }

            //VertexType.Texture == VertexTypeStruct.TextureEnum.Byte
            //return;
            //PrepareRead(GpuState);

            if (GpuState->ClearingMode)
            {
                //return;
                //GL.ClearColor(1, 1, 0, 0);

                // @TODO: Fake

                /*
                 */
                //PrepareState(GpuState);
                //return;
                //Console.WriteLine(VertexCount);
                drawBeginClear(GpuState);

                /*
                 * GL.ClearColor(0, 0, 0, 1);
                 * GL.ClearDepth(0);
                 * GL.ClearStencil(0);
                 * GL.ClearAccum(0, 0, 0, 0);
                 * GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit | ClearBufferMask.AccumBufferBit);
                 * return;
                 */
            }
            else
            {
                PrepareState(GpuState);
            }

            // DRAW BEGIN COMMON
            {
                if (GpuState->VertexState.Type.Transform2D)
                {
                    GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
                    GL.Ortho(0, 512, 272, 0, -0x7FFF, +0x7FFF);
                    GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
                }
                else
                {
                    GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
                    GL.MultMatrix(GpuState->VertexState.ProjectionMatrix.Values);

                    GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
                    GL.MultMatrix(GpuState->VertexState.ViewMatrix.Values);
                    GL.MultMatrix(GpuState->VertexState.WorldMatrix.Values);

                    if (GpuState->VertexState.WorldMatrix.Values[0] == float.NaN)
                    {
                        throw (new Exception("Invalid WorldMatrix"));
                    }

                    //GpuState->VertexState.ViewMatrix.Dump();
                    //GpuState->VertexState.WorldMatrix.Dump();

                    //Console.WriteLine("NO Transform2D");
                }
            }

            // DRAW ACTUALLY
            {
                uint VertexSize = GpuState->VertexState.Type.GetVertexSize();

                byte *VertexPtr = (byte *)Memory.PspAddressToPointerSafe(GpuState->VertexAddress);

                //Console.WriteLine(VertexSize);

                var BeginMode = default(BeginMode);

                switch (PrimitiveType)
                {
                case PrimitiveType.Lines: BeginMode = BeginMode.Lines; break;

                case PrimitiveType.LineStrip: BeginMode = BeginMode.LineStrip; break;

                case PrimitiveType.Triangles: BeginMode = BeginMode.Triangles; break;

                case PrimitiveType.Points: BeginMode = BeginMode.Points; break;

                case PrimitiveType.TriangleFan: BeginMode = BeginMode.TriangleFan; break;

                case PrimitiveType.TriangleStrip: BeginMode = BeginMode.TriangleStrip; break;

                case PrimitiveType.Sprites: BeginMode = BeginMode.Quads; break;

                default: throw (new NotImplementedException("Not implemented PrimitiveType:'" + PrimitiveType + "'"));
                }

                //Console.WriteLine(BeginMode);

                GL.Begin(BeginMode);
                {
                    if (PrimitiveType == PrimitiveType.Sprites)
                    {
                        GL.Disable(EnableCap.CullFace);
                        for (int n = 0; n < VertexCount; n += 2)
                        {
                            VertexInfo VertexInfoTopLeft;
                            VertexInfo VertexInfoTopRight;
                            VertexInfo VertexInfoBottomRight;
                            VertexInfo VertexInfoBottomLeft;
                            ReadVertex(n + 0, &VertexInfoTopLeft);
                            ReadVertex(n + 1, &VertexInfoBottomRight);

                            //if (GpuState->ClearingMode) Console.WriteLine("{0} - {1}", VertexInfoTopLeft, VertexInfoBottomRight);

                            float R = VertexInfoBottomRight.R, G = VertexInfoBottomRight.G, B = VertexInfoBottomRight.B, A = VertexInfoBottomRight.A;
                            float PZ = VertexInfoTopLeft.PZ;
                            float NZ = VertexInfoTopLeft.NZ;

                            VertexInfoTopRight = new VertexInfo()
                            {
                                U  = VertexInfoBottomRight.U,
                                V  = VertexInfoTopLeft.V,
                                PX = VertexInfoBottomRight.PX,
                                PY = VertexInfoTopLeft.PY,
                                NX = VertexInfoBottomRight.NX,
                                NY = VertexInfoTopLeft.NY,
                            };

                            VertexInfoBottomLeft = new VertexInfo()
                            {
                                U  = VertexInfoTopLeft.U,
                                V  = VertexInfoBottomRight.V,
                                PX = VertexInfoTopLeft.PX,
                                PY = VertexInfoBottomRight.PY,
                                NX = VertexInfoTopLeft.NX,
                                NY = VertexInfoBottomRight.NY,
                            };

                            VertexInfoBottomLeft.R  = VertexInfoBottomRight.R = VertexInfoTopRight.R = VertexInfoTopLeft.R = R;
                            VertexInfoBottomLeft.G  = VertexInfoBottomRight.G = VertexInfoTopRight.G = VertexInfoTopLeft.G = G;
                            VertexInfoBottomLeft.B  = VertexInfoBottomRight.B = VertexInfoTopRight.B = VertexInfoTopLeft.B = B;
                            VertexInfoBottomLeft.A  = VertexInfoBottomRight.A = VertexInfoTopRight.A = VertexInfoTopLeft.A = R;
                            VertexInfoBottomLeft.PZ = VertexInfoBottomRight.PZ = VertexInfoTopRight.PZ = VertexInfoTopLeft.PZ = PZ;
                            VertexInfoBottomLeft.NZ = VertexInfoBottomRight.NZ = VertexInfoTopRight.NZ = VertexInfoTopLeft.NZ = NZ;

                            PutVertex(ref VertexInfoTopLeft, ref VertexType);
                            PutVertex(ref VertexInfoTopRight, ref VertexType);
                            PutVertex(ref VertexInfoBottomRight, ref VertexType);
                            PutVertex(ref VertexInfoBottomLeft, ref VertexType);
                        }
                    }
                    else
                    {
                        for (int n = 0; n < VertexCount; n++)
                        {
                            VertexInfo VertexInfo;
                            ReadVertex(n, &VertexInfo);
                            PutVertex(ref VertexInfo, ref VertexType);
                        }
                    }
                }
                GL.End();
                GL.Flush();
            }
            //Console.WriteLine(VertexCount);

            //PrepareWrite(GpuState);
        }
예제 #6
0
        /// <summary>
        /// </summary>
        /// <param name="vertexCount"></param>
        public override void Prim(ushort vertexCount)
        {
            VertexType = GpuState->VertexState.Type;

            if (_doPrimStart || (VertexType != _cachedVertexType))
            {
                _cachedVertexType = VertexType;
                _doPrimStart      = false;

                OpenglGpuImplCommon.PrepareStateCommon(GpuState, ScaleViewport);

                if (GpuState->ClearingMode)
                {
                    OpenglGpuImplClear.PrepareStateClear(GpuState);
                }
                else
                {
                    PrepareStateDraw(GpuState);
                }

                OpenglGpuImplMatrix.PrepareStateMatrix(GpuState, out _worldViewProjectionMatrix);
                PrepareDrawStateFirst();
            }

            var morpingVertexCount = VertexType.MorphingVertexCount + 1;

            //if (PrimitiveType == GuPrimitiveType.TriangleStrip) VertexCount++;

            // ReSharper disable once RedundantAssignment (Resharper BUG)
            ReadVertexDelegate readVertex = ReadVertex_Void;

            VertexReader.SetVertexTypeStruct(
                VertexType,
                (byte *)Memory.PspAddressToPointerSafe(
                    GpuState->GetAddressRelativeToBaseOffset(GpuState->VertexAddress), 0)
                );

            // Fix missing geometry! At least!
            if (VertexType.Index == VertexTypeStruct.IndexEnum.Void)
            {
                GpuState->VertexAddress += (uint)(VertexReader.VertexSize * vertexCount * morpingVertexCount);
                //GpuState->VertexAddress += (uint)(VertexReader.VertexSize * VertexCount);
            }

            if (morpingVertexCount != 1 || VertexType.RealSkinningWeightCount != 0)
            {
                //Console.WriteLine("PRIM: {0}, {1}, Morphing:{2}, Skinning:{3}", PrimitiveType, VertexCount, MorpingVertexCount, VertexType.RealSkinningWeightCount);
            }

            uint totalVerticesWithoutMorphing = vertexCount;

            void *indexPointer = null;

            if (VertexType.Index != VertexTypeStruct.IndexEnum.Void)
            {
                indexPointer =
                    Memory.PspAddressToPointerSafe(GpuState->GetAddressRelativeToBaseOffset(GpuState->IndexAddress), 0);
            }

            //Console.Error.WriteLine(VertexType.Index);
            switch (VertexType.Index)
            {
            case VertexTypeStruct.IndexEnum.Void:
                break;

            case VertexTypeStruct.IndexEnum.Byte:
                readVertex    = ReadVertex_Byte;
                indexListByte = (byte *)indexPointer;
                totalVerticesWithoutMorphing = 0;
                for (int n = 0; n < vertexCount; n++)
                {
                    if (totalVerticesWithoutMorphing < indexListByte[n])
                    {
                        totalVerticesWithoutMorphing = indexListByte[n];
                    }
                }
                break;

            case VertexTypeStruct.IndexEnum.Short:
                readVertex     = ReadVertex_Short;
                indexListShort = (ushort *)indexPointer;
                totalVerticesWithoutMorphing = 0;
                //VertexCount--;
                for (int n = 0; n < vertexCount; n++)
                {
                    //Console.Error.WriteLine(IndexListShort[n]);
                    if (totalVerticesWithoutMorphing < indexListShort[n])
                    {
                        totalVerticesWithoutMorphing = indexListShort[n];
                    }
                }
                break;

            default:
                throw (new NotImplementedException("VertexType.Index: " + VertexType.Index));
            }
            totalVerticesWithoutMorphing++;


            //Console.WriteLine(TotalVerticesWithoutMorphing);

            var z = 0;

            //for (int n = 0; n < MorpingVertexCount; n++) Console.Write("{0}, ", Morphs[n]); Console.WriteLine("");

            //int VertexInfoFloatCount = (sizeof(Color4F) + sizeof(Vector3F) * 3) / sizeof(float);
            var vertexInfoFloatCount = (sizeof(VertexInfo)) / sizeof(float);

            fixed(VertexInfo *verticesPtr = Vertices)
            {
                if (morpingVertexCount == 1)
                {
                    VertexReader.ReadVertices(0, verticesPtr, (int)totalVerticesWithoutMorphing);
                }
                else
                {
                    VertexInfo tempVertexInfo;
                    var        componentsIn = (float *)&tempVertexInfo;
                    for (var n = 0; n < totalVerticesWithoutMorphing; n++)
                    {
                        var componentsOut = (float *)&verticesPtr[n];
                        for (var cc = 0; cc < vertexInfoFloatCount; cc++)
                        {
                            componentsOut[cc] = 0;
                        }
                        for (var m = 0; m < morpingVertexCount; m++)
                        {
                            VertexReader.ReadVertex(z++, &tempVertexInfo);
                            for (int cc = 0; cc < vertexInfoFloatCount; cc++)
                            {
                                componentsOut[cc] += componentsIn[cc] * GpuState->MorphingState.MorphWeight[m];
                            }
                        }
                        verticesPtr[n].Normal = verticesPtr[n].Normal.Normalize();
                    }
                }
            }

            _CapturePrimitive(_primitiveType, GpuState->GetAddressRelativeToBaseOffset(GpuState->VertexAddress),
                              vertexCount, ref VertexType, () =>
            {
                // Continuation
                if (_indicesList.Length > 0)
                {
                    switch (_primitiveType)
                    {
                    // Degenerate.
                    case GuPrimitiveType.TriangleStrip:
                    case GuPrimitiveType.Sprites:
                        if (vertexCount > 0)
                        {
                            PutVertexIndexRelative(-1);
                            PutVertexIndexRelative(0);
                        }
                        break;

                    // Can't degenerate, flush.
                    default:
                        EndVertex();
                        break;
                    }
                }

                if (_primitiveType == GuPrimitiveType.Sprites)
                {
                    GL.glDisable(GL.GL_CULL_FACE);
                    for (int n = 0; n < vertexCount; n += 2)
                    {
                        VertexInfo v0, v1, v2, v3;

                        readVertex(n + 0, out v0);
                        readVertex(n + 1, out v3);

                        VertexUtils.GenerateTriangleStripFromSpriteVertices(ref v0, out v1, out v2, ref v3);

                        if (n > 0)
                        {
                            PutVertexIndexRelative(-1);
                            PutVertexIndexRelative(0);
                        }

                        PutVertices(v0, v1, v2, v3);
                    }
                }
                else
                {
                    VertexInfo VertexInfo;
                    //Console.Error.WriteLine("{0} : {1} : {2}", BeginMode, VertexCount, VertexType.Index);
                    for (int n = 0; n < vertexCount; n++)
                    {
                        readVertex(n, out VertexInfo);
                        PutVertex(VertexInfo);
                    }
                }
            });
        }
예제 #7
0
        /// <summary>
        /// </summary>
        /// <param name="vertexCount"></param>
        public override void Prim(ushort vertexCount)
        {
            VertexType = GpuState.VertexState.Type;

            if (_doPrimStart || (VertexType != _cachedVertexType))
            {
                _cachedVertexType = VertexType;
                _doPrimStart      = false;

                OpenglGpuImplCommon.PrepareStateCommon(GpuState, ScaleViewport);

                if (GpuState.ClearingMode)
                {
                    OpenglGpuImplClear.PrepareStateClear(GpuState);
                }
                else
                {
                    PrepareStateDraw(GpuState);
                }

                OpenglGpuImplMatrix.PrepareStateMatrix(GpuState, out _worldViewProjectionMatrix);
                PrepareDrawStateFirst();
            }

            //if (PrimitiveType == GuPrimitiveType.TriangleStrip) VertexCount++;

            uint morpingVertexCount, totalVerticesWithoutMorphing;

            PreparePrim(GpuState, out totalVerticesWithoutMorphing, vertexCount, out morpingVertexCount);

            var z = 0;

            //for (int n = 0; n < MorpingVertexCount; n++) Console.Write("{0}, ", Morphs[n]); Console.WriteLine("");

            //int VertexInfoFloatCount = (sizeof(Color4F) + sizeof(Vector3F) * 3) / sizeof(float);
            var vertexInfoFloatCount = (sizeof(VertexInfo)) / sizeof(float);

            fixed(VertexInfo *verticesPtr = Vertices)
            {
                if (morpingVertexCount == 1)
                {
                    VertexReader.ReadVertices(0, verticesPtr, (int)totalVerticesWithoutMorphing);
                }
                else
                {
                    VertexInfo tempVertexInfo;
                    var        componentsIn = (float *)&tempVertexInfo;
                    for (var n = 0; n < totalVerticesWithoutMorphing; n++)
                    {
                        var componentsOut = (float *)&verticesPtr[n];
                        for (var cc = 0; cc < vertexInfoFloatCount; cc++)
                        {
                            componentsOut[cc] = 0;
                        }
                        for (var m = 0; m < morpingVertexCount; m++)
                        {
                            VertexReader.ReadVertex(z++, &tempVertexInfo);
                            for (var cc = 0; cc < vertexInfoFloatCount; cc++)
                            {
                                componentsOut[cc] += componentsIn[cc] * GpuState.MorphingState.MorphWeight(m);
                            }
                        }
                        verticesPtr[n].Normal = verticesPtr[n].Normal.Normalize();
                    }
                }
            }

            _CapturePrimitive(_primitiveType, GpuState.GetAddressRelativeToBaseOffset(GpuState.VertexAddress),
                              vertexCount, ref VertexType, () =>
            {
                // Continuation
                if (_indicesList.Length > 0)
                {
                    switch (_primitiveType)
                    {
                    // Degenerate.
                    case GuPrimitiveType.TriangleStrip:
                    case GuPrimitiveType.Sprites:
                        if (vertexCount > 0)
                        {
                            PutVertexIndexRelative(-1);
                            PutVertexIndexRelative(0);
                        }
                        break;

                    // Can't degenerate, flush.
                    default:
                        EndVertex();
                        break;
                    }
                }

                if (_primitiveType == GuPrimitiveType.Sprites)
                {
                    GL.glDisable(GL.GL_CULL_FACE);
                    for (var n = 0; n < vertexCount; n += 2)
                    {
                        VertexInfo v0, v1, v2, v3;

                        readVertex(n + 0, out v0);
                        readVertex(n + 1, out v3);

                        VertexUtils.GenerateTriangleStripFromSpriteVertices(ref v0, out v1, out v2, ref v3);

                        if (n > 0)
                        {
                            PutVertexIndexRelative(-1);
                            PutVertexIndexRelative(0);
                        }

                        PutVertices(v0, v1, v2, v3);
                    }
                }
                else
                {
                    VertexInfo VertexInfo;
                    //Console.Error.WriteLine("{0} : {1} : {2}", BeginMode, VertexCount, VertexType.Index);
                    for (var n = 0; n < vertexCount; n++)
                    {
                        readVertex(n, out VertexInfo);
                        PutVertex(VertexInfo);
                    }
                }
            });
        }