/// <summary>Searches for the specified RssChannel and returns the zero-based index of the first occurrence within the entire RssChannelCollection.</summary>
 /// <param name="rssChannel">The RssChannel to locate in the RssChannelCollection.</param>
 /// <returns>The zero-based index of the first occurrence of RssChannel within the entire RssChannelCollection, if found; otherwise, -1.</returns>
 public int IndexOf(RssChannel rssChannel)
 {
     return List.IndexOf(rssChannel);
 }
 /// <summary>Inserts a channel into this collection at a specified index.</summary>
 /// <param name="index">The zero-based index of the collection at which to insert the channel.</param>
 /// <param name="channel">The channel to insert into this collection.</param>
 public void Insert(int index, RssChannel channel)
 {
     List.Insert(index, channel);
 }
 /// <summary>Determines whether the RssChannelCollection contains a specific element.</summary>
 /// <param name="rssChannel">The RssChannel to locate in the RssChannelCollection.</param>
 /// <returns>true if the RssChannelCollection contains the specified value; otherwise, false.</returns>
 public bool Contains(RssChannel rssChannel)
 {
     return List.Contains(rssChannel);
 }
 /// <summary>Copies the entire RssChannelCollection to a compatible one-dimensional <see cref="Array"/>, starting at the specified index of the target array.</summary>
 /// <param name="array">The one-dimensional RssChannel Array that is the destination of the elements copied from RssChannelCollection. The Array must have zero-based indexing.</param>
 /// <param name="index">The zero-based index in array at which copying begins.</param>
 /// <exception cref="ArgumentNullException">array is a null reference (Nothing in Visual Basic).</exception>
 /// <exception cref="ArgumentOutOfRangeException">index is less than zero.</exception>
 /// <exception cref="ArgumentException">array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssChannelCollection is greater than the available space from index to the end of the destination array.</exception>
 public void CopyTo(RssChannel[] array, int index)
 {
     List.CopyTo(array, index);
 }
 /// <summary>Removes a specified channel from this collection.</summary>
 /// <param name="channel">The channel to remove.</param>
 public void Remove(RssChannel channel)
 {
     List.Remove(channel);
 }
 /// <summary>Adds a specified channel to this collection.</summary>
 /// <param name="channel">The channel to add.</param>
 /// <returns>The zero-based index of the added channel.</returns>
 public int Add(RssChannel channel)
 {
     return List.Add(channel);
 }
