コード例 #1
0
        private static TestServer CreateAuthorizationServer(Action <OpenIdConnectServerOptions> configuration = null)
        {
            var builder = new WebHostBuilder();

            builder.UseEnvironment("Testing");

            builder.ConfigureServices(services => services.AddAuthentication());

            builder.Configure(app => {
                app.UseOpenIdConnectServer(options => {
                    options.AllowInsecureHttp = true;

                    options.SigningCredentials.AddCertificate(
                        assembly: typeof(OpenIdConnectServerMiddlewareTests).GetTypeInfo().Assembly,
                        resource: "AspNet.Security.OpenIdConnect.Server.Tests.Certificate.pfx",
                        password: "******");

                    // Note: overriding the default data protection provider is not necessary for the tests to pass,
                    // but is useful to ensure unnecessary keys are not persisted in testing environments, which also
                    // helps make the unit tests run faster, as no registry or disk access is required in this case.
                    options.DataProtectionProvider = new EphemeralDataProtectionProvider(app.ApplicationServices);

                    // Run the configuration delegate
                    // registered by the unit tests.
                    configuration?.Invoke(options);
                });
            });

            return(new TestServer(builder));
        }
コード例 #2
0
        public UsersResourceSampleSite(string resource)
        {
            var webhostbuilder = new WebHostBuilder();

            webhostbuilder
            .ConfigureServices(services => {
                services.AddSingleton(_ => new State());
                services.AddSingleton(_ => new MapperConfiguration(cfg =>
                {
                    cfg.CreateMap <UserUpdateRequest, UserResponse>();
                    cfg.CreateMap <UserCreateRequest, UserResponse>();
                }).CreateMapper());
                services.AddRouting();
                services.AddMemoryCache();
            })
            .Configure(app =>
            {
                app.UseRouter(MatchesRequest);
            });

            _server = new TestServer(webhostbuilder);
            _client = _server.CreateClient();

            RefreshClient(resource);
        }
コード例 #3
0
        public void Initialize(string basePath = null)
        {
            var builder = new WebHostBuilder();

            builder.ConfigureServices(ConfigureServices);
            builder.Configure(app =>
            {
                if (basePath != null)
                {
                    app.Map(basePath, map =>
                    {
                        ConfigureApp(map);
                    });
                }
                else
                {
                    ConfigureApp(app);
                }
            });
            var server = new TestServer(builder);

            Server  = new TestServer(builder);
            Handler = Server.CreateHandler();

            BrowserClient = new BrowserClient(new BrowserHandler(Handler));
            Client        = new HttpClient(Handler);
        }
コード例 #4
0
        protected static TestServer SetupSample(
            IEnumerable <User> testdata   = null,
            Action <WebHostBuilder> setup = null
            )
        {
            var databaseName = "Blog_" + Guid.NewGuid();
            var builder      = new WebHostBuilder();

            builder.UseStartup <Startup>();
            builder.ConfigureServices(s =>
            {
                s.AddDbContext <BlogDbContext>(o => o.UseInMemoryDatabase(databaseName));
            });
            setup?.Invoke(builder);

            var server = new TestServer(builder);

            if (testdata != null)
            {
                using (var scope = server.Services.CreateScope())
                {
                    var context = scope.ServiceProvider.GetRequiredService <BlogDbContext>();
                    context.Database.EnsureCreated();
                    context.Users.AddRange(testdata);
                    context.SaveChanges();
                }
            }

            return(server);
        }
コード例 #5
0
        public void Initialize(string basePath = null, bool enableLogging = false)
        {
            var builder = new WebHostBuilder();

            builder.ConfigureServices(ConfigureServices);
            builder.Configure(app =>
            {
                if (basePath != null)
                {
                    app.Map(basePath, map =>
                    {
                        ConfigureApp(map);
                    });
                }
                else
                {
                    ConfigureApp(app);
                }
            });

            if (enableLogging)
            {
                builder.ConfigureLogging((ctx, b) => b.AddConsole());
            }

            Server  = new TestServer(builder);
            Handler = Server.CreateHandler();

            BrowserClient     = new BrowserClient(new BrowserHandler(Handler));
            BackChannelClient = new HttpClient(Handler);
        }
