From f88f7fa841c354203f74c9ffecd28a23d7109d3c Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Sat, 13 Nov 2010 09:57:44 -0800 Subject: [PATCH 1/8] Fix SpecFlow test --HG-- branch : dev --- src/Orchard.Specs/Bindings/OrchardSiteFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs index e4e820952..90a5864a1 100644 --- a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs +++ b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs @@ -17,7 +17,7 @@ namespace Orchard.Specs.Bindings { webApp.GivenIHaveACleanSiteWith(TableData( new { extension = "module", names = "Orchard.Setup, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" }, - new { extension = "core", names = "Common, Dashboard, Feeds, HomePage, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" }, + new { extension = "core", names = "Common, Dashboard, Feeds, HomePage, Messaging, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" }, new { extension = "theme", names = "SafeMode, TheAdmin, TheThemeMachine" })); webApp.WhenIGoTo("Setup"); From 27ecd9e5bb087333326b3b6dcad203f46e0c454d Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Sat, 13 Nov 2010 10:01:30 -0800 Subject: [PATCH 2/8] Add dependencies --HG-- branch : dev --- src/Orchard.Web/Modules/Orchard.Email/Module.txt | 2 +- src/Orchard.Web/Modules/Orchard.Users/Module.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.Email/Module.txt b/src/Orchard.Web/Modules/Orchard.Email/Module.txt index e53254b6b..84dea17b9 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.Email/Module.txt @@ -9,4 +9,4 @@ Features: Orchard.Email: Description: Email Messaging services. Category: Messaging - Dependencies: Messaging + Dependencies: Messaging, Orchard.Users diff --git a/src/Orchard.Web/Modules/Orchard.Users/Module.txt b/src/Orchard.Web/Modules/Orchard.Users/Module.txt index 266449435..2566b6b59 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.Users/Module.txt @@ -8,4 +8,5 @@ Description: The users module enables user management. Features: Orchard.Users: Description: Standard users. + Dependencies: Messaging Category: Core From 5b0fe58931b69c6ca828a70f3f0e59e298473349 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Sat, 13 Nov 2010 10:08:26 -0800 Subject: [PATCH 3/8] Fix SpecFlow tests --HG-- branch : dev --- src/Orchard.Specs/Setup.feature | 16 +++++++-------- src/Orchard.Specs/Setup.feature.cs | 32 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Orchard.Specs/Setup.feature b/src/Orchard.Specs/Setup.feature index 45d4aa23d..50f974e02 100644 --- a/src/Orchard.Specs/Setup.feature +++ b/src/Orchard.Specs/Setup.feature @@ -6,8 +6,8 @@ Feature: Setup Scenario: Root request shows setup form Given I have a clean site with | extension | names | - | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Orchard.jQuery, TinyMce | - | core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Orchard.PublishLater, Scheduling, Settings, Shapes, XmlRpc | + | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce | + | core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc | | theme | SafeMode | When I go to "/Default.aspx" Then I should see "Welcome to Orchard" @@ -17,8 +17,8 @@ Scenario: Root request shows setup form Scenario: Setup folder also shows setup form Given I have a clean site with | extension | names | - | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Orchard.jQuery, TinyMce | - | core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Orchard.PublishLater, Scheduling, Settings, Shapes, XmlRpc | + | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce | + | core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc | | theme | SafeMode | When I go to "/Setup" Then I should see "Welcome to Orchard" @@ -28,8 +28,8 @@ Scenario: Setup folder also shows setup form Scenario: Some of the initial form values are required Given I have a clean site with | extension | names | - | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Orchard.jQuery, TinyMce | - | core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Orchard.PublishLater, Scheduling, Settings, Shapes, XmlRpc | + | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce | + | core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc | | theme | SafeMode | When I go to "/Setup" And I hit "Finish Setup" @@ -39,8 +39,8 @@ Scenario: Some of the initial form values are required Scenario: Calling setup on a brand new install Given I have a clean site with | extension | names | - | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce | - | core | Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable, Orchard.PublishLater, Scheduling, Settings, Shapes, XmlRpc | + | module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce | + | core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc | | theme | SafeMode, TheThemeMachine | And I am on "/Setup" When I fill in diff --git a/src/Orchard.Specs/Setup.feature.cs b/src/Orchard.Specs/Setup.feature.cs index dbad29dc8..d71fe7a70 100644 --- a/src/Orchard.Specs/Setup.feature.cs +++ b/src/Orchard.Specs/Setup.feature.cs @@ -66,12 +66,12 @@ this.ScenarioSetup(scenarioInfo); "names"}); table1.AddRow(new string[] { "module", - "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Or" + - "chard.jQuery, TinyMce, Orchard.PublishLater"}); + "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" + + "er, Orchard.Themes, Orchard.jQuery, TinyMce"}); table1.AddRow(new string[] { "core", - "Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable," + - " Scheduling, Settings, Shapes, XmlRpc"}); + "Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" + + "heduling, Settings, Shapes, XmlRpc"}); table1.AddRow(new string[] { "theme", "SafeMode"}); @@ -102,12 +102,12 @@ this.ScenarioSetup(scenarioInfo); "names"}); table2.AddRow(new string[] { "module", - "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Or" + - "chard.jQuery, TinyMce, Orchard.PublishLater"}); + "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" + + "er, Orchard.Themes, Orchard.jQuery, TinyMce"}); table2.AddRow(new string[] { "core", - "Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable," + - " Scheduling, Settings, Shapes, XmlRpc"}); + "Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" + + "heduling, Settings, Shapes, XmlRpc"}); table2.AddRow(new string[] { "theme", "SafeMode"}); @@ -138,12 +138,12 @@ this.ScenarioSetup(scenarioInfo); "names"}); table3.AddRow(new string[] { "module", - "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Or" + - "chard.jQuery, TinyMce, Orchard.PublishLater"}); + "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" + + "er, Orchard.Themes, Orchard.jQuery, TinyMce"}); table3.AddRow(new string[] { "core", - "Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable," + - " Scheduling, Settings, Shapes, XmlRpc"}); + "Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" + + "heduling, Settings, Shapes, XmlRpc"}); table3.AddRow(new string[] { "theme", "SafeMode"}); @@ -176,12 +176,12 @@ this.ScenarioSetup(scenarioInfo); "names"}); table4.AddRow(new string[] { "module", - "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.Themes, Or" + - "chard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce, Orchard.PublishLater"}); + "Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" + + "er, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce"}); table4.AddRow(new string[] { "core", - "Common, Contents, Dashboard, Feeds, HomePage, Navigation, Routable," + - " Scheduling, Settings, Shapes, XmlRpc"}); + "Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" + + "heduling, Settings, Shapes, XmlRpc"}); table4.AddRow(new string[] { "theme", "SafeMode, TheThemeMachine"}); From 4d9e2955425fa93e345cec3f3c862f5f63b81b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Sat, 13 Nov 2010 10:17:32 -0800 Subject: [PATCH 4/8] Removing dependency to Orchard.User from Orchard.Email --HG-- branch : dev --- src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj | 4 ---- .../Orchard.Email/Services/EmailMessageEventHandler.cs | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj b/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj index 0e6b5b122..911ca0478 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj +++ b/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj @@ -92,10 +92,6 @@ {9916839C-39FC-4CEB-A5AF-89CA7E87119F} Orchard.Core - - {79AED36E-ABD0-4747-93D3-8722B042454B} - Orchard.Users - diff --git a/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessageEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessageEventHandler.cs index e67ace915..a9bf4ee56 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessageEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessageEventHandler.cs @@ -1,7 +1,7 @@ using Orchard.Messaging.Events; using Orchard.ContentManagement; -using Orchard.Users.Models; using Orchard.Messaging.Models; +using Orchard.Security; namespace Orchard.Email.Services { public class EmailMessageEventHandler : IMessageEventHandler { @@ -16,7 +16,7 @@ namespace Orchard.Email.Services { if ( contentItem == null ) return; - var recipient = contentItem.As(); + var recipient = contentItem.As(); if ( recipient == null ) return; From d6760392e0c3742938f4934bbf395a3e5b63609c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Sat, 13 Nov 2010 10:20:47 -0800 Subject: [PATCH 5/8] Removing dependency in manifest --HG-- branch : dev --- src/Orchard.Web/Modules/Orchard.Email/Module.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.Email/Module.txt b/src/Orchard.Web/Modules/Orchard.Email/Module.txt index 84dea17b9..e53254b6b 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.Email/Module.txt @@ -9,4 +9,4 @@ Features: Orchard.Email: Description: Email Messaging services. Category: Messaging - Dependencies: Messaging, Orchard.Users + Dependencies: Messaging From a80b790cce08b3e197d5865dea7e0df62a62ed23 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Sat, 13 Nov 2010 11:38:33 -0800 Subject: [PATCH 6/8] Fix web.config 500 error with IIS7 This is just a temporary fix as Theme.jpg files aren't served properly anymore --HG-- branch : dev --- src/Orchard.Web/Themes/Web.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Themes/Web.config b/src/Orchard.Web/Themes/Web.config index a2d69a7b9..8ebb44d0d 100644 --- a/src/Orchard.Web/Themes/Web.config +++ b/src/Orchard.Web/Themes/Web.config @@ -3,7 +3,7 @@ - + - + From 1badb1a917e7995b34ab57c5e2387193ad803ff7 Mon Sep 17 00:00:00 2001 From: andrerod Date: Sat, 13 Nov 2010 23:20:25 -0800 Subject: [PATCH 7/8] Medium Trust: Replacing usage of GetName() by assemblyName on commandhostenvironment. Extracting DefaultHostEnvironment class to a file outside of the Interface one. --HG-- branch : dev --- .../Commands/CommandHostEnvironment.cs | 3 +- .../Environment/DefaultHostEnvironment.cs | 64 +++++++++++++++++++ src/Orchard/Environment/IHostEnvironment.cs | 56 +--------------- src/Orchard/Orchard.Framework.csproj | 1 + 4 files changed, 69 insertions(+), 55 deletions(-) create mode 100644 src/Orchard/Environment/DefaultHostEnvironment.cs diff --git a/src/Orchard/Commands/CommandHostEnvironment.cs b/src/Orchard/Commands/CommandHostEnvironment.cs index 8a79ff81d..a37339ca9 100644 --- a/src/Orchard/Commands/CommandHostEnvironment.cs +++ b/src/Orchard/Commands/CommandHostEnvironment.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Reflection; using System.Web.Hosting; using Orchard.Environment; using Orchard.Localization; @@ -21,7 +22,7 @@ namespace Orchard.Commands { } public bool IsAssemblyLoaded(string name) { - return AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name == name); + return AppDomain.CurrentDomain.GetAssemblies().Any(assembly => new AssemblyName(assembly.FullName).Name == name); } public void RestartAppDomain() { diff --git a/src/Orchard/Environment/DefaultHostEnvironment.cs b/src/Orchard/Environment/DefaultHostEnvironment.cs new file mode 100644 index 000000000..d9616b7aa --- /dev/null +++ b/src/Orchard/Environment/DefaultHostEnvironment.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Web; +using System.Web.Hosting; +using Orchard.Services; +using Orchard.Utility.Extensions; + +namespace Orchard.Environment +{ + public class DefaultHostEnvironment : IHostEnvironment + { + private readonly IClock _clock; + + public DefaultHostEnvironment(IClock clock) + { + _clock = clock; + } + + public bool IsFullTrust + { + get { return AppDomain.CurrentDomain.IsFullyTrusted; } + } + + public string MapPath(string virtualPath) + { + return HostingEnvironment.MapPath(virtualPath); + } + + public bool IsAssemblyLoaded(string name) + { + return AppDomain.CurrentDomain.GetAssemblies().Any(assembly => new AssemblyName(assembly.FullName).Name == name); + } + + public void RestartAppDomain() + { + ResetSiteCompilation(); + } + + public void ResetSiteCompilation() + { + // Touch web.config + File.SetLastWriteTimeUtc(MapPath("~/web.config"), _clock.UtcNow); + + // If setting up extensions/modules requires an AppDomain restart, it's very unlikely the + // current request can be processed correctly. So, we redirect to the same URL, so that the + // new request will come to the newly started AppDomain. + if (HttpContext.Current != null) + { + // Don't redirect posts... + if (HttpContext.Current.Request.RequestType == "GET") + { + HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ToUrlString(), true /*endResponse*/); + } + else + { + HttpContext.Current.Response.WriteFile("~/Refresh.html"); + HttpContext.Current.Response.End(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard/Environment/IHostEnvironment.cs b/src/Orchard/Environment/IHostEnvironment.cs index c1cba668a..8b6d668bf 100644 --- a/src/Orchard/Environment/IHostEnvironment.cs +++ b/src/Orchard/Environment/IHostEnvironment.cs @@ -1,13 +1,4 @@ -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Web; -using System.Web.Hosting; -using Orchard.Services; -using Orchard.Utility.Extensions; - -namespace Orchard.Environment { +namespace Orchard.Environment { /// /// Abstraction of the running environment /// @@ -20,47 +11,4 @@ namespace Orchard.Environment { void RestartAppDomain(); void ResetSiteCompilation(); } - - public class DefaultHostEnvironment : IHostEnvironment { - private readonly IClock _clock; - - public DefaultHostEnvironment(IClock clock) { - _clock = clock; - } - - public bool IsFullTrust { - get { return AppDomain.CurrentDomain.IsFullyTrusted; } - } - - public string MapPath(string virtualPath) { - return HostingEnvironment.MapPath(virtualPath); - } - - public bool IsAssemblyLoaded(string name) { - return AppDomain.CurrentDomain.GetAssemblies().Any(assembly => new AssemblyName(assembly.FullName).Name == name); - } - - public void RestartAppDomain() { - ResetSiteCompilation(); - } - - public void ResetSiteCompilation() { - // Touch web.config - File.SetLastWriteTimeUtc(MapPath("~/web.config"), _clock.UtcNow); - - // If setting up extensions/modules requires an AppDomain restart, it's very unlikely the - // current request can be processed correctly. So, we redirect to the same URL, so that the - // new request will come to the newly started AppDomain. - if (HttpContext.Current != null) { - // Don't redirect posts... - if (HttpContext.Current.Request.RequestType == "GET") { - HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ToUrlString(), true /*endResponse*/); - } - else { - HttpContext.Current.Response.WriteFile("~/Refresh.html"); - HttpContext.Current.Response.End(); - } - } - } - } -} +} \ No newline at end of file diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index c8c95384d..f9c9cffe3 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -174,6 +174,7 @@ + From 6eb257fc7cdbfd85b8ff9bb704322a0c93e176ea Mon Sep 17 00:00:00 2001 From: andrerod Date: Sun, 14 Nov 2010 00:09:42 -0800 Subject: [PATCH 8/8] Updating project references with hint paths to avoid warnings on clean. --HG-- branch : dev --- src/Orchard.Core.Tests/Orchard.Core.Tests.csproj | 4 +++- src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj | 8 ++++++-- .../Modules/Orchard.Setup/Orchard.Setup.csproj | 4 +++- src/Orchard/Orchard.Framework.csproj | 4 +++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj b/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj index 2606ff580..c6f6c4624 100644 --- a/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj +++ b/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj @@ -59,7 +59,9 @@ False ..\..\lib\autofac\Autofac.dll - + + ..\..\lib\claysharp\ClaySharp.dll + False ..\..\lib\moq\Moq.dll diff --git a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj index 77eb787f7..8512c3825 100644 --- a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj +++ b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj @@ -59,8 +59,12 @@ False ..\..\lib\autofac\Autofac.dll - - + + ..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll + + + ..\..\lib\claysharp\ClaySharp.dll + False ..\..\lib\fluentnhibernate\FluentNHibernate.dll diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Orchard.Setup.csproj b/src/Orchard.Web/Modules/Orchard.Setup/Orchard.Setup.csproj index 7b81c2256..906b5033c 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Orchard.Setup.csproj +++ b/src/Orchard.Web/Modules/Orchard.Setup/Orchard.Setup.csproj @@ -43,7 +43,9 @@ False ..\..\..\..\lib\autofac\Autofac.dll - + + ..\..\..\..\lib\claysharp\ClaySharp.dll + diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index f9c9cffe3..06ecea4d6 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -147,7 +147,9 @@ False ..\..\lib\aspnetmvc\System.Web.WebPages.dll - + + ..\..\lib\aspnetmvc\System.Web.WebPages.Razor.dll +