//public static Volume GetVolume(string id);
        public async static Task<Chapter> GetChapterAsync(string chpId, string volId, string serId)
        {

            var chapter = new Chapter();
            chapter.Id = chpId;
            chapter.ParentVolumeId = volId;
            chapter.ParentSeriesId = serId;
            var novelUrl = new Uri(String.Format(ChapterSource, chpId, volId, serId));
            var doc = await GetHtmlDocumentAsync(novelUrl);
            if (doc == null) return null;

            try
            {
                var article = doc.DocumentNode.Descendants("article").FirstOrDefault();
                var titles = article.PreviousSublingElement("div");
                chapter.Title = titles?.Element("h1")?.InnerText;
                var lines = article.ChildNodes.Where(node => node.Name == "p" && node.HasClass("read-line"));
                chapter.Lines = lines.Select(
                    (p) =>
                    {
                        var line = new Line(
                           int.Parse(p.Attributes["data-i"].Value),
                           LineContentType.TextContent,
                           string.Empty);
                        if (p.HasClass("read-line-image"))
                        {
                            line.ContentType = LineContentType.ImageContent;
                            var img = p.ChildNodes.FirstOrDefault(child => child.Name == "img");
                            line.Content = img.GetAttributeValue("src", string.Empty);
                            line.Width = img.GetAttributeValue("data-width", 0);
                            line.Height = img.GetAttributeValue("data-height", 0);
                            line.Size = ulong.Parse(img.GetAttributeValue("data-size", string.Empty));
                        }
                        else
                        {
                            line.Content = CleanText(WebUtility.HtmlDecode(p.InnerText));
                        }
                        return line;
                    }).ToList();
            }
            catch (Exception excp)
            {
                throw new Exception("Failed to parse content : " + excp.Message, excp);
            }

            return chapter;
        }
        public static Chapter ParseChapterAlter(string id, HtmlDocument doc)
        {

            var chapter = new Chapter();

            var nodes = doc.DocumentNode.Descendants();
            chapter.Id = id;
            // Navigation Properties
            {
                var navi = nodes.First(
                    node => node.Attributes["class"] != null && node.Attributes["class"].Value.StartsWith("lk-m-view-pager"));
                var naviNodes = navi.Descendants("a");

                var prev = naviNodes.FirstOrDefault(node => node.InnerText.Contains("上一章"));
                if (prev != null)
                    chapter.PrevChapterId = RetriveId(prev.Attributes["href"].Value);
                var content = naviNodes.FirstOrDefault(node => node.Attributes["href"].Value.Contains("book/"));
                if (content != null)
                    chapter.ParentVolumeId = RetriveId(content.Attributes["href"].Value);
                var next = naviNodes.FirstOrDefault(node => node.InnerText.Contains("下一章"));
                if (next != null)
                    chapter.NextChapterId = RetriveId(next.Attributes["href"].Value);
            }

            var canvas = nodes.First(
                node => node.Attributes["class"] != null && node.Attributes["class"].Value.StartsWith("lk-m-view-can"));
            var contents = canvas.ChildNodes;
            var chapterTitleNode = contents.First(node => node.Name == "h3");
            if (chapterTitleNode != null)
                chapter.Title = RemoveLabel(chapterTitleNode.InnerText);

            var lines = from line in contents
                        where line.Name == "div"
                        && line.Attributes["class"] != null
                        && line.Attributes["class"].Value.StartsWith("lk-view-line")
                        select line;

            chapter.Lines = (lines.Select<HtmlNode, Line>(node =>
            {
                Line line = new Line(int.Parse(node.Id), LineContentType.TextContent, null);
                if (!node.HasChildNodes)
                {
                    line.Content = String.Empty;
                    return line;
                }
                if (node.ChildNodes.Any(elem => elem.Name == "div"))
                {
                    line.ContentType = LineContentType.ImageContent;
                    var img_url = (from elem in node.Descendants()
                                   where elem.Name == "img"
                                         && elem.Attributes["data-ks-lazyload"] != null
                                   select elem.Attributes["data-ks-lazyload"].Value).FirstOrDefault();
                    if (img_url != null)
                    {
                        line.Content = AbsoluteUrl(img_url);
                    }
                }
                else
                {
                    var text = node.InnerText;
                    line.Content = WebUtility.HtmlDecode(text.Trim());
                }
                return line;
            })).ToList();
            return chapter;
        }