コード例 #6
0
ファイル: HostingStartup.cs プロジェクト: delixfe/Performance
        public static WebHostBuilder UseProjectOf <TStartup>(this WebHostBuilder builder)
        {
            var applicationName = typeof(TStartup).GetTypeInfo().Assembly.GetName().Name;
            var webRoot         = GetProjectDirectoryOf <TStartup>();

            var assemblyProvider = new StaticAssemblyProvider();

            assemblyProvider.CandidateAssemblies.Add(typeof(TStartup).Assembly);
            builder.ConfigureServices(services =>
            {
                var applicationEnvironment = new TestApplicationEnvironment(
                    PlatformServices.Default.Application,
                    applicationName,
                    webRoot);
                services.AddSingleton <IApplicationEnvironment>(applicationEnvironment);

                var hostingEnvironment = new HostingEnvironment();
                hostingEnvironment.Initialize(
                    webRoot,
                    new WebHostOptions
                {
                    Environment = "Production",
                },
                    configuration: null);
                services.AddSingleton <IHostingEnvironment>(hostingEnvironment);

                services.AddSingleton <IAssemblyProvider>(assemblyProvider);
            });

            return(builder);
        }
コード例 #7
0
 public IWebHostBuilder ConfigureServices(Action <WebHostBuilderContext, IServiceCollection> configureServices)
 {
     WebHostBuilder.ConfigureServices(configureServices);
     MockLogger = new MockLogger();
     WebHostBuilder.ConfigureServices(x => x.Replace(new ServiceDescriptor(typeof(ILoggerFactory), new MockLoggerFactory(_ => MockLogger))));
     return(this);
 }
コード例 #8
0
        public override void SetUp()
        {
            theCheck = new RecordingEnvironmentCheck();

            var builder = new WebHostBuilder();

            builder.UseUrls("http://localhost:3456");
            //builder.UseKestrel();
            builder.ConfigureServices(x =>
            {
                x.AddSingleton <IService, Service>();
                x.AddSingleton <IEnvironmentCheck>(theCheck);
            });

            builder.ConfigureAppConfiguration(b =>
            {
                b.AddInMemoryCollection(new Dictionary <string, string> {
                    { "city", "Austin" }
                });
            });


            builder.UseStartup <AppStartUp>();
            builder.UseEnvironment("Green");
            builder.UseJasper <BootstrappingApp>();


            theSystem = new SystemUnderTest(builder);



            theContainer = theSystem.Services.As <IContainer>();
        }
コード例 #9
0
        private static TestServer CreateAuthorizationServer(Action <OpenIddictServerBuilder> configuration = null)
        {
            var builder = new WebHostBuilder();

            builder.UseEnvironment("Testing");

            builder.ConfigureLogging(options => options.AddDebug());

            builder.ConfigureServices(services =>
            {
                services.AddAuthentication();
                services.AddOptions();
                services.AddDistributedMemoryCache();

                services.AddOpenIddict()
                .AddCore(options =>
                {
                    options.SetDefaultApplicationEntity <OpenIddictApplication>()
                    .SetDefaultAuthorizationEntity <OpenIddictAuthorization>()
                    .SetDefaultScopeEntity <OpenIddictScope>()
                    .SetDefaultTokenEntity <OpenIddictToken>();
                })

                .AddServer(options => configuration?.Invoke(options));
            });

            builder.Configure(app =>
            {
                app.UseAuthentication();

                app.Run(context => context.ChallengeAsync(OpenIddictServerDefaults.AuthenticationScheme));
            });

            return(new TestServer(builder));
        }
