From 262f4a45593680f3f649e5c22faa720879f820a2 Mon Sep 17 00:00:00 2001 From: Nathan Heskew Date: Fri, 15 Oct 2010 14:40:35 -0700 Subject: [PATCH] Getting Orchard.Blogs on the new UI composition model (for display) --HG-- branch : dev --- .../Controllers/BlogController.cs | 28 ++++++++++--------- .../Drivers/BlogArchivesPartDriver.cs | 18 ++++++------ .../Drivers/BlogPagerPartDriver.cs | 11 ++++++++ .../Orchard.Blogs/Drivers/BlogPartDriver.cs | 10 ++++--- .../Drivers/RecentBlogPostsPartDriver.cs | 10 +++---- .../Modules/Orchard.Blogs/Migrations.cs | 6 ++++ .../Orchard.Blogs/Models/BlogPagerPart.cs | 10 +++++++ .../Orchard.Blogs/Orchard.Blogs.csproj | 9 ++++-- .../Modules/Orchard.Blogs/Placement.info | 22 +++++++++++---- .../Modules/Orchard.Blogs/Shapes.cs | 22 +++++++++++++++ .../ViewModels/BlogPostArchiveViewModel.cs | 9 ------ .../ViewModels/DisplayBlogViewModel.cs | 8 ------ .../Orchard.Blogs/Views/Blog/Item.cshtml | 28 ++----------------- .../Parts/Blogs.BlogArchives.cshtml | 2 +- .../Views/Parts/Blogs.Blog.Pager.cshtml | 18 ++++++++++++ .../Parts/Blogs.BlogArchives.cshtml | 24 +++++++--------- .../Views/Parts/Blogs.BlogPost.List.cshtml | 8 ++---- .../Views/Parts/Blogs.RecentBlogPosts.cshtml | 1 + src/Orchard.sln | 3 ++ 19 files changed, 143 insertions(+), 104 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPagerPartDriver.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPagerPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/Shapes.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/BlogPostArchiveViewModel.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/DisplayBlogViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Pager.cshtml rename src/Orchard.Web/Modules/Orchard.Blogs/Views/{DisplayTemplates => }/Parts/Blogs.BlogArchives.cshtml (50%) create mode 100644 src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.RecentBlogPosts.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs index 5523068e1..524ed60c2 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs @@ -6,7 +6,7 @@ using System.Xml.Linq; using Orchard.Blogs.Models; using Orchard.Blogs.Routing; using Orchard.Blogs.Services; -using Orchard.Blogs.ViewModels; +using Orchard.ContentManagement; using Orchard.DisplayManagement; using Orchard.Logging; using Orchard.Themes; @@ -53,25 +53,27 @@ namespace Orchard.Blogs.Controllers { if (correctedSlug == null) return HttpNotFound(); - BlogPart blog = _blogService.Get(correctedSlug); - if (blog == null) + var blogPart = _blogService.Get(correctedSlug); + if (blogPart == null) return HttpNotFound(); - var blogPosts = _blogPostService.Get(blog, (page - 1)*pageSize, pageSize).Select(b => _services.ContentManager.BuildDisplay(b, "Summary")); + var blogPosts = _blogPostService.Get(blogPart, (page - 1) * pageSize, pageSize) + .Select(b => _services.ContentManager.BuildDisplay(b, "Summary")); + + blogPart.As().Page = page; + blogPart.As().PageSize = pageSize; + blogPart.As().BlogSlug = correctedSlug; + blogPart.As().ThereIsANextPage = _blogPostService.Get(blogPart, (page) * pageSize, pageSize).Any(); + + var blog = _services.ContentManager.BuildDisplay(blogPart); var list = Shape.List(); list.AddRange(blogPosts); - var blogShape = _services.ContentManager.BuildDisplay(blog); - var model = new DisplayBlogViewModel { - Blog = blogShape, - BlogPostList = list, - Page = page, - PageSize = pageSize - }; - - return View(model); + blog.ContentItem = blogPart; + blog.Content.Add(Shape.Parts_Blogs_BlogPost_List(ContentItems: list), "5"); + return View("Display", blog); } public ActionResult LiveWriterManifest(string blogSlug) { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogArchivesPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogArchivesPartDriver.cs index 44621999e..4bc0982fb 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogArchivesPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogArchivesPartDriver.cs @@ -1,6 +1,5 @@ using Orchard.Blogs.Models; using Orchard.Blogs.Services; -using Orchard.Blogs.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.Core.ContentsLocation.Models; @@ -16,16 +15,17 @@ namespace Orchard.Blogs.Drivers { } protected override DriverResult Display(BlogArchivesPart part, string displayType, dynamic shapeHelper) { - BlogPart blog = null; - if (!string.IsNullOrWhiteSpace(part.ForBlog)) - blog = _blogService.Get(part.ForBlog); + return ContentShape("Parts_Blogs_BlogArchives", + () => { + BlogPart blog = null; + if (!string.IsNullOrWhiteSpace(part.ForBlog)) + blog = _blogService.Get(part.ForBlog); - if ( blog != null ) { - var model = new BlogPostArchiveViewModel {BlogPart = blog, Archives = _blogPostService.GetArchives(blog)}; - return ContentPartTemplate(model, "Parts/Blogs.BlogArchives"); - } + if (blog == null) + return null; - return null; + return shapeHelper.Parts_Blogs_BlogArchives(ContentItem: part, Blog: blog, Archives: _blogPostService.GetArchives(blog)); + }).Location("Content"); } protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPagerPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPagerPartDriver.cs new file mode 100644 index 000000000..727ff6b55 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPagerPartDriver.cs @@ -0,0 +1,11 @@ +using Orchard.Blogs.Models; +using Orchard.ContentManagement.Drivers; + +namespace Orchard.Blogs.Drivers { + public class BlogPagerPartDriver : ContentPartDriver { + protected override DriverResult Display(BlogPagerPart part, string displayType, dynamic shapeHelper) { + return ContentShape("Parts_Blogs_Blog_Pager", + () => shapeHelper.Parts_Blogs_Blog_Pager(ContentPart: part, Page: part.Page, PageSize: part.PageSize, BlogSlug: part.BlogSlug, ThereIsANextPage: part.ThereIsANextPage)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPartDriver.cs index f3cb14478..9ed222575 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPartDriver.cs @@ -38,13 +38,15 @@ namespace Orchard.Blogs.Drivers { () => shapeHelper.Parts_Blogs_Blog_Manage(ContentPart: part)), ContentShape("Parts_Blogs_Blog_Description", () => shapeHelper.Parts_Blogs_Blog_Description(ContentPart: part, Description: part.Description)), + // todo: (heskew) implement a paging solution that doesn't require blog posts to be tied to the blog within the controller ContentShape("Parts_Blogs_BlogPost_List", () => { _feedManager.Register(part); - var list = shapeHelper.List(); - list.AddRange(_blogPostService.Get(part) - .Select(bp => _contentManager.BuildDisplay(bp, "Summary"))); - return shapeHelper.Parts_Blogs_BlogPost_List(ContentPart: part, ContentItems: list); + return null; + // var list = shapeHelper.List(); + // list.AddRange(_blogPostService.Get(part) + // .Select(bp => _contentManager.BuildDisplay(bp, "Summary"))); + // return shapeHelper.Parts_Blogs_BlogPost_List(ContentPart: part, ContentItems: list); }), ContentShape("Parts_Blogs_BlogPost_List_Admin", () => { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/RecentBlogPostsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/RecentBlogPostsPartDriver.cs index ed5cb1adf..ac7ec0313 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/RecentBlogPostsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/RecentBlogPostsPartDriver.cs @@ -18,7 +18,7 @@ namespace Orchard.Blogs.Drivers { } protected override DriverResult Display(RecentBlogPostsPart part, string displayType, dynamic shapeHelper) { - IEnumerable blogPosts = null; + IEnumerable blogPosts; BlogPart blog = null; if (!string.IsNullOrWhiteSpace(part.ForBlog)) @@ -32,7 +32,6 @@ namespace Orchard.Blogs.Drivers { .Select(ci => ci.As()); } else { - var blogs = _blogService.Get().ToList(); blogPosts = _contentManager.Query(VersionOptions.Published, "BlogPost") .Join() .OrderByDescending(cr => cr.CreatedUtc) @@ -41,12 +40,11 @@ namespace Orchard.Blogs.Drivers { } var list = shapeHelper.List(); - list.AddRange(blogPosts.Select(bp => _contentManager.BuildDisplay(bp, "Summary.BlogPost"))); + list.AddRange(blogPosts.Select(bp => _contentManager.BuildDisplay(bp, "Summary"))); - var blogPostList = shapeHelper.Parts_Blogs_BlogPost_List(ContentPart: part, BlogPosts: list); - blogPostList.Metadata.Type = "Parts_Blogs_BlogPost.List"; + var blogPostList = shapeHelper.Parts_Blogs_BlogPost_List(ContentPart: part, ContentItems: list); - return ContentShape(blogPostList).Location("Primary"); + return ContentShape(shapeHelper.Parts_Blogs_RecentBlogPosts(ContentItem: part, ContentItems: blogPostList)); } protected override DriverResult Editor(RecentBlogPostsPart part, dynamic shapeHelper) { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs index 51d8f85fb..5dd7888a5 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs @@ -89,5 +89,11 @@ namespace Orchard.Blogs { return 5; } + + public int UpdateFrom5() { + ContentDefinitionManager.AlterTypeDefinition("Blog", + cfg => cfg.WithPart("BlogPagerPart")); + return 6; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPagerPart.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPagerPart.cs new file mode 100644 index 000000000..e5e9b4132 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPagerPart.cs @@ -0,0 +1,10 @@ +using Orchard.ContentManagement; + +namespace Orchard.Blogs.Models { + public class BlogPagerPart : ContentPart { + public int Page { get; set; } + public int PageSize { get; set; } + public string BlogSlug { get; set; } + public bool ThereIsANextPage { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj index f66a94a27..a3ef9685a 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj @@ -68,11 +68,13 @@ + + @@ -107,8 +109,7 @@ - - + @@ -161,7 +162,7 @@ Designer - + @@ -169,6 +170,8 @@ + + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Placement.info b/src/Orchard.Web/Modules/Orchard.Blogs/Placement.info index 7a90c2c0e..107de8e35 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Placement.info @@ -1,13 +1,23 @@  - - - - + + + + + + + - + + { +// var blog = created.Shape; +// blog.Content.Add(created.New.Parts_Blogs_BlogPost_List(ContentPart: blog.ContentItem, ContentItems: blog.)); +// }) +// .OnDisplaying(displaying => { +// ContentItem contentItem = displaying.Shape.ContentItem; +// if (contentItem != null) { +// var zoneName = contentItem.As().Zone; +// displaying.ShapeMetadata.Alternates.Add("Items_Widget__" + contentItem.ContentType); +// displaying.ShapeMetadata.Alternates.Add("Items_Widget__" + zoneName); +// } +// }); +// } +// } +//} diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/BlogPostArchiveViewModel.cs b/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/BlogPostArchiveViewModel.cs deleted file mode 100644 index a2c6541ca..000000000 --- a/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/BlogPostArchiveViewModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using Orchard.Blogs.Models; - -namespace Orchard.Blogs.ViewModels { - public class BlogPostArchiveViewModel { - public BlogPart BlogPart { get; set; } - public IEnumerable> Archives { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/DisplayBlogViewModel.cs b/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/DisplayBlogViewModel.cs deleted file mode 100644 index 9639d425e..000000000 --- a/src/Orchard.Web/Modules/Orchard.Blogs/ViewModels/DisplayBlogViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Orchard.Blogs.ViewModels { - public class DisplayBlogViewModel { - public dynamic Blog { get; set; } - public dynamic BlogPostList { get; set; } - public int Page { get; set; } - public int PageSize { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Blog/Item.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Blog/Item.cshtml index 7b03eeae4..6057ccc62 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Blog/Item.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Blog/Item.cshtml @@ -1,26 +1,2 @@ -@model Orchard.Blogs.ViewModels.DisplayBlogViewModel -@using Orchard.Blogs.Extensions; -@{ - Style.Include("pagination.css"); -} -@Display(Model.Blog) -@if (Model.BlogPostList.Items.Count > 0) { - @Display(Model.BlogPostList) - -
    - @if(Model.BlogPostList.Items.Count == Model.PageSize) { -
  • - @Html.ActionLink(T("Older Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.Blog.Slug, page = Model.Page + 1 }) -
  • - } - - @if(Model.Page > 1) { -
  • - @Html.ActionLink(T("Newer Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.Blog.Slug, page = Model.Page - 1 }) -
  • - } -
-} -else { -

@T("There are no posts for this blog.")

-} \ No newline at end of file +@Display(Model.Meta) +@Display(Model.Content) \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/EditorTemplates/Parts/Blogs.BlogArchives.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/EditorTemplates/Parts/Blogs.BlogArchives.cshtml index 3f67d5472..1f29a1f88 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/EditorTemplates/Parts/Blogs.BlogArchives.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/EditorTemplates/Parts/Blogs.BlogArchives.cshtml @@ -3,6 +3,6 @@
@Html.LabelFor(m => m.ForBlog) @Html.TextBoxFor(m => m.ForBlog) - @T("The blog's slug to display the archives for.") + @T("Show the archives for which blog? Note: specify the blog's slug.")
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Pager.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Pager.cshtml new file mode 100644 index 000000000..925ad6eef --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.Blog.Pager.cshtml @@ -0,0 +1,18 @@ +@using Orchard.Blogs.Extensions; +@{ + Style.Include("pagination.css"); +} +@if (Model.ThereIsANextPage || Model.Page > 1) { +
    + @if(Model.ThereIsANextPage) { +
  • + @Html.ActionLink(T("Older Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.BlogSlug, page = Model.Page + 1 }) +
  • + } + @if(Model.Page > 1) { +
  • + @Html.ActionLink(T("Newer Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.BlogSlug, page = Model.Page - 1 }) +
  • + } +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Parts/Blogs.BlogArchives.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogArchives.cshtml similarity index 50% rename from src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Parts/Blogs.BlogArchives.cshtml rename to src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogArchives.cshtml index 072dda3bd..9b6c5910b 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Parts/Blogs.BlogArchives.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogArchives.cshtml @@ -1,23 +1,20 @@ -@model Orchard.Blogs.ViewModels.BlogPostArchiveViewModel -@using Orchard.Blogs.Extensions; - +@using Orchard.Blogs.Extensions; +@using Orchard.Blogs.Models; @{ Style.Require("BlogsArchives"); Script.Require("BlogsArchives"); + IEnumerable> archives = Model.Archives; } -

@T("Archives")

- @if (Model.Archives.Count() > 20) { + @if (archives.Count() > 20) {
    @{ - int lastYear = Model.Archives.First().Key.Year; - int firstYear = Model.Archives.Last().Key.Year; + int lastYear = archives.First().Key.Year; + int firstYear = archives.Last().Key.Year; } - - @for (int year = lastYear; year >= firstYear; year--) { - var yearMonths = Model.Archives.Where(m => m.Key.Year == year); + var yearMonths = archives.Where(m => m.Key.Year == year); if (year == lastYear) {
  • @@ -28,15 +25,14 @@ if (year != lastYear) {
  • } } -
} - else if (Model.Archives.Count() > 0) { - @Html.UnorderedList(Model.Archives, (t, i) => Html.Link(string.Format("{0:MMMM yyyy} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth(Model.BlogPart.Slug, t.Key.Year, t.Key.Month)), "archiveMonthList") + else if (archives.Count() > 0) { + @Html.UnorderedList(archives, (t, i) => Html.Link(string.Format("{0:MMMM yyyy} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth((string)Model.BlogPart.Slug, t.Key.Year, t.Key.Month)), "archiveMonthList") } else {
@T("None found")
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogPost.List.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogPost.List.cshtml index 86506523a..c5ad057ad 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogPost.List.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.BlogPost.List.cshtml @@ -1,9 +1,7 @@ @{ - IEnumerable blogPosts = Model.BlogPosts; + IEnumerable blogPosts = Model.ContentItems; } -@Display(ContentItems) +@Display(Model.ContentItems) @if (blogPosts == null || blogPosts.Count() < 1) {

@T("There are no posts for this blog.")

-} - -hi \ No newline at end of file +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.RecentBlogPosts.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.RecentBlogPosts.cshtml new file mode 100644 index 000000000..46e0c33a4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Parts/Blogs.RecentBlogPosts.cshtml @@ -0,0 +1 @@ +@Display(Model.ContentItems) \ No newline at end of file diff --git a/src/Orchard.sln b/src/Orchard.sln index b21c15219..7f33dc2ef 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -44,6 +44,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Tests", "Tools\Orchard.Tests\Orchard.Tests.csproj", "{0DFA2E10-96C8-4E05-BC10-B710B97ECCDE}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Notes", "_Notes", "{8A49DB66-40B2-4B6A-BFF0-D4839A240D00}" + ProjectSection(SolutionItems) = preProject + Shapes.txt = Shapes.txt + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Modules", "Orchard.Web\Modules\Orchard.Modules\Orchard.Modules.csproj", "{17F86780-9A1F-4AA1-86F1-875EEC2730C7}" EndProject