Exemplo n.º 7
0
        /// <summary>Reads the next RssElement from the stream.</summary>
        /// <returns>An RSS Element</returns>
        /// <exception cref="InvalidOperationException">RssReader has been closed, and can not be read.</exception>
        /// <exception cref="System.IO.FileNotFoundException">RSS file not found.</exception>
        /// <exception cref="System.Xml.XmlException">Invalid XML syntax in RSS file.</exception>
        /// <exception cref="System.IO.EndOfStreamException">Unable to read an RssElement. Reached the end of the stream.</exception>
        public RssElement Read()
        {
            var readData = false;
            bool pushElement;
            RssElement rssElement = null;
            var lineNumber = -1;
            var linePosition = -1;

            if (reader == null)
                throw new InvalidOperationException("RssReader has been closed, and can not be read.");

            do
            {
                pushElement = true;
                try
                {
                    readData = reader.Read();
                }
                catch (EndOfStreamException e)
                {
                    throw new EndOfStreamException("Unable to read an RssElement. Reached the end of the stream.", e);
                }
                catch (XmlException e)
                {
                    if (lineNumber != -1 || linePosition != -1)
                        if (reader.LineNumber == lineNumber && reader.LinePosition == linePosition)
                            throw exceptions.LastException;

                    lineNumber = reader.LineNumber;
                    linePosition = reader.LinePosition;

                    exceptions.Add(e); // just add to list of exceptions and continue :)
                }
                if (readData)
                {
                    var readerName = reader.Name.ToLower();
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            {
                                if (reader.IsEmptyElement)
                                    break;
                                elementText = new StringBuilder();

                                switch (readerName)
                                {
                                    case "item":
                                        // is this the end of the channel element? (absence of </channel> before <item>)
                                        if (!wroteChannel)
                                        {
                                            wroteChannel = true;
                                            rssElement = channel; // return RssChannel
                                            readData = false;
                                        }
                                        item = new RssItem(); // create new RssItem
                                        channel.Items.Add(item);
                                        break;
                                    case "source":
                                        source = new RssSource();
                                        item.Source = source;
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            switch (reader.Name.ToLower())
                                            {
                                                case "url":
                                                    try
                                                    {
                                                        source.Url = new Uri(reader.Value);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                    break;
                                            }
                                        }
                                        break;
                                    case "enclosure":
                                        enclosure = new RssEnclosure();
                                        item.Enclosure = enclosure;
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            switch (reader.Name.ToLower())
                                            {
                                                case "url":
                                                    try
                                                    {
                                                        enclosure.Url = new Uri(reader.Value);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                    break;
                                                case "length":
                                                    try
                                                    {
                                                        enclosure.Length = int.Parse(reader.Value);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                    break;
                                                case "type":
                                                    enclosure.Type = reader.Value;
                                                    break;
                                            }
                                        }
                                        break;
                                    case "guid":
                                        guid = new RssGuid();
                                        item.Guid = guid;
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            switch (reader.Name.ToLower())
                                            {
                                                case "ispermalink":
                                                    try
                                                    {
                                                        guid.PermaLink = bool.Parse(reader.Value);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                    break;
                                            }
                                        }
                                        break;
                                    case "category":
                                        category = new RssCategory();
                                        if ((string) xmlNodeStack.Peek() == "channel")
                                            channel.Categories.Add(category);
                                        else
                                            item.Categories.Add(category);
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            switch (reader.Name.ToLower())
                                            {
                                                case "url":
                                                    goto case "domain";
                                                case "domain":
                                                    category.Domain = reader.Value;
                                                    break;
                                            }
                                        }
                                        break;
                                    case "channel":
                                        channel = new RssChannel();
                                        textInput = null;
                                        image = null;
                                        cloud = null;
                                        source = null;
                                        enclosure = null;
                                        category = null;
                                        item = null;
                                        break;
                                    case "image":
                                        image = new RssImage();
                                        channel.Image = image;
                                        break;
                                    case "textinput":
                                        textInput = new RssTextInput();
                                        channel.TextInput = textInput;
                                        break;
                                    case "cloud":
                                        pushElement = false;
                                        cloud = new RssCloud();
                                        channel.Cloud = cloud;
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            switch (reader.Name.ToLower())
                                            {
                                                case "domain":
                                                    cloud.Domain = reader.Value;
                                                    break;
                                                case "port":
                                                    try
                                                    {
                                                        cloud.Port = ushort.Parse(reader.Value);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                    break;
                                                case "path":
                                                    cloud.Path = reader.Value;
                                                    break;
                                                case "registerprocedure":
                                                    cloud.RegisterProcedure = reader.Value;
                                                    break;
                                                case "protocol":
                                                    switch (reader.Value.ToLower())
                                                    {
                                                        case "xml-rpc":
                                                            cloud.Protocol = RssCloudProtocol.XmlRpc;
                                                            break;
                                                        case "soap":
                                                            cloud.Protocol = RssCloudProtocol.Soap;
                                                            break;
                                                        case "http-post":
                                                            cloud.Protocol = RssCloudProtocol.HttpPost;
                                                            break;
                                                        default:
                                                            cloud.Protocol = RssCloudProtocol.Empty;
                                                            break;
                                                    }
                                                    break;
                                            }
                                        }
                                        break;
                                    case "rss":
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            if (reader.Name.ToLower() == "version")
                                                switch (reader.Value)
                                                {
                                                    case "0.91":
                                                        rssVersion = RssVersion.RSS091;
                                                        break;
                                                    case "0.92":
                                                        rssVersion = RssVersion.RSS092;
                                                        break;
                                                    case "2.0":
                                                        rssVersion = RssVersion.RSS20;
                                                        break;
                                                    default:
                                                        rssVersion = RssVersion.NotSupported;
                                                        break;
                                                }
                                        }
                                        break;
                                    case "rdf":
                                        for (var i = 0; i < reader.AttributeCount; i++)
                                        {
                                            reader.MoveToAttribute(i);
                                            if (reader.Name.ToLower() == "version")
                                                switch (reader.Value)
                                                {
                                                    case "0.90":
                                                        rssVersion = RssVersion.RSS090;
                                                        break;
                                                    case "1.0":
                                                        rssVersion = RssVersion.RSS10;
                                                        break;
                                                    default:
                                                        rssVersion = RssVersion.NotSupported;
                                                        break;
                                                }
                                        }
                                        break;
                                }
                                if (pushElement)
                                    xmlNodeStack.Push(readerName);
                                break;
                            }
                        case XmlNodeType.EndElement:
                            {
                                if (xmlNodeStack.Count == 1)
                                    break;
                                var childElementName = (string) xmlNodeStack.Pop();
                                var parentElementName = (string) xmlNodeStack.Peek();
                                switch (childElementName) // current element
                                {
                                        // item classes
                                    case "item":
                                        rssElement = item;
                                        readData = false;
                                        break;
                                    case "source":
                                        source.Name = elementText.ToString();
                                        rssElement = source;
                                        readData = false;
                                        break;
                                    case "enclosure":
                                        rssElement = enclosure;
                                        readData = false;
                                        break;
                                    case "guid":
                                        guid.Name = elementText.ToString();
                                        rssElement = guid;
                                        readData = false;
                                        break;
                                    case "category": // parent is either item or channel
                                        category.Name = elementText.ToString();
                                        rssElement = category;
                                        readData = false;
                                        break;
                                        // channel classes
                                    case "channel":
                                        if (wroteChannel)
                                            wroteChannel = false;
                                        else
                                        {
                                            wroteChannel = true;
                                            rssElement = channel;
                                            readData = false;
                                        }
                                        break;
                                    case "textinput":
                                        rssElement = textInput;
                                        readData = false;
                                        break;
                                    case "image":
                                        rssElement = image;
                                        readData = false;
                                        break;
                                    case "cloud":
                                        rssElement = cloud;
                                        readData = false;
                                        break;
                                }
                                switch (parentElementName) // parent element
                                {
                                    case "item":
                                        switch (childElementName)
                                        {
                                            case "title":
                                                item.Title = elementText.ToString();
                                                break;
                                            case "link":
                                                item.Link = new Uri(elementText.ToString());
                                                break;
                                            case "description":
                                                item.Description = elementText.ToString();
                                                break;
                                            case "author":
                                                item.Author = elementText.ToString();
                                                break;
                                            case "comments":
                                                item.Comments = elementText.ToString();
                                                break;
                                            case "pubdate":
                                                try
                                                {
                                                    item.PubDate = DateTime.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    try
                                                    {
                                                        var tmp = elementText.ToString();
                                                        tmp = tmp.Substring(0, tmp.Length - 5);
                                                        tmp += "GMT";
                                                        item.PubDate = DateTime.Parse(tmp);
                                                    }
                                                    catch
                                                    {
                                                        exceptions.Add(e);
                                                    }
                                                }
                                                break;
                                        }
                                        break;
                                    case "channel":
                                        switch (childElementName)
                                        {
                                            case "title":
                                                channel.Title = elementText.ToString();
                                                break;
                                            case "link":
                                                try
                                                {
                                                    channel.Link = new Uri(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "description":
                                                channel.Description = elementText.ToString();
                                                break;
                                            case "language":
                                                channel.Language = elementText.ToString();
                                                break;
                                            case "copyright":
                                                channel.Copyright = elementText.ToString();
                                                break;
                                            case "managingeditor":
                                                channel.ManagingEditor = elementText.ToString();
                                                break;
                                            case "webmaster":
                                                channel.WebMaster = elementText.ToString();
                                                break;
                                            case "rating":
                                                channel.Rating = elementText.ToString();
                                                break;
                                            case "pubdate":
                                                try
                                                {
                                                    channel.PubDate = DateTime.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "lastbuilddate":
                                                try
                                                {
                                                    channel.LastBuildDate = DateTime.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "generator":
                                                channel.Generator = elementText.ToString();
                                                break;
                                            case "docs":
                                                channel.Docs = elementText.ToString();
                                                break;
                                            case "ttl":
                                                try
                                                {
                                                    channel.TimeToLive = int.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                        }
                                        break;
                                    case "image":
                                        switch (childElementName)
                                        {
                                            case "url":
                                                try
                                                {
                                                    image.Url = new Uri(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "title":
                                                image.Title = elementText.ToString();
                                                break;
                                            case "link":
                                                try
                                                {
                                                    image.Link = new Uri(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "description":
                                                image.Description = elementText.ToString();
                                                break;
                                            case "width":
                                                try
                                                {
                                                    image.Width = Byte.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "height":
                                                try
                                                {
                                                    image.Height = Byte.Parse(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                        }
                                        break;
                                    case "textinput":
                                        switch (childElementName)
                                        {
                                            case "title":
                                                textInput.Title = elementText.ToString();
                                                break;
                                            case "description":
                                                textInput.Description = elementText.ToString();
                                                break;
                                            case "name":
                                                textInput.Name = elementText.ToString();
                                                break;
                                            case "link":
                                                try
                                                {
                                                    textInput.Link = new Uri(elementText.ToString());
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                        }
                                        break;
                                    case "skipdays":
                                        if (childElementName == "day")
                                            switch (elementText.ToString().ToLower())
                                            {
                                                case "monday":
                                                    channel.SkipDays[0] = true;
                                                    break;
                                                case "tuesday":
                                                    channel.SkipDays[1] = true;
                                                    break;
                                                case "wednesday":
                                                    channel.SkipDays[2] = true;
                                                    break;
                                                case "thursday":
                                                    channel.SkipDays[3] = true;
                                                    break;
                                                case "friday":
                                                    channel.SkipDays[4] = true;
                                                    break;
                                                case "saturday":
                                                    channel.SkipDays[5] = true;
                                                    break;
                                                case "sunday":
                                                    channel.SkipDays[6] = true;
                                                    break;
                                            }
                                        break;
                                    case "skiphours":
                                        if (childElementName == "hour")
                                            channel.SkipHours[Byte.Parse(elementText.ToString().ToLower())] = true;
                                        break;
                                }
                                break;
                            }
                        case XmlNodeType.Text:
                            elementText.Append(reader.Value);
                            break;
                        case XmlNodeType.CDATA:
                            elementText.Append(reader.Value);
                            break;
                    }
                }
            } while (readData);
            return rssElement;
        }
Exemplo n.º 8
0
 /// <summary>Closes connection to file.</summary>
 /// <remarks>This method also releases any resources held while reading.</remarks>
 public void Close()
 {
     textInput = null;
     image = null;
     cloud = null;
     channel = null;
     source = null;
     enclosure = null;
     category = null;
     item = null;
     if (reader != null)
     {
         reader.Close();
         reader = null;
     }
     elementText = null;
     xmlNodeStack = null;
 }
Exemplo n.º 9
0
        private void writeChannel(RssChannel channel)
        {
            if (writer == null)
                throw new InvalidOperationException("RssWriter has been closed, and can not be written to.");
            if (channel == null)
                throw new ArgumentNullException("channel", "Channel must be instanciated with data to be written.");

            if (wroteChannel)
                writer.WriteEndElement();
            else
                wroteChannel = true;

            BeginDocument();

            writer.WriteStartElement("channel");
            WriteElement("title", channel.Title, true);
            WriteElement("description", channel.Description, false);
            WriteElement("link", channel.Link, true);
            if (channel.Image != null)
            {
                writer.WriteStartElement("image");
                WriteElement("title", channel.Image.Title, true);
                WriteElement("url", channel.Image.Url, true);
                WriteElement("link", channel.Image.Link, true);
                switch (rssVersion)
                {
                    case RssVersion.RSS091:
                    case RssVersion.RSS092:
                    case RssVersion.RSS20:
                        WriteElement("description", channel.Image.Description, false);
                        WriteElement("width", channel.Image.Width, false);
                        WriteElement("height", channel.Image.Height, false);
                        break;
                }
                writer.WriteEndElement();
            }
            switch (rssVersion)
            {
                case RssVersion.RSS091:
                case RssVersion.RSS092:
                case RssVersion.RSS20:
                    WriteElement("language", channel.Language, rssVersion == RssVersion.RSS091);
                    WriteElement("copyright", channel.Copyright, false);
                    WriteElement("managingEditor", channel.ManagingEditor, false);
                    WriteElement("webMaster", channel.WebMaster, false);
                    WriteElement("pubDate", channel.PubDate, false);
                    WriteElement("lastBuildDate", channel.LastBuildDate, false);
                    if (channel.Docs != RssDefault.String)
                        WriteElement("docs", channel.Docs, false);
                    else
                        switch (rssVersion)
                        {
                            case RssVersion.RSS091:
                                WriteElement("docs", "http://my.netscape.com/publish/formats/rss-spec-0.91.html", false);
                                break;
                            case RssVersion.RSS092:
                                WriteElement("docs", "http://backend.userland.com/rss092", false);
                                break;
                            case RssVersion.RSS20:
                                WriteElement("docs", "http://backend.userland.com/rss", false);
                                break;
                        }
                    WriteElement("rating", channel.Rating, false);
                    string[] Days = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
                    for (var i = 0; i <= 6; i++)
                        if (channel.SkipDays[i])
                        {
                            writer.WriteStartElement("skipDays");
                            for (var i2 = 0; i2 <= 6; i2++)
                                if (channel.SkipDays[i2])
                                    WriteElement("day", Days[i2], false);
                            writer.WriteEndElement();
                            break;
                        }
                    for (var i = 0; i <= 23; i++)
                        if (channel.SkipHours[i])
                        {
                            writer.WriteStartElement("skipHours");
                            for (var i2 = 0; i2 <= 23; i2++)
                                if (channel.SkipHours[i2])
                                    WriteElement("hour", i2 + 1, false);
                            writer.WriteEndElement();
                            break;
                        }
                    break;
            }
            switch (rssVersion)
            {
                case RssVersion.RSS092:
                case RssVersion.RSS20:
                    if (channel.Categories != null)
                        foreach (RssCategory category in channel.Categories)
                            if (category.Name != RssDefault.String)
                            {
                                writer.WriteStartElement("category");
                                WriteAttribute("domain", category.Domain, false);
                                writer.WriteString(category.Name);
                                writer.WriteEndElement();
                            }
                    if (channel.Cloud != null)
                    {
                        writer.WriteStartElement("cloud");
                        WriteElement("domain", channel.Cloud.Domain, false);
                        WriteElement("port", channel.Cloud.Port, false);
                        WriteElement("path", channel.Cloud.Path, false);
                        WriteElement("registerProcedure", channel.Cloud.RegisterProcedure, false);
                        if (channel.Cloud.Protocol != RssCloudProtocol.Empty)
                            WriteElement("Protocol", channel.Cloud.Protocol, false);
                        writer.WriteEndElement();
                    }
                    break;
            }
            if (rssVersion == RssVersion.RSS20)
            {
                if (channel.Generator != RssDefault.String)
                    WriteElement("generator", channel.Generator, false);
                else
                    WriteElement("generator", "RSS.NET: http://www.rssdotnet.com/", false);
                WriteElement("ttl", channel.TimeToLive, false);

                // RSS Modules
                foreach (RssModule rssModule in _rssModules)
                {
                    if (rssModule.IsBoundTo(channel.GetHashCode()))
                    {
                        foreach (RssModuleItem rssModuleItem in rssModule.ChannelExtensions)
                        {
                            if (rssModuleItem.SubElements.Count == 0)
                                WriteElement(rssModule.NamespacePrefix + ":" + rssModuleItem.Name, rssModuleItem.Text,
                                             rssModuleItem.IsRequired);
                            else
                                writeSubElements(rssModuleItem.SubElements, rssModule.NamespacePrefix);
                        }
                    }
                }
            }
            if (channel.TextInput != null)
            {
                writer.WriteStartElement("textinput");
                WriteElement("title", channel.TextInput.Title, true);
                WriteElement("description", channel.TextInput.Description, true);
                WriteElement("name", channel.TextInput.Name, true);
                WriteElement("link", channel.TextInput.Link, true);
                writer.WriteEndElement();
            }
            foreach (RssItem item in channel.Items)
            {
                writeItem(item, channel.GetHashCode());
            }
            writer.Flush();
        }
Exemplo n.º 10
0
 /// <summary>Writes an RSS channel</summary>
 /// <exception cref="InvalidOperationException">RssWriter has been closed, and can not be written to.</exception>
 /// <exception cref="ArgumentNullException">Channel must be instanciated with data, before calling Write.</exception>
 /// <param name="channel">RSS channel to write</param>
 public void Write(RssChannel channel)
 {
     writeChannel(channel);
 }
Exemplo n.º 11
0
        public ActionResult Rss()
        {
            var blog = Blog.GetBlogByName(CurrentWeb);
            if (blog == null)
            {
                throw new HttpException(404, Messages.BlogNotExist);
            }

            int total;
            var posts = Post.GetPostsOfBlog(blog.Id, 1, blog.PostsPerFeed, out total);
            var baseUri = MyLifeContext.AbsoluteWebRoot;
            Response.ContentType = "text/xml";
            var rssWriter = new RssWriter(Response.OutputStream, Encoding.UTF8) {Version = RssVersion.RSS20};
            var rssChanel = new RssChannel
                                {
                                    Title = blog.Name,
                                    Description = blog.Description,
                                    Link = new Uri(baseUri, blog.CreatedBy + "/blog"),
                                    LastBuildDate = DateTime.UtcNow
                                };

            foreach (var post in posts)
            {
                rssChanel.Items.Add(new RssItem
                                        {
                                            Title = post.Title,
                                            Description = post.Content,
                                            Link = new Uri(baseUri, post.RelativeUrl),
                                            Author = post.CreatedBy,
                                            PubDate = post.CreatedDate
                                        });
            }

            rssWriter.Write(rssChanel);
            rssWriter.Close();
            Response.Flush();
            return new EmptyResult();
        }