コード例 #10
0
ファイル: ServerPlugin.cs プロジェクト: dpen2000/lunet
        public int Server()
        {
            BuildSite(Site, true);
            try
            {
                var wwwDirectory = Site.OutputFileSystem.ConvertPathToInternal(UPath.Root);
                var hostBuilder  = new WebHostBuilder()
                                   .UseKestrel()
                                   .UseWebRoot(wwwDirectory)
                                   .UseContentRoot(wwwDirectory)
                                   .UseUrls(Site.BaseUrl)
                                   .Configure(Configure);

                // Setup the environment
                // TODO: access to Site.Scripts.SiteFunctions.LunetObject is too long!
                hostBuilder.UseEnvironment(Site.Scripts.SiteFunctions.LunetObject.Environment ?? "Development");

                // Enable server log only if log.server = true
                if (Site.Scripts.SiteFunctions.LogObject.GetSafeValue <bool>("server"))
                {
                    hostBuilder.ConfigureServices(collection => collection.Add(ServiceDescriptor.Singleton(Site.LoggerFactory)));
                }

                var host = hostBuilder.Build();

                host.Run();
            }
            catch (Exception ex)
            {
                Site.Error($"Error while starting server. Reason: {ex.GetReason()}");
                return(1);
            }

            return(0);
        }
コード例 #11
0
ファイル: RegistryHttpServer.cs プロジェクト: i-Asset/basyx
 public void SetRegistryProvider(IAssetAdministrationShellRegistry aasRegistryProvider)
 {
     WebHostBuilder.ConfigureServices(services =>
     {
         services.AddSingleton <IAssetAdministrationShellRegistry>(aasRegistryProvider);
     });
 }
コード例 #12
0
        public async void Should_serve_hal_endpoints()
        {
            var streamStore = new InMemoryStreamStore();

            var builder = new WebHostBuilder();

            builder.ConfigureServices(services => services
                                      .AddSingleton <IStartup>(new TestStartup(streamStore)));

            var server = new TestServer(builder);
            var client = server.CreateClient();

            var request = new HttpRequestMessage()
            {
                RequestUri = new Uri("http://localhost/hal"),
                Method     = HttpMethod.Get,
            };

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/hal+json"));

            var halResponse = await client.SendAsync(request);

            var content = await halResponse.Content.ReadAsStringAsync();

            Assert.Equal(HttpStatusCode.OK, halResponse.StatusCode);
            Assert.Contains("provider", content);
            Assert.Contains("InMemory", content);
        }
コード例 #13
0
        public static void Main(string[] args)
        {
            var configurationBuilder = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
                                       .SetBasePath(Directory.GetCurrentDirectory())
                                       .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                                       .AddJsonFile("appsettings.Development.json", true, false)
                                       .AddJsonFile("appsettings.Production.json", true, false)
                                       .AddEnvironmentVariables()
                                       .AddCommandLine(args);

            if (args != null)
            {
                configurationBuilder.AddCommandLine(args);
            }
            var hostingconfig = configurationBuilder.Build();
            var url           = hostingconfig[addressKey] ?? defaultAddress;

            IWebHostBuilder builder = new WebHostBuilder();

            builder.ConfigureServices(s => {
                s.AddSingleton(builder);
            });
            builder.UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseConfiguration(hostingconfig)
            .UseIISIntegration()
            .UseUrls(url)
            .UseStartup <Startup>();
            var host = builder.Build();

            host.Run();
        }
コード例 #14
0
        private string Start(string assemblyName)
        {
            var builder = new WebHostBuilder()
                          .UseContentRoot(Directory.GetCurrentDirectory())
                          .UseUrls(this.BaseHost)
                          .UseKestrel()
                          .UseStartup(assemblyName)
                          .UseEnvironment("Production");

            builder.ConfigureServices(services =>
            {
                services.AddSingleton <IApplicationIdProvider>(provider =>
                                                               new DictionaryApplicationIdProvider()
                {
                    Defined = new Dictionary <string, string> {
                        [IKey] = AppId
                    }
                });
            });

            if (this.configureHost != null)
            {
                builder = this.configureHost(builder);
            }

            this.hostingEngine = builder.Build();
            this.hostingEngine.Start();

            this.ApplicationServices = this.hostingEngine.Services;

            return(((EndpointAddress)this.hostingEngine.Services.GetService <EndpointAddress>()).ConnectionString);
        }
        private static TestServer CreateAuthorizationServer(Action <OpenIdConnectServerOptions> configuration = null)
        {
            var builder = new WebHostBuilder();

            builder.UseEnvironment("Testing");

            builder.ConfigureServices(services => services.AddAuthentication());

            builder.Configure(app =>
            {
                app.UseOpenIdConnectServer(options =>
                {
                    options.AllowInsecureHttp = true;

                    // Note: overriding the default data protection provider is not necessary for the tests to pass,
                    // but is useful to ensure unnecessary keys are not persisted in testing environments, which also
                    // helps make the unit tests run faster, as no registry or disk access is required in this case.
                    options.DataProtectionProvider = new EphemeralDataProtectionProvider(app.ApplicationServices);

                    // Run the configuration delegate
                    // registered by the unit tests.
                    configuration?.Invoke(options);
                });
            });

            return(new TestServer(builder));
        }
コード例 #16
0
 public void SetServiceProvider(IAssetAdministrationShellServiceProvider aasServiceProvider)
 {
     WebHostBuilder.ConfigureServices(services =>
     {
         services.AddSingleton <IAssetAdministrationShellServiceProvider>(aasServiceProvider);
     });
 }
コード例 #17
0
ファイル: Program.cs プロジェクト: emmatex/Library-1
        public static void Main(string[] args)
        {
            IWebHostBuilder builder = new WebHostBuilder();

            builder.ConfigureServices(s => {
                s.AddSingleton(builder);
            });

            builder
            .UseKestrel()
            .UseUrls("http://*:4999")
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
                var env = hostingContext.HostingEnvironment;
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                config.AddJsonFile("configuration.json");
                config.AddEnvironmentVariables();
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
            })
            .UseStartup <Startup>();

            var host = builder.Build();

            host.Run();
        }
コード例 #18
0
        public async Task GetException_WhenDeveloperPageIsConfigured_ShouldBeInternalServerError()
        {
            // Arrange
            var builder = new WebHostBuilder();

            builder.ConfigureServices(services =>
            {
                services.AddRouting();
            });
            builder.Configure(app => app
                              .UseDeveloperExceptionPage()
                              .UseRouting()
                              .UseEndpoints(endpoints =>
            {
                endpoints.Map("/exception", context =>
                {
                    throw new Exception("Wow!", new Exception("Exactly!"));
                });
            }));
            using var testServer = new TestServer(builder);
            using var client     = testServer.CreateClient();

            // Act
            using var response = await client.GetAsync("/exception");

            // Assert
            response.Should().Be500InternalServerError();
        }
コード例 #19
0
        public static WebHostBuilder UseProjectOf <TStartup>(this WebHostBuilder builder)
        {
            var startupAssembly = typeof(TStartup).GetTypeInfo().Assembly;
            var applicationName = startupAssembly.GetName().Name;
            var webRoot         = GetProjectDirectoryOf(startupAssembly);

            builder.ConfigureServices(services =>
            {
                var hostingEnvironment = new HostingEnvironment();
                hostingEnvironment.Initialize(
                    applicationName,
                    webRoot,
                    new WebHostOptions
                {
                    Environment = "Production"
                });
                services.AddSingleton <IHostingEnvironment>(hostingEnvironment);

                var manager = new ApplicationPartManager();
                manager.ApplicationParts.Add(new AssemblyPart(startupAssembly));
                services.AddSingleton(manager);
            });

            return(builder);
        }
コード例 #20
0
        private static TestServer CreateResourceServer(Action <OpenIddictValidationBuilder> configuration = null)
        {
            var builder = new WebHostBuilder();

            builder.UseEnvironment("Testing");

            builder.ConfigureLogging(options => options.AddDebug());

            builder.ConfigureServices(services =>
            {
                services.AddAuthentication();
                services.AddOptions();
                services.AddDistributedMemoryCache();

                services.AddOpenIddict()
                .AddValidation(options => configuration?.Invoke(options));
            });

            builder.Configure(app =>
            {
                app.UseAuthentication();

                app.Run(context => context.ChallengeAsync(OpenIddictValidationDefaults.AuthenticationScheme));
            });

            return(new TestServer(builder));
        }
コード例 #21
0
 public async Task StartFakeOcelotWithWebSockets()
 {
     _ocelotBuilder = new WebHostBuilder();
     _ocelotBuilder.ConfigureServices(s =>
     {
         s.AddSingleton(_ocelotBuilder);
         s.AddOcelot();
     });
     _ocelotBuilder.UseKestrel()
     .UseUrls("http://localhost:5000")
     .UseContentRoot(Directory.GetCurrentDirectory())
     .ConfigureAppConfiguration((hostingContext, config) =>
     {
         config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
         var env = hostingContext.HostingEnvironment;
         config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
         .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
         config.AddJsonFile("ocelot.json", false, false);
         config.AddEnvironmentVariables();
     })
     .ConfigureLogging((hostingContext, logging) =>
     {
         logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
         logging.AddConsole();
     })
     .Configure(app =>
     {
         app.UseWebSockets();
         app.UseOcelot().Wait();
     })
     .UseIISIntegration();
     _ocelotHost = _ocelotBuilder.Build();
     await _ocelotHost.StartAsync();
 }
コード例 #22
0
    static async Task Main()
    {
        var webHostBuilder = new WebHostBuilder();

        webHostBuilder.UseKestrel();
        webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory());

        #region ServiceProviderFactoryAutofac

        webHostBuilder.ConfigureServices(services => services.AddAutofac());

        #endregion
        webHostBuilder.UseStartup <Startup>();
        var host = webHostBuilder.Build();
        await host.StartAsync()
        .ConfigureAwait(false);

        var serverAddresses = host.ServerFeatures.Get <IServerAddressesFeature>();
        var address         = serverAddresses.Addresses.First();
        Console.WriteLine($"Now listening on: {address}");
        Console.WriteLine("Press any key to shutdown");

        AttemptToLaunchBrowser(address);

        Console.ReadKey();
        await host.StopAsync()
        .ConfigureAwait(false);
    }
コード例 #23
0
        public TicketResourceSampleSite(string resource)
        {
            var webhostbuilder = new WebHostBuilder();

            webhostbuilder
            .ConfigureServices(services => {
                services.AddSingleton(_ => new State());
                services.AddSingleton(_ => new MapperConfiguration(cfg =>
                {
                    cfg.CreateMap <TicketCreateRequest, TicketResponse>()
                    .ForMember(r => r.Ticket, r => r.MapFrom(req => req));
                    cfg.CreateMap <TicketUpdateRequest, TicketResponse>()
                    .ForMember(r => r.Ticket, r => r.MapFrom(req => req));
                    cfg.CreateMap <TicketCreateRequest, Ticket>();
                    cfg.CreateMap <TicketUpdateRequest, Ticket>();
                }).CreateMapper());
                services.AddRouting();
                services.AddMemoryCache();
            })
            .Configure(app =>
            {
                app.UseRouter(MatchesRequest);
            });

            _server = new TestServer(webhostbuilder);

            RefreshClient(resource);
        }
コード例 #24
0
 public void SetServiceProvider(ISubmodelRepositoryServiceProvider submodelRepositoryServiceProvider)
 {
     WebHostBuilder.ConfigureServices(services =>
     {
         services.AddSingleton <ISubmodelRepositoryServiceProvider>(submodelRepositoryServiceProvider);
     });
 }
コード例 #25
0
ファイル: Program.cs プロジェクト: zhujinhu21/FamilyBucket
        /// <summary>
        /// 应用程序入口点
        /// </summary>
        /// <param name="args">入口点参数</param>
        public static void Main(string[] args)
        {
            IWebHostBuilder builder = new WebHostBuilder();

            builder.ConfigureServices(s =>
            {
                s.AddSingleton(builder);
            });

            // 默认配置
            var config = new ConfigurationBuilder()
                         .SetBasePath(Directory.GetCurrentDirectory())
                         .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                         .AddCommandLine(args)      // 添加对命令参数的支持
                         .AddEnvironmentVariables() // 添加环境变量
                         .Build();

            builder.UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup <Startup>()
            .UseConfiguration(config)
            .Build()
            .Run();
        }
コード例 #26
0
        public async Task TestExceptionLogger()
        {
            var hostBuilder = new WebHostBuilder();

            hostBuilder
            .ConfigureServices(collection =>
            {
                collection.AddSidExceptionHandler();
            })
            .Configure(app =>
            {
                var options = new ExceptionHandlerOptions {
                    ClientExceptionEnabled = true
                };

                app.UseSidExceptionHandler(options);
            });

            using (var testServer = new TestServer(hostBuilder))
            {
                var response = await testServer.CreateRequest("/exception/client").GetAsync();

                Assert.Equal(400, (int)response.StatusCode);

                response = await testServer.CreateRequest("/exception/client").PostAsync();

                Assert.True(response.IsSuccessStatusCode);
            }
        }
コード例 #27
0
        public TestFixture()
        {
            var builder = new WebHostBuilder()
                          .UseEnvironment("Testing")
                          .UseStartup <CleanArchitecture.Web.Startup>();

            builder.ConfigureServices(services =>
            {
                // Create a new service provider.
                var serviceProvider = new ServiceCollection()
                                      .AddEntityFrameworkInMemoryDatabase()
                                      .BuildServiceProvider();

                // Add a database context (ApplicationDbContext) using an in-memory
                // database for testing.
                services.AddDbContext <NorthwindDbContext>(options =>
                {
                    options.UseInMemoryDatabase("InMemoryDbForTesting");
                    options.UseInternalServiceProvider(serviceProvider);
                });
            });


            var server = new TestServer(builder);

            Context = server.Host.Services.GetService(typeof(NorthwindDbContext)) as NorthwindDbContext;
            Client  = server.CreateClient();

            NorthwindInitializer.Initialize(Context);
            Context.SaveChanges();
        }
コード例 #28
0
        public void Background()
        {
            "Server is running".x(() =>
            {
                var serverHostBuilder = new WebHostBuilder();
                serverHostBuilder
                .ConfigureServices(s
                                   => s
                                   .AddSingleton(new UserStoryEditor()))
                .UseStartup <Startup>();

                this.server = new TestServer(serverHostBuilder);
            })
            .Teardown(() =>
            {
                this.server.Dispose();
            });

            "client is connected to server".x(() =>
            {
                var httpClient         = this.server.CreateClient();
                httpClient.BaseAddress = new Uri("http://localhost/api/");

                this.Client = new WebsiteHttpClient(
                    httpClient);
            })
            .Teardown(() =>
            {
                this.Client.Dispose();
            });
        }
コード例 #29
0
        public static IWebHost BuildWebHost(string[] args)
        {
            var    startUrl = new ConfigurationBuilder().AddCommandLine(args).Build();
            string url      = string.Empty;

            if (startUrl != null && !string.IsNullOrEmpty(startUrl["scheme"]))
            {
                url = $"{startUrl["scheme"]}://{startUrl["ip"]}:{startUrl["port"]}";
            }
            IWebHostBuilder builder = new WebHostBuilder();

            //注入WebHostBuilder
            return(builder.ConfigureServices(service =>
            {
                service.AddSingleton(builder);
            })
                   //加载configuration配置文人年
                   .ConfigureAppConfiguration(conbuilder =>
            {
                conbuilder.AddJsonFile("appsettings.json");
                conbuilder.AddJsonFile("ocelot.json");
            })
                   .UseKestrel()
                   .UseUrls(string.IsNullOrEmpty(url) ? "http://*:5000" : url)
                   .UseStartup <Startup>()
                   .Build());
        }
コード例 #30
0
        public void CreateServerAndClient()
        {
            IWebHostBuilder webhostBuilder = new WebHostBuilder();

            webhostBuilder.ConfigureServices(InitialServiceConfiguration);
            webhostBuilder = webhostBuilder.UseContentRoot("..\\..\\..\\..\\..\\netmockery").UseStartup <Startup>();
            server         = new TestServer(webhostBuilder);
            client         = server.CreateClient();
        }