From 0e26ada711bf057ac4df938a20e3aae7e627677a Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:04:21 -1000 Subject: [PATCH 01/12] Update secure-data.md --- aspnetcore/security/authorization/secure-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authorization/secure-data.md b/aspnetcore/security/authorization/secure-data.md index 7ca5a8c0e54e..1a8725377a8c 100644 --- a/aspnetcore/security/authorization/secure-data.md +++ b/aspnetcore/security/authorization/secure-data.md @@ -68,7 +68,7 @@ This tutorial is advanced. You should be familiar with: [Download](xref:index#how-to-download-a-sample) the [completed](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/security/authorization/secure-data/samples) app. [Test](#test-the-completed-app) the completed app so you become familiar with its security features. > [!TIP] -> Use [`git sparse-checkout`](https://git-scm.com/docs/git-sparse-checkout) to only download the sample subfolder +> Use [`git sparse-checkout`](https://git-scm.com/docs/git-sparse-checkout) to only download the sample subfolder. For example: ``` git clone --depth 1 --filter=blob:none https://github.com/dotnet/AspNetCore.Docs.git --sparse From eebdeab1195b1d17f750d43cdea0a4322f1f36bc Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:56:02 -0500 Subject: [PATCH 02/12] Blazor movie tutorial QuickGrid styling (#34227) --- aspnetcore/blazor/components/quickgrid.md | 26 +++++++++-- .../tutorials/movie-database-app/part-8.md | 42 +++++++++++++++++- .../part-8/_static/styled-quickgrid.png | Bin 0 -> 127819 bytes 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png diff --git a/aspnetcore/blazor/components/quickgrid.md b/aspnetcore/blazor/components/quickgrid.md index bdf0348b5707..c68b5895f426 100644 --- a/aspnetcore/blazor/components/quickgrid.md +++ b/aspnetcore/blazor/components/quickgrid.md @@ -138,7 +138,25 @@ To provide a UI for pagination, add a [`Paginator` component](xref:Microsoft.Asp In the running app, page through the items using a rendered `Paginator` component. -QuickGrid renders additional empty rows to fill in the final page of data when used with a `Paginator` component. In .NET 9 or later, empty data cells (``) are added to the empty rows. The empty rows are intended to facilitate rendering the QuickGrid with stable row height and styling across all pages. You can apply styles to the rows using [CSS isolation](xref:blazor/components/css-isolation) by wrapping the `QuickGrid` component in a wrapper element, such as a `
`, and applying a row style with `::deep` [pseudo-elements](https://developer.mozilla.org/docs/Web/CSS/Pseudo-elements): +QuickGrid renders additional empty rows to fill in the final page of data when used with a `Paginator` component. In .NET 9 or later, empty data cells (``) are added to the empty rows. The empty rows are intended to facilitate rendering the QuickGrid with stable row height and styling across all pages. + +## Apply row styles + +Apply styles to rows using [CSS isolation](xref:blazor/components/css-isolation), which can include styling empty rows for `QuickGrid` components that [page data with a `Paginator` component](#page-items-with-a-paginator-component). + +Wrap the `QuickGrid` component in a wrapper block element, for example a `
`: + +```diff ++
+ + ... + ++
+``` + +Apply a row style with the `::deep` [pseudo-element](https://developer.mozilla.org/docs/Web/CSS/Pseudo-elements). In the following example, row height is set to `2em`, including for empty data rows. + +`{COMPONENT}.razor.css`: ```css ::deep tr { @@ -146,10 +164,10 @@ QuickGrid renders additional empty rows to fill in the final page of data when u } ``` -To hide the empty row data cells rendered by the QuickGrid, use CSS styling. In the following isolated CSS styles: +Alternatively, use the following CSS styling approach: -* Row cells populated with data are displayed. -* Empty row data cells aren't displayed, which avoids empty row cell borders from rendering per Bootstrap styling. +* Display row cells populated with data. +* Don't display empty row cells, which avoids empty row cell borders from rendering per Bootstrap styling. `{COMPONENT}.razor.css`: diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8.md b/aspnetcore/blazor/tutorials/movie-database-app/part-8.md index 63a076d72492..f3423ed01670 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-8.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-8.md @@ -118,11 +118,11 @@ Run the app and navigate to the movies `Index` page. You can page through the mo The component is *interactive*. The page doesn't reload for paging to occur. The paging is performed live over the SignalR connection between the browser and the server, where the paging operation is performed on the server with the rendered result sent back to the client for the browser to display. -Change to a more reasonable value, such as 10 items per page: +Change to a more reasonable value, such as five items per page: ```diff - private PaginationState pagination = new PaginationState { ItemsPerPage = 2 }; -+ private PaginationState pagination = new PaginationState { ItemsPerPage = 10 }; ++ private PaginationState pagination = new PaginationState { ItemsPerPage = 5 }; ``` ## Sortable `QuickGrid` @@ -199,6 +199,44 @@ Filtering database records is performed on the server, and the server interactiv Instead of an HTML form, submitting a GET request in this scenario could've also used JavaScript to submit the request to the server, either using the [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API)` or [XMLHttpRequest API](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest). In most cases, JavaScript can be replaced by using Blazor and C# in an interactive component. +## Style the `QuickGrid` component + +You can apply styles to the rendered `QuickGrid` component with a stylesheet isolated to the `Index` component using *CSS isolation*. + +CSS isolation is applied by adding a stylesheet file using the file name format `{COMPONENT NAME}.razor.css`, where the `{COMPONENT NAME}` placeholder is the component name. + +To apply styles to a child component, such as the `QuickGrid` component of the `Index` component, use the `::deep` pseudo-element. + +In the `MoviePages` folder, add the following stylesheet for the `Index` component. Use `::deep` pseudo-elements to make the row height `3em` and vertically center the table cell content. + +`Components/Pages/MoviePages/Index.razor.css`: + +```css +::deep tr { + height: 3em; +} + + ::deep tr > td { + vertical-align: middle; + } +``` + +The `::deep` pseudo-element only works with descendant elements, so the `QuickGrid` component must be wrapped with a `
` or some other block-level element in order to apply the styles to it. + +In `Components/Pages/MoviePages/Index.razor`, place `
` tags around the `QuickGrid` component: + +```diff ++
+ + ... + ++
+``` + +Blazor rewrites CSS selectors to match the markup rendered by the component. The rewritten CSS styles are bundled and produced as a static asset, so you don't need to take further action to apply the styles to the rendered `QuickGrid` component. + +![Movie list showing row heights at 3em with vertically-centered content](~/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png) + ## Clean up :::zone pivot="vs" diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png new file mode 100644 index 0000000000000000000000000000000000000000..410a8e834f630d0646834e50976a8d31a994310a GIT binary patch literal 127819 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 literal 0 HcmV?d00001 From 05a56d79e700d8b7bdecdfc6096b608d1b1f1577 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:03:01 -0500 Subject: [PATCH 03/12] Swap video link (#34274) --- aspnetcore/blazor/test.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/aspnetcore/blazor/test.md b/aspnetcore/blazor/test.md index e1b60f2428be..338a11e2cad6 100644 --- a/aspnetcore/blazor/test.md +++ b/aspnetcore/blazor/test.md @@ -163,7 +163,5 @@ The following actions take place at each step of the test: ## Additional resources - - * [Getting Started with bUnit](https://bunit.dev/docs/getting-started/): bUnit instructions include guidance on creating a test project, referencing testing framework packages, and building and running tests. -* [How to create maintainable and testable Blazor components - Egil Hansen - NDC Oslo 2022](https://www.youtube.com/watch?v=L_n-12FglLI) +* [Blazor Testing from A to Z - Egil Hansen - Swetugg Stockholm 2024](https://youtu.be/GU_XbWjrP_g?si=1SrjeaP1T9LdFegN) ([Swetugg](https://www.swetugg.se/sthlm-2025)) From aebcf12165f5000232642f7e2f20b0f638efee69 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:20:46 -0500 Subject: [PATCH 04/12] Blazor 9.0 updates (#34277) --- aspnetcore/blazor/file-uploads.md | 16 +++++----------- aspnetcore/blazor/host-and-deploy/server.md | 7 +------ aspnetcore/blazor/hybrid/class-libraries.md | 15 +++++---------- .../blazor/hybrid/reuse-razor-components.md | 10 +++------- .../blazor/security/blazor-web-app-with-oidc.md | 5 ----- aspnetcore/blazor/security/index.md | 4 ---- .../tutorials/movie-database-app/part-2.md | 2 +- 7 files changed, 15 insertions(+), 44 deletions(-) diff --git a/aspnetcore/blazor/file-uploads.md b/aspnetcore/blazor/file-uploads.md index bd021fb4e90b..98edb37d3620 100644 --- a/aspnetcore/blazor/file-uploads.md +++ b/aspnetcore/blazor/file-uploads.md @@ -259,15 +259,15 @@ public class UploadResult A security best practice for production apps is to avoid sending error messages to clients that might reveal sensitive information about an app, server, or network. Providing detailed error messages can aid a malicious user in devising attacks on an app, server, or network. The example code in this section only sends back an error code number (`int`) for display by the component client-side if a server-side error occurs. If a user requires assistance with a file upload, they provide the error code to support personnel for support ticket resolution without ever knowing the exact cause of the error. - + The following `LazyBrowserFileStream` class defines a custom stream type that lazily calls just before the first bytes of the stream are requested. The stream isn't transmitted from the browser to the server until reading the stream begins in .NET. `LazyBrowserFileStream.cs`: - + - + :::moniker range=">= aspnetcore-8.0" @@ -332,7 +332,7 @@ The following `FileUpload2` component: :::moniker-end - + :::moniker range=">= aspnetcore-8.0" @@ -909,10 +909,6 @@ For more information on SignalR configuration and how to set - Blazor relies on set to 1, which is the default value. Increasing the value leads to a high probability that `CopyTo` operations throw `System.InvalidOperationException: 'Reading is not allowed after reader was completed.'`. For more information, see [MaximumParallelInvocationsPerClient > 1 breaks file upload in Blazor Server mode (`dotnet/aspnetcore` #53951)](https://github.com/dotnet/aspnetcore/issues/53951). @@ -925,13 +921,11 @@ The line that calls - * Using the [Autofac Inversion of Control (IoC) container](https://autofac.org/) instead of the built-in ASP.NET Core dependency injection container. To resolve the issue, set to `true` in the [server-side circuit handler hub options](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). For more information, see [FileUpload: Did not receive any data in the allotted time (`dotnet/aspnetcore` #38842)](https://github.com/dotnet/aspnetcore/issues/38842#issuecomment-1342540950). * Not reading the stream to completion. This isn't a framework issue. Trap the exception and investigate it further in your local environment/network. - diff --git a/aspnetcore/blazor/host-and-deploy/server.md b/aspnetcore/blazor/host-and-deploy/server.md index 5837da0ee65b..6a83dcad6340 100644 --- a/aspnetcore/blazor/host-and-deploy/server.md +++ b/aspnetcore/blazor/host-and-deploy/server.md @@ -95,12 +95,7 @@ The service isn't required for Blazor apps hosted in Azure App Service or Azure :::moniker range=">= aspnetcore-8.0" - - -> [!NOTE] -> [Stateful reconnect](xref:signalr/configuration#configure-stateful-reconnect) () was released with .NET 8 but isn't currently supported for the Azure SignalR Service. For more information, see [Stateful Reconnect Support? (`Azure/azure-signalr` #1878)](https://github.com/Azure/azure-signalr/issues/1878). +The Azure SignalR Service with SDK [v1.26.1](https://github.com/Azure/azure-signalr/releases/tag/v1.26.1) or later supports [SignalR stateful reconnect](xref:signalr/configuration#configure-stateful-reconnect) (). :::moniker-end diff --git a/aspnetcore/blazor/hybrid/class-libraries.md b/aspnetcore/blazor/hybrid/class-libraries.md index fb08e780b616..431a8ed30b02 100644 --- a/aspnetcore/blazor/hybrid/class-libraries.md +++ b/aspnetcore/blazor/hybrid/class-libraries.md @@ -48,25 +48,20 @@ For more information, see the following articles: :::moniker-end - +* [.NET Aspire](/dotnet/aspire/get-started/aspire-overview) +* [Docker](https://docs.docker.com/get-started/docker-overview/) ## Share web UI Razor components, code, and static assets diff --git a/aspnetcore/blazor/hybrid/reuse-razor-components.md b/aspnetcore/blazor/hybrid/reuse-razor-components.md index 82634f78fa05..75ea893d2936 100644 --- a/aspnetcore/blazor/hybrid/reuse-razor-components.md +++ b/aspnetcore/blazor/hybrid/reuse-razor-components.md @@ -75,12 +75,8 @@ For an example, see +* eShop Reference Application (AdventureWorks): The .NET MAUI Blazor Hybrid app is in the `src/HybridApp` folder. + * For Azure hosting: [`Azure-Samples/eShopOnAzure` GitHub repository](https://github.com/Azure-Samples/eShopOnAzure) + * For general non-Azure hosting: [`dotnet/eShop` GitHub repository](https://github.com/dotnet/eShop). diff --git a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md index fc054b6b4382..b7e3e09e0f2b 100644 --- a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md +++ b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md @@ -731,11 +731,6 @@ At this point, Razor components can adopt [role-based and policy-based authoriza Use the guidance in this section to implement application roles, ME-ID security groups, and ME-ID built-in administrator roles for apps using [Microsoft Entra ID (ME-ID)](https://www.microsoft.com/security/business/microsoft-entra). - - The approach described in this section configures ME-ID to send groups and roles in the authentication cookie header. When users are only a member of a few security groups and roles, the following approach should work for most hosting platforms without running into a problem where headers are too long, for example with IIS hosting that has a default header length limit of 16 KB (`MaxRequestBytes`). If header length is a problem due to high group or role membership, we recommend not following the guidance in this section in favor of implementing [Microsoft Graph](/graph/sdks/sdks-overview) to obtain a user's groups and roles from ME-ID separately, an approach that doesn't inflate the size of the authentication cookie. For more information, see [Bad Request - Request Too Long - IIS Server (`dotnet/aspnetcore` #57545)](https://github.com/dotnet/aspnetcore/issues/57545). Configure the role claim type () in of `Program.cs`. Set the value to `roles`: diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md index d560d199154e..6162f9d67a77 100644 --- a/aspnetcore/blazor/security/index.md +++ b/aspnetcore/blazor/security/index.md @@ -283,10 +283,6 @@ For a description on how global interactive render modes are applied to non-Iden For more information on persisting prerendered state, see . - - -For more information on the Blazor Identity UI and guidance on integrating external logins through social websites, see [What's new with identity in .NET 8](https://devblogs.microsoft.com/dotnet/whats-new-with-identity-in-dotnet-8/#the-blazor-identity-ui). - [!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)] ### Manage authentication state in Blazor Web Apps diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2.md b/aspnetcore/blazor/tutorials/movie-database-app/part-2.md index 1dc5afc78f2e..38cffb270f7d 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-2.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-2.md @@ -417,7 +417,7 @@ When you select the **:::no-loc text="Create":::** button, the movie data is pos :::moniker range=">= aspnetcore-9.0" - + :::zone pivot="vs" From e3a1591c959e3319f5a1988ef0a3d2395b5b4882 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 3 Dec 2024 13:53:16 -0800 Subject: [PATCH 05/12] Link to /dotnet/core/deploying (#34254) --- aspnetcore/host-and-deploy/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aspnetcore/host-and-deploy/index.md b/aspnetcore/host-and-deploy/index.md index bf9e221c2805..864365b7145f 100644 --- a/aspnetcore/host-and-deploy/index.md +++ b/aspnetcore/host-and-deploy/index.md @@ -111,6 +111,7 @@ Use Health Check Middleware to perform health checks on an app and its dependenc ## Additional resources +* [.NET application publishing overview](/dotnet/core/deploying) * * [ASP.NET Hosting](https://dotnet.microsoft.com/apps/aspnet/hosting) @@ -184,6 +185,7 @@ For more information, see . ## Additional resources +* [.NET application publishing overview](/dotnet/core/deploying) * * [ASP.NET Hosting](https://dotnet.microsoft.com/apps/aspnet/hosting) From 45bd5456d9c9f08f5f1f57e1af995951d6ee0e21 Mon Sep 17 00:00:00 2001 From: Robert Haken Date: Wed, 4 Dec 2024 00:47:12 +0100 Subject: [PATCH 06/12] [Blazor] Performance - Change detection - set parameters only (#34281) --- aspnetcore/blazor/performance.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/performance.md b/aspnetcore/blazor/performance.md index 71661280723f..7bdcf7d00048 100644 --- a/aspnetcore/blazor/performance.md +++ b/aspnetcore/blazor/performance.md @@ -35,10 +35,23 @@ The last two steps of the preceding sequence continue recursively down the compo To prevent rendering recursion into a particular subtree, use either of the following approaches: -* Ensure that child component parameters are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. +:::moniker range=">= aspnetcore-9.0" + +* Ensure that the set parameters of child components are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. Only the parameters that are explicitly set on the component are considered for change detection. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. +* Override : + * To accept nonprimitive parameter values, such as complex custom model types or values. + * If authoring a UI-only component that doesn't change after the initial render, regardless of parameter value changes. + +:::moniker-end + +:::moniker range="< aspnetcore-9.0" + +* Ensure that the set parameters of child components are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. Only the parameters that are explicitly set on the component are considered for change detection. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. * Override : * To accept nonprimitive parameter values, such as complex custom model types, event callbacks, or values. * If authoring a UI-only component that doesn't change after the initial render, regardless of parameter value changes. + +:::moniker-end The following airline flight search tool example uses private fields to track the necessary information to detect changes. The previous inbound flight identifier (`prevInboundFlightId`) and previous outbound flight identifier (`prevOutboundFlightId`) track information for the next potential component update. If either of the flight identifiers change when the component's parameters are set in [`OnParametersSet`](xref:blazor/components/lifecycle#after-parameters-are-set-onparameterssetasync), the component is rerendered because `shouldRender` is set to `true`. If `shouldRender` evaluates to `false` after checking the flight identifiers, an expensive rerender is avoided: From e663fdf1f1b594a4f66b3e686ad01e9cf3660049 Mon Sep 17 00:00:00 2001 From: Robert Haken Date: Wed, 4 Dec 2024 00:52:49 +0100 Subject: [PATCH 07/12] [Blazor] Performance - IsFixed=true for `this` explanation (#34292) --- aspnetcore/blazor/performance.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/aspnetcore/blazor/performance.md b/aspnetcore/blazor/performance.md index 7bdcf7d00048..ba15a20f3584 100644 --- a/aspnetcore/blazor/performance.md +++ b/aspnetcore/blazor/performance.md @@ -35,23 +35,10 @@ The last two steps of the preceding sequence continue recursively down the compo To prevent rendering recursion into a particular subtree, use either of the following approaches: -:::moniker range=">= aspnetcore-9.0" - -* Ensure that the set parameters of child components are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. Only the parameters that are explicitly set on the component are considered for change detection. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. -* Override : - * To accept nonprimitive parameter values, such as complex custom model types or values. - * If authoring a UI-only component that doesn't change after the initial render, regardless of parameter value changes. - -:::moniker-end - -:::moniker range="< aspnetcore-9.0" - -* Ensure that the set parameters of child components are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. Only the parameters that are explicitly set on the component are considered for change detection. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. +* Ensure that child component parameters are of primitive immutable types, such as `string`, `int`, `bool`, `DateTime`, and other similar types. The built-in logic for detecting changes automatically skips rerendering if the primitive immutable parameter values haven't changed. If you render a child component with ``, where `CustomerId` is an `int` type, then the `Customer` component isn't rerendered unless `item.CustomerId` changes. * Override : * To accept nonprimitive parameter values, such as complex custom model types, event callbacks, or values. * If authoring a UI-only component that doesn't change after the initial render, regardless of parameter value changes. - -:::moniker-end The following airline flight search tool example uses private fields to track the necessary information to detect changes. The previous inbound flight identifier (`prevInboundFlightId`) and previous outbound flight identifier (`prevOutboundFlightId`) track information for the next potential component update. If either of the flight identifiers change when the component's parameters are set in [`OnParametersSet`](xref:blazor/components/lifecycle#after-parameters-are-set-onparameterssetasync), the component is rerendered because `shouldRender` is set to `true`. If `shouldRender` evaluates to `false` after checking the flight identifiers, an expensive rerender is avoided: @@ -261,7 +248,7 @@ The [`CascadingValue` component](xref:blazor/components/cascading-values-and-par Setting `IsFixed` to `true` improves performance if there are a large number of other components that receive the cascaded value. Wherever possible, set `IsFixed` to `true` on cascaded values. You can set `IsFixed` to `true` when the supplied value doesn't change over time. -Where a component passes `this` as a cascaded value, `IsFixed` can also be set to `true`: +Where a component passes `this` as a cascaded value, `IsFixed` can also be set to `true`, because `this` never changes during the component's lifecycle: ```razor From 3b26ce2d1cf46470da6c0b62635d05430ed0778e Mon Sep 17 00:00:00 2001 From: Robert Haken Date: Wed, 4 Dec 2024 12:31:33 +0100 Subject: [PATCH 08/12] [Blazor] Performance - Event callbacks in RenderFragments (#34293) --- aspnetcore/blazor/performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/performance.md b/aspnetcore/blazor/performance.md index ba15a20f3584..41a4c4229e06 100644 --- a/aspnetcore/blazor/performance.md +++ b/aspnetcore/blazor/performance.md @@ -195,7 +195,7 @@ public static RenderFragment SayHello = @

Hello!

; } ``` -The preceding approach reuses rendering logic without per-component overhead. However, the approach doesn't permit refreshing the subtree of the UI independently, nor does it have the ability to skip rendering the subtree of the UI when its parent renders because there's no component boundary. Assignment to a delegate is only supported in Razor component files (`.razor`), and [event callbacks](xref:blazor/components/event-handling#eventcallback) aren't supported. +The preceding approach reuses rendering logic without per-component overhead. However, the approach doesn't permit refreshing the subtree of the UI independently, nor does it have the ability to skip rendering the subtree of the UI when its parent renders because there's no component boundary. Assignment to a delegate is only supported in Razor component files (`.razor`). For a non-static field, method, or property that can't be referenced by a field initializer, such as `TitleTemplate` in the following example, use a property instead of a field for the : From 15149e82120b5388fcf84024456455b2674d7c60 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 4 Dec 2024 08:57:46 -1000 Subject: [PATCH 09/12] local is ambiguous in requiring two 2FA (#34298) * local is ambiguous in requiring two 2FA * Update aspnetcore/security/authentication/identity-enable-qrcodes.md * Update aspnetcore/security/authentication/identity-enable-qrcodes.md * Update aspnetcore/security/authentication/identity-enable-qrcodes.md Co-authored-by: Luke Latham <1622880+guardrex@users.noreply.github.com> --------- Co-authored-by: Luke Latham <1622880+guardrex@users.noreply.github.com> --- aspnetcore/security/authentication/identity-enable-qrcodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authentication/identity-enable-qrcodes.md b/aspnetcore/security/authentication/identity-enable-qrcodes.md index 754222afd22c..18bac2ffb26f 100644 --- a/aspnetcore/security/authentication/identity-enable-qrcodes.md +++ b/aspnetcore/security/authentication/identity-enable-qrcodes.md @@ -27,7 +27,7 @@ The ASP.NET Core web app templates support authenticators but don't provide supp :::moniker-end -Two-factor authentication does not happen using an external authentication provider, such as [Google](xref:security/authentication/google-logins) or [Facebook](xref:security/authentication/facebook-logins). External logins are protected by whatever mechanism the external login provider provides. Consider, for example, the [Microsoft](xref:security/authentication/microsoft-logins) authentication provider requires a hardware key or another 2FA approach. If the default templates enforced "local" 2FA then users would be required to satisfy two 2FA approaches, which is not a commonly used scenario. +Two-factor authentication does not happen using an external authentication provider, such as [Google](xref:security/authentication/google-logins) or [Facebook](xref:security/authentication/facebook-logins). External logins are protected by whatever mechanism the external login provider provides. Consider, for example, the [Microsoft](xref:security/authentication/microsoft-logins) authentication provider requires a hardware key or another 2FA approach. If the default templates required 2FA for both the web app and the external authentication provider, then users would be required to satisfy two 2FA approaches. Requiring two 2FA approaches deviates from established security practices, which typically rely on a single, strong 2FA method for authentication. ## Adding QR codes to the 2FA configuration page From 393d67605f11528a38547674d9b909669b187c2a Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:51:22 -1000 Subject: [PATCH 10/12] Update anti-request-forgery.md (#34257) * Update anti-request-forgery.md * Update aspnetcore/security/anti-request-forgery.md * Update aspnetcore/security/anti-request-forgery.md * Update aspnetcore/security/anti-request-forgery.md Co-authored-by: Tom Dykstra * Update anti-request-forgery.md --------- Co-authored-by: Tom Dykstra --- aspnetcore/security/anti-request-forgery.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/aspnetcore/security/anti-request-forgery.md b/aspnetcore/security/anti-request-forgery.md index 618522885c49..4e1a3481d0db 100644 --- a/aspnetcore/security/anti-request-forgery.md +++ b/aspnetcore/security/anti-request-forgery.md @@ -159,10 +159,7 @@ Calling Date: Thu, 5 Dec 2024 02:27:28 +0300 Subject: [PATCH 11/12] Add Localization Samples for .NET 8 (#34199) * Add Localization & PO Localization samples for .NET 8 * Update markdown files * Remove unnecessary files --- .../localization/make-content-localizable.md | 16 +- .../Controllers/AboutController.cs | 21 + .../Controllers/AccountController.cs | 468 + .../Controllers/BookController.cs | 66 + .../Controllers/HomeController.cs | 74 + .../Controllers/InfoController.cs | 70 + .../Controllers/ManageController.cs | 348 + .../Controllers/TestController.cs | 51 + .../8.x/Localization/Localization.csproj | 14 + .../Models/ApplicationDbContext.cs | 21 + .../Localization/Models/ApplicationUser.cs | 10 + .../sample/8.x/Localization/Program.cs | 84 + .../Controllers.AboutController.fr.resx | 123 + .../Controllers.BookController.fr.resx | 129 + .../Controllers.TestController.fr.resx | 129 + .../Controllers/HomeController.fr.resx | 129 + .../Controllers/InfoController.fr.resx | 129 + .../LocSample.SharedResource.fr.resx | 123 + .../Resources.SharedResource.fr.resx | 123 + .../Resources/SharedResource.fr.resx | 135 + .../Localization/Resources/StartUp.fr.resx | 129 + ...wModels.Account.RegisterViewModel2.fr.resx | 144 + .../Account/RegisterViewModel.fr.resx | 144 + .../Resources/Views.Home.About.fr.resx | 126 + .../Resources/Views.Info.About.fr.resx | 126 + .../Views.Shared._Layout.fr.Designer.cs | 98 + .../Resources/Views.Shared._Layout.fr.resx | 132 + .../Views.Shared._LoginPartial.fr.resx | 138 + ...iews.Shared._SelectLanguagePartial.fr.resx | 126 + .../Resources/Views.book.About.fr.resx | 126 + .../Resources/Views.book.Hello.fr.Designer.cs | 80 + .../Resources/Views.book.Hello.fr.resx | 126 + .../Resources/Views.test.About.fr.resx | 126 + .../Resources/Views/Account/Login.fr.resx | 141 + .../Resources/Views/Account/Register.fr.resx | 126 + .../Views/Book/Contact.fr.Designer.cs | 80 + .../Resources/Views/Book/Contact.fr.resx | 126 + .../Resources/Views/Book/Index.Designer.cs | 352 + .../Resources/Views/Book/Index.resx | 222 + .../Resources/Views/Home/About2.fr.resx | 126 + .../Views/Home/Contact.fr.Designer.cs | 80 + .../Resources/Views/Home/Contact.fr.resx | 126 + .../Resources/Views/Home/Index.fr.resx | 222 + .../Views/Info/Contact.fr.Designer.cs | 80 + .../Resources/Views/Info/Contact.fr.resx | 126 + .../Resources/Views/Info/Index.fr.resx | 222 + .../Views/Test/Contact.fr.Designer.cs | 80 + .../Resources/Views/Test/Contact.fr.resx | 126 + .../Resources/Views/Test/Index.fr.resx | 222 + .../8.x/Localization/Services/IEmailSender.cs | 12 + .../8.x/Localization/Services/ISmsSender.cs | 12 + .../Localization/Services/MessageServices.cs | 25 + .../sample/8.x/Localization/SharedResource.cs | 7 + .../ExternalLoginConfirmationViewModel.cs | 15 + .../Account/ForgotPasswordViewModel.cs | 15 + .../ViewModels/Account/LoginViewModel.cs | 22 + .../ViewModels/Account/RegisterViewModel.cs | 24 + .../Account/ResetPasswordViewModel.cs | 27 + .../ViewModels/Account/SendCodeViewModel.cs | 16 + .../ViewModels/Account/VerifyCodeViewModel.cs | 25 + .../Manage/AddPhoneNumberViewModel.cs | 16 + .../Manage/ChangePasswordViewModel.cs | 27 + .../Manage/ConfigureTwoFactorViewModel.cs | 12 + .../ViewModels/Manage/FactorViewModel.cs | 12 + .../ViewModels/Manage/IndexViewModel.cs | 21 + .../Manage/ManageLoginsViewModel.cs | 16 + .../ViewModels/Manage/RemoveLoginViewModel.cs | 14 + .../ViewModels/Manage/SetPasswordViewModel.cs | 22 + .../Manage/VerifyPhoneNumberViewModel.cs | 19 + .../Views/Account/ConfirmEmail.cshtml | 10 + .../Account/ExternalLoginConfirmation.cshtml | 35 + .../Views/Account/ExternalLoginFailure.cshtml | 8 + .../Views/Account/ForgotPassword.cshtml | 31 + .../Account/ForgotPasswordConfirmation.cshtml | 8 + .../Localization/Views/Account/Lockout.cshtml | 8 + .../Localization/Views/Account/Login.cshtml | 89 + .../Views/Account/Register.cshtml | 44 + .../Views/Account/ResetPassword.cshtml | 43 + .../Account/ResetPasswordConfirmation.cshtml | 8 + .../Views/Account/SendCode.cshtml | 21 + .../Views/Account/VerifyCode.cshtml | 38 + .../8.x/Localization/Views/Book/About.cshtml | 218 + .../Localization/Views/Book/Contact.cshtml | 21 + .../8.x/Localization/Views/Book/Hello.cshtml | 12 + .../8.x/Localization/Views/Book/Index.cshtml | 120 + .../8.x/Localization/Views/Home/About.cshtml | 11 + .../8.x/Localization/Views/Home/About2.cshtml | 11 + .../Localization/Views/Home/Contact.cshtml | 21 + .../8.x/Localization/Views/Home/Index.cshtml | 57 + .../8.x/Localization/Views/Info/About.cshtml | 12 + .../Localization/Views/Info/Contact.cshtml | 21 + .../8.x/Localization/Views/Info/Hello.cshtml | 11 + .../8.x/Localization/Views/Info/Index.cshtml | 120 + .../Views/Manage/AddPhoneNumber.cshtml | 27 + .../Views/Manage/ChangePassword.cshtml | 42 + .../Localization/Views/Manage/Index.cshtml | 77 + .../Views/Manage/ManageLogins.cshtml | 53 + .../Views/Manage/SetPassword.cshtml | 38 + .../Views/Manage/VerifyPhoneNumber.cshtml | 30 + .../Localization/Views/Shared/Error.cshtml | 6 + .../Localization/Views/Shared/_Layout.cshtml | 67 + .../Views/Shared/_LoginPartial.cshtml | 31 + .../Shared/_SelectLanguagePartial.cshtml | 27 + .../Shared/_ValidationScriptsPartial.cshtml | 8 + .../8.x/Localization/Views/Test/About.cshtml | 12 + .../Localization/Views/Test/Contact.cshtml | 21 + .../8.x/Localization/Views/Test/Hello.cshtml | 11 + .../8.x/Localization/Views/Test/Index.cshtml | 120 + .../Localization/Views/_ViewImports.cshtml | 6 + .../8.x/Localization/Views/_ViewStart.cshtml | 3 + .../sample/8.x/Localization/appsettings.json | 15 + .../wwwroot/css/bootstrap-3.3.7.css | 6757 ++++++++++ .../8.x/Localization/wwwroot/favicon.ico | Bin 0 -> 17174 bytes .../wwwroot/js/bootstrap-3.3.7.js | 2377 ++++ .../Localization/wwwroot/js/jquery-2.2.0.js | 9831 ++++++++++++++ .../wwwroot/js/jquery.validate-1.16.0.js | 1574 +++ .../js/jquery.validate.unobtrusive-3.2.6.js | 416 + .../8.x/POLocalization/POLocalization.csproj | 12 + .../8.x/POLocalization/Pages/Index.cshtml | 13 + .../8.x/POLocalization/Pages/Privacy.cshtml | 8 + .../Pages/Shared/_Layout.cshtml | 50 + .../Shared/_ValidationScriptsPartial.cshtml | 2 + .../POLocalization/Pages/_ViewImports.cshtml | 2 + .../POLocalization/Pages/_ViewStart.cshtml | 3 + .../sample/8.x/POLocalization/Program.cs | 39 + .../appsettings.Development.json | 10 + .../8.x/POLocalization/appsettings.json | 8 + .../sample/8.x/POLocalization/cs.po | 8 + .../sample/8.x/POLocalization/fr.po | 2 + .../POLocalization/wwwroot/css/bootstrap.css | 10038 ++++++++++++++ .../8.x/POLocalization/wwwroot/css/site.css | 74 + .../8.x/POLocalization/wwwroot/favicon.ico | Bin 0 -> 32038 bytes .../wwwroot/js/bootstrap.bundle.js | 7013 ++++++++++ .../POLocalization/wwwroot/js/bootstrap.js | 4435 +++++++ .../8.x/POLocalization/wwwroot/js/jquery.js | 10872 ++++++++++++++++ .../8.x/POLocalization/wwwroot/js/site.js | 1 + .../localization/select-language-culture.md | 8 +- 137 files changed, 61813 insertions(+), 12 deletions(-) create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AboutController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AccountController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/BookController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/HomeController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/InfoController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/ManageController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/TestController.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Localization.csproj create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationDbContext.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationUser.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Program.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.AboutController.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.BookController.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.TestController.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/HomeController.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/InfoController.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/LocSample.SharedResource.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Resources.SharedResource.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/SharedResource.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/StartUp.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels.Account.RegisterViewModel2.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels/Account/RegisterViewModel.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Home.About.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Info.About.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._LoginPartial.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._SelectLanguagePartial.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.About.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.test.About.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Login.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Register.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/About2.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Index.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Index.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.Designer.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Index.fr.resx create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/IEmailSender.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/ISmsSender.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/MessageServices.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/SharedResource.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ExternalLoginConfirmationViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ForgotPasswordViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/LoginViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/RegisterViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ResetPasswordViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/SendCodeViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/VerifyCodeViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/AddPhoneNumberViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ChangePasswordViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ConfigureTwoFactorViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/FactorViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/IndexViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ManageLoginsViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/RemoveLoginViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/SetPasswordViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/VerifyPhoneNumberViewModel.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ConfirmEmail.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginConfirmation.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginFailure.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPassword.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPasswordConfirmation.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Lockout.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Login.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Register.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPassword.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPasswordConfirmation.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/SendCode.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/VerifyCode.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/About.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Contact.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Hello.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About2.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Contact.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/About.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Contact.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Hello.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/AddPhoneNumber.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ChangePassword.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ManageLogins.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/SetPassword.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/VerifyPhoneNumber.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/Error.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_Layout.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_LoginPartial.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_SelectLanguagePartial.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/About.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Contact.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Hello.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewImports.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewStart.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/appsettings.json create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/css/bootstrap-3.3.7.css create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/favicon.ico create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/bootstrap-3.3.7.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery-2.2.0.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery.validate-1.16.0.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery.validate.unobtrusive-3.2.6.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/POLocalization.csproj create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/Index.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/Privacy.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/Shared/_Layout.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/Shared/_ValidationScriptsPartial.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/_ViewImports.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Pages/_ViewStart.cshtml create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/Program.cs create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/appsettings.Development.json create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/appsettings.json create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/cs.po create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/fr.po create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/css/bootstrap.css create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/css/site.css create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/favicon.ico create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/js/bootstrap.bundle.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/js/bootstrap.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/js/jquery.js create mode 100644 aspnetcore/fundamentals/localization/sample/8.x/POLocalization/wwwroot/js/site.js diff --git a/aspnetcore/fundamentals/localization/make-content-localizable.md b/aspnetcore/fundamentals/localization/make-content-localizable.md index 48eaa8ba225a..49c1ab0116fc 100644 --- a/aspnetcore/fundamentals/localization/make-content-localizable.md +++ b/aspnetcore/fundamentals/localization/make-content-localizable.md @@ -23,7 +23,7 @@ One task for localizing an app is to wrap localizable content with code that fac The following code example shows how to wrap the string "About Title" for localization. -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/Controllers/AboutController.cs)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/Controllers/AboutController.cs)] In the preceding code, the `IStringLocalizer` implementation comes from [Dependency Injection](~/fundamentals/dependency-injection.md). If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "About Title". @@ -35,7 +35,7 @@ Alternatively, you can use the traditional approach and provide a key to retriev Use the implementation for resources that contain HTML. HTML-encodes arguments that are formatted in the resource string, but doesn't HTML-encode the resource string itself. In the following highlighted code, only the value of the `name` parameter is HTML-encoded. -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/Controllers/BookController.cs?highlight=3,5,20&start=1&end=24)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/Controllers/BookController.cs?highlight=3,5,20&start=1&end=24)] ***NOTE:*** Generally, only localize text, not HTML. @@ -43,7 +43,7 @@ Use the implemen At the lowest level, can be retrieved from of [Dependency Injection](~/fundamentals/dependency-injection.md): -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/Controllers/TestController.cs?highlight=6-12&name=snippet_1)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/Controllers/TestController.cs?highlight=6-12&name=snippet_1)] The preceding code demonstrates each of the two factory create methods. @@ -51,17 +51,17 @@ The preceding code demonstrates each of the two factory create methods. You can partition your localized strings by controller or area, or have just one container. In the sample app, a marker class named `SharedResource` is used for shared resources. The marker class is never called: -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/SharedResource.cs)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/SharedResource.cs)] In the following sample, the `InfoController` and the `SharedResource` localizers are used: -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/Controllers/InfoController.cs?name=snippet_1)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/Controllers/InfoController.cs?name=snippet_1)] ## View localization The service provides localized strings for a [view](xref:mvc/views/overview). The `ViewLocalizer` class implements this interface and finds the resource location from the view file path. The following code shows how to use the default implementation of `IViewLocalizer`: -[!code-cshtml[](~/fundamentals/localization/sample/6.x/Localization/Views/Home/About.cshtml)] +[!code-cshtml[](~/fundamentals/localization/sample/8.x/Localization/Views/Home/About.cshtml)] The default implementation of `IViewLocalizer` finds the resource file based on the view's file name. There's no option to use a global shared resource file. `ViewLocalizer` implements the localizer using `IHtmlLocalizer`, so Razor doesn't HTML-encode the localized string. You can parameterize resource strings, and `IViewLocalizer` HTML-encodes the parameters but not the resource string. Consider the following Razor markup: @@ -81,7 +81,7 @@ Generally, ***only localize text***, not HTML. To use a shared resource file in a view, inject `IHtmlLocalizer`: -[!code-cshtml[](~/fundamentals/localization/sample/6.x/Localization/Views/Test/About.cshtml?highlight=5,12)] +[!code-cshtml[](~/fundamentals/localization/sample/8.x/Localization/Views/Test/About.cshtml?highlight=5,12)] ## DataAnnotations localization @@ -90,7 +90,7 @@ DataAnnotations error messages are localized with `IStringLocalizer`. Using t * *Resources/ViewModels.Account.RegisterViewModel.fr.resx* * *Resources/ViewModels/Account/RegisterViewModel.fr.resx* -[!code-csharp[](~/fundamentals/localization/sample/6.x/Localization/ViewModels/Account/RegisterViewModel.cs)] +[!code-csharp[](~/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/RegisterViewModel.cs)] Non-validation attributes are localized. diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AboutController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AboutController.cs new file mode 100644 index 000000000000..ba0f91e85aea --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AboutController.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; + +namespace Localization.Controllers; + +[Route("api/[controller]")] +public class AboutController : Controller +{ + private readonly IStringLocalizer _localizer; + + public AboutController(IStringLocalizer localizer) + { + _localizer = localizer; + } + + [HttpGet] + public string Get() + { + return _localizer["About Title"]; + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AccountController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AccountController.cs new file mode 100644 index 000000000000..bf3185ea2932 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/AccountController.cs @@ -0,0 +1,468 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.Extensions.Logging; +using Localization.Models; +using Localization.Services; +using Localization.ViewModels.Account; + +namespace Localization.Controllers +{ + [Authorize] + public class AccountController : Controller + { + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly IEmailSender _emailSender; + private readonly ISmsSender _smsSender; + private readonly ILogger _logger; + + public AccountController( + UserManager userManager, + SignInManager signInManager, + IEmailSender emailSender, + ISmsSender smsSender, + ILoggerFactory loggerFactory) + { + _userManager = userManager; + _signInManager = signInManager; + _emailSender = emailSender; + _smsSender = smsSender; + _logger = loggerFactory.CreateLogger(); + } + + // + // GET: /Account/Login + [HttpGet] + [AllowAnonymous] + public IActionResult Login(string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + return View(); + } + + // + // POST: /Account/Login + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Login(LoginViewModel model, string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + if (ModelState.IsValid) + { + // This doesn't count login failures towards account lockout + // To enable password failures to trigger account lockout, set lockoutOnFailure: true + var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); + if (result.Succeeded) + { + _logger.LogInformation(1, "User logged in."); + return RedirectToLocal(returnUrl); + } + if (result.RequiresTwoFactor) + { + return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); + } + if (result.IsLockedOut) + { + _logger.LogWarning(2, "User account locked out."); + return View("Lockout"); + } + else + { + ModelState.AddModelError(string.Empty, "Invalid login attempt."); + return View(model); + } + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // GET: /Account/Register + [HttpGet] + [AllowAnonymous] + public IActionResult Register(string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + return View(); + } + + // + // POST: /Account/Register + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Register(RegisterViewModel model, string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + if (ModelState.IsValid) + { + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await _userManager.CreateAsync(user, model.Password); + if (result.Succeeded) + { + // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 + // Send an email with this link + //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); + //await _emailSender.SendEmailAsync(model.Email, "Confirm your account", + // $"Please confirm your account by clicking this link: link"); + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation(3, "User created a new account with password."); + return RedirectToLocal(returnUrl); + } + AddErrors(result); + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // POST: /Account/LogOff + [HttpPost] + [ValidateAntiForgeryToken] + public async Task LogOff() + { + await _signInManager.SignOutAsync(); + _logger.LogInformation(4, "User logged out."); + return RedirectToAction(nameof(HomeController.Index), "Home"); + } + + // + // POST: /Account/ExternalLogin + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public IActionResult ExternalLogin(string provider, string returnUrl = null) + { + // Request a redirect to the external login provider. + var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }); + var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); + return Challenge(properties, provider); + } + + // + // GET: /Account/ExternalLoginCallback + [HttpGet] + [AllowAnonymous] + public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null) + { + if (remoteError != null) + { + ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}"); + return View(nameof(Login)); + } + var info = await _signInManager.GetExternalLoginInfoAsync(); + if (info == null) + { + return RedirectToAction(nameof(Login)); + } + + // Sign in the user with this external login provider if the user already has a login. + var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); + if (result.Succeeded) + { + _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider); + return RedirectToLocal(returnUrl); + } + if (result.RequiresTwoFactor) + { + return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl }); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } + else + { + // If the user does not have an account, then ask the user to create an account. + ViewData["ReturnUrl"] = returnUrl; + ViewData["LoginProvider"] = info.LoginProvider; + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email }); + } + } + + // + // POST: /Account/ExternalLoginConfirmation + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null) + { + if (ModelState.IsValid) + { + // Get the information about the user from the external login provider + var info = await _signInManager.GetExternalLoginInfoAsync(); + if (info == null) + { + return View("ExternalLoginFailure"); + } + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await _userManager.CreateAsync(user); + if (result.Succeeded) + { + result = await _userManager.AddLoginAsync(user, info); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider); + return RedirectToLocal(returnUrl); + } + } + AddErrors(result); + } + + ViewData["ReturnUrl"] = returnUrl; + return View(model); + } + + // GET: /Account/ConfirmEmail + [HttpGet] + [AllowAnonymous] + public async Task ConfirmEmail(string userId, string code) + { + if (userId == null || code == null) + { + return View("Error"); + } + var user = await _userManager.FindByIdAsync(userId); + if (user == null) + { + return View("Error"); + } + var result = await _userManager.ConfirmEmailAsync(user, code); + return View(result.Succeeded ? "ConfirmEmail" : "Error"); + } + + // + // GET: /Account/ForgotPassword + [HttpGet] + [AllowAnonymous] + public IActionResult ForgotPassword() + { + return View(); + } + + // + // POST: /Account/ForgotPassword + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ForgotPassword(ForgotPasswordViewModel model) + { + if (ModelState.IsValid) + { + var user = await _userManager.FindByNameAsync(model.Email); + if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) + { + // Don't reveal that the user does not exist or is not confirmed + return View("ForgotPasswordConfirmation"); + } + + // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 + // Send an email with this link + //var code = await _userManager.GeneratePasswordResetTokenAsync(user); + //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); + //await _emailSender.SendEmailAsync(model.Email, "Reset Password", + // $"Please reset your password by clicking here: link"); + //return View("ForgotPasswordConfirmation"); + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // GET: /Account/ForgotPasswordConfirmation + [HttpGet] + [AllowAnonymous] + public IActionResult ForgotPasswordConfirmation() + { + return View(); + } + + // + // GET: /Account/ResetPassword + [HttpGet] + [AllowAnonymous] + public IActionResult ResetPassword(string code = null) + { + return code == null ? View("Error") : View(); + } + + // + // POST: /Account/ResetPassword + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ResetPassword(ResetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await _userManager.FindByNameAsync(model.Email); + if (user == null) + { + // Don't reveal that the user does not exist + return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account"); + } + var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password); + if (result.Succeeded) + { + return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account"); + } + AddErrors(result); + return View(); + } + + // + // GET: /Account/ResetPasswordConfirmation + [HttpGet] + [AllowAnonymous] + public IActionResult ResetPasswordConfirmation() + { + return View(); + } + + // + // GET: /Account/SendCode + [HttpGet] + [AllowAnonymous] + public async Task SendCode(string returnUrl = null, bool rememberMe = false) + { + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user); + var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList(); + return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe }); + } + + // + // POST: /Account/SendCode + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task SendCode(SendCodeViewModel model) + { + if (!ModelState.IsValid) + { + return View(); + } + + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + + // Generate the token and send it + var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider); + if (string.IsNullOrWhiteSpace(code)) + { + return View("Error"); + } + + var message = "Your security code is: " + code; + if (model.SelectedProvider == "Email") + { + await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message); + } + else if (model.SelectedProvider == "Phone") + { + await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message); + } + + return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); + } + + // + // GET: /Account/VerifyCode + [HttpGet] + [AllowAnonymous] + public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null) + { + // Require that the user has already logged in via username/password or external login + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); + } + + // + // POST: /Account/VerifyCode + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task VerifyCode(VerifyCodeViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + // The following code protects for brute force attacks against the two factor codes. + // If a user enters incorrect codes for a specified amount of time then the user account + // will be locked out for a specified amount of time. + var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser); + if (result.Succeeded) + { + return RedirectToLocal(model.ReturnUrl); + } + if (result.IsLockedOut) + { + _logger.LogWarning(7, "User account locked out."); + return View("Lockout"); + } + else + { + ModelState.AddModelError(string.Empty, "Invalid code."); + return View(model); + } + } + + #region Helpers + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError(string.Empty, error.Description); + } + } + + private Task GetCurrentUserAsync() + { + return _userManager.GetUserAsync(HttpContext.User); + } + + private IActionResult RedirectToLocal(string returnUrl) + { + if (Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } + else + { + return RedirectToAction(nameof(HomeController.Index), "Home"); + } + } + + #endregion + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/BookController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/BookController.cs new file mode 100644 index 000000000000..11577232863e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/BookController.cs @@ -0,0 +1,66 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Localization; + +namespace Localization.Controllers; + +public class BookController : Controller +{ + private readonly IHtmlLocalizer _localizer; + + public BookController(IHtmlLocalizer localizer) + { + _localizer = localizer; + } + + public IActionResult Hello(string name) + { + ViewData["Message"] = _localizer["Hello {0}", name]; + + return View(); + } + + public IActionResult Index() + { + return View(); + } + + // Pass the requestCultureFeature and requestCulture objects to the view + // so we can get Culture/UICulture information. + + public IActionResult About() + { + IRequestCultureFeature requestCultureFeature = HttpContext.Features.Get(); + RequestCulture requestCulture = requestCultureFeature.RequestCulture; + ViewData["requestCultureFeature"] = requestCultureFeature; + ViewData["requestCulture"] = requestCulture; + ViewData["Message"] = _localizer["Your application description page."]; + + return View(); + } + + public IActionResult Contact() + { + ViewData["Message"] = _localizer["Your contact page."]; + return View(); + } + + [HttpPost] + public IActionResult SetLanguage(string culture, string returnUrl) + { + Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), + new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } + ); + + return LocalRedirect(returnUrl); + } + + public IActionResult Error() + { + return View(); + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/HomeController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/HomeController.cs new file mode 100644 index 000000000000..10c063618fb5 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/HomeController.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; + +namespace Localization.Controllers +{ + public class HomeController : Controller + { + private readonly IStringLocalizer _localizer; + + public HomeController(IStringLocalizer localizer) + { + _localizer = localizer; + } + + public IActionResult Index() + { + return View(); + } + + public IActionResult About() + { + ViewData["Message"] = _localizer["Your application description page."]; + + return View(); + } + + public IActionResult About2() + { + ViewData["Message"] = _localizer["Your application description page."]; + + return View(); + } + + public IActionResult SetCulture(string id="en") + { + string culture = id; + Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), + new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } + ); + + ViewData["Message"] = "Culture set to " + culture; + + return View("About"); + } + + public IActionResult Contact() + { + ViewData["Message"] = _localizer["Your contact page."]; + return View(); + } + + [HttpPost] + public IActionResult SetLanguage(string culture, string returnUrl) + { + Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), + new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } + ); + + return LocalRedirect(returnUrl); + } + + public IActionResult Error() + { + return View(); + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/InfoController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/InfoController.cs new file mode 100644 index 000000000000..275c1f75f238 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/InfoController.cs @@ -0,0 +1,70 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; + +namespace Localization.Controllers; + +// +public class InfoController : Controller +{ + private readonly IStringLocalizer _localizer; + private readonly IStringLocalizer _sharedLocalizer; + + public InfoController(IStringLocalizer localizer, + IStringLocalizer sharedLocalizer) + { + _localizer = localizer; + _sharedLocalizer = sharedLocalizer; + } + + public string TestLoc() + { + string msg = "Shared resx: " + _sharedLocalizer["Hello!"] + + " Info resx " + _localizer["Hello!"]; + return msg; + } + // + + public IActionResult Index() + { + return View(); + } + + public IActionResult About() + { + ViewData["Message"] = _sharedLocalizer["Your application description page."]; + + return View(); + } + + public IActionResult Contact() + { + ViewData["Message"] = _sharedLocalizer["Your contact page."]; + return View(); + } + + [HttpPost] + public IActionResult SetLanguage(string culture, string returnUrl) + { + Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), + new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } + ); + + return LocalRedirect(returnUrl); + } + + public IActionResult Error() + { + return View(); + } +} + + +public class SharedResource +{ +} + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/ManageController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/ManageController.cs new file mode 100644 index 000000000000..fcb8fdf295c6 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/ManageController.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Security.Claims; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Localization.Models; +using Localization.Services; +using Localization.ViewModels.Manage; + +namespace Localization.Controllers +{ + [Authorize] + public class ManageController : Controller + { + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly IEmailSender _emailSender; + private readonly ISmsSender _smsSender; + private readonly ILogger _logger; + + public ManageController( + UserManager userManager, + SignInManager signInManager, + IEmailSender emailSender, + ISmsSender smsSender, + ILoggerFactory loggerFactory) + { + _userManager = userManager; + _signInManager = signInManager; + _emailSender = emailSender; + _smsSender = smsSender; + _logger = loggerFactory.CreateLogger(); + } + + // + // GET: /Manage/Index + [HttpGet] + public async Task Index(ManageMessageId? message = null) + { + ViewData["StatusMessage"] = + message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." + : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." + : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." + : message == ManageMessageId.Error ? "An error has occurred." + : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." + : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." + : ""; + + var user = await GetCurrentUserAsync(); + var model = new IndexViewModel + { + HasPassword = await _userManager.HasPasswordAsync(user), + PhoneNumber = await _userManager.GetPhoneNumberAsync(user), + TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user), + Logins = await _userManager.GetLoginsAsync(user), + BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user) + }; + return View(model); + } + + // + // POST: /Manage/RemoveLogin + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RemoveLogin(RemoveLoginViewModel account) + { + ManageMessageId? message = ManageMessageId.Error; + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + message = ManageMessageId.RemoveLoginSuccess; + } + } + return RedirectToAction(nameof(ManageLogins), new { Message = message }); + } + + // + // GET: /Manage/AddPhoneNumber + public IActionResult AddPhoneNumber() + { + return View(); + } + + // + // POST: /Manage/AddPhoneNumber + [HttpPost] + [ValidateAntiForgeryToken] + public async Task AddPhoneNumber(AddPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + // Generate the token and send it + var user = await GetCurrentUserAsync(); + var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber); + await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code); + return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber }); + } + + // + // POST: /Manage/EnableTwoFactorAuthentication + [HttpPost] + [ValidateAntiForgeryToken] + public async Task EnableTwoFactorAuthentication() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + await _userManager.SetTwoFactorEnabledAsync(user, true); + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation(1, "User enabled two-factor authentication."); + } + return RedirectToAction(nameof(Index), "Manage"); + } + + // + // POST: /Manage/DisableTwoFactorAuthentication + [HttpPost] + [ValidateAntiForgeryToken] + public async Task DisableTwoFactorAuthentication() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + await _userManager.SetTwoFactorEnabledAsync(user, false); + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation(2, "User disabled two-factor authentication."); + } + return RedirectToAction(nameof(Index), "Manage"); + } + + // + // GET: /Manage/VerifyPhoneNumber + [HttpGet] + public async Task VerifyPhoneNumber(string phoneNumber) + { + var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber); + // Send an SMS to verify the phone number + return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); + } + + // + // POST: /Manage/VerifyPhoneNumber + [HttpPost] + [ValidateAntiForgeryToken] + public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess }); + } + } + // If we got this far, something failed, redisplay the form + ModelState.AddModelError(string.Empty, "Failed to verify phone number"); + return View(model); + } + + // + // GET: /Manage/RemovePhoneNumber + [HttpGet] + public async Task RemovePhoneNumber() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await _userManager.SetPhoneNumberAsync(user, null); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess }); + } + } + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); + } + + // + // GET: /Manage/ChangePassword + [HttpGet] + public IActionResult ChangePassword() + { + return View(); + } + + // + // POST: /Manage/ChangePassword + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ChangePassword(ChangePasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation(3, "User changed their password successfully."); + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess }); + } + AddErrors(result); + return View(model); + } + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); + } + + // + // GET: /Manage/SetPassword + [HttpGet] + public IActionResult SetPassword() + { + return View(); + } + + // + // POST: /Manage/SetPassword + [HttpPost] + [ValidateAntiForgeryToken] + public async Task SetPassword(SetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await _userManager.AddPasswordAsync(user, model.NewPassword); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess }); + } + AddErrors(result); + return View(model); + } + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); + } + + //GET: /Manage/ManageLogins + [HttpGet] + public async Task ManageLogins(ManageMessageId? message = null) + { + ViewData["StatusMessage"] = + message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." + : message == ManageMessageId.AddLoginSuccess ? "The external login was added." + : message == ManageMessageId.Error ? "An error has occurred." + : ""; + var user = await GetCurrentUserAsync(); + if (user == null) + { + return View("Error"); + } + var userLogins = await _userManager.GetLoginsAsync(user); + var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync(); + var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList(); + ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1; + return View(new ManageLoginsViewModel + { + CurrentLogins = userLogins, + OtherLogins = otherLogins + }); + } + + // + // POST: /Manage/LinkLogin + [HttpPost] + [ValidateAntiForgeryToken] + public IActionResult LinkLogin(string provider) + { + // Request a redirect to the external login provider to link a login for the current user + var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); + var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); + return new ChallengeResult(provider, properties); + } + + // + // GET: /Manage/LinkLoginCallback + [HttpGet] + public async Task LinkLoginCallback() + { + var user = await GetCurrentUserAsync(); + if (user == null) + { + return View("Error"); + } + var info = await _signInManager.GetExternalLoginInfoAsync(_userManager.GetUserId(User)); + if (info == null) + { + return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error }); + } + var result = await _userManager.AddLoginAsync(user, info); + var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error; + return RedirectToAction(nameof(ManageLogins), new { Message = message }); + } + +// + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError(string.Empty, error.Description); + } + } + + public enum ManageMessageId + { + AddPhoneSuccess, + AddLoginSuccess, + ChangePasswordSuccess, + SetTwoFactorSuccess, + SetPasswordSuccess, + RemoveLoginSuccess, + RemovePhoneSuccess, + Error + } + + private async Task GetCurrentUserAsync() + { + return await _userManager.FindByIdAsync(_userManager.GetUserId(User)); + } + +// + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/TestController.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/TestController.cs new file mode 100644 index 000000000000..6d12ed8825c8 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Controllers/TestController.cs @@ -0,0 +1,51 @@ +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; + +namespace Localization.Controllers; + +// +public class TestController : Controller +{ + private readonly IStringLocalizer _localizer; + private readonly IStringLocalizer _localizer2; + + public TestController(IStringLocalizerFactory factory) + { + var type = typeof(SharedResource); + var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName); + _localizer = factory.Create(type); + _localizer2 = factory.Create("SharedResource", assemblyName.Name); + } + + public IActionResult About() + { + ViewData["Message"] = _localizer["Your application description page."] + + " loc 2: " + _localizer2["Your application description page."]; + + return View(); + } + // + public IActionResult Contact() + { + ViewData["Message"] = _localizer["Your contact page."] + + " shared 2: " + _localizer2["Your contact page."]; + return View(); + } + + public IActionResult Hello(string name) + { + ViewData["Message"] = _localizer["Hello {0}", name]; + + return View(); + } + public IActionResult Index() + { + return View(); + } + + public IActionResult Error() + { + return View(); + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Localization.csproj b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Localization.csproj new file mode 100644 index 000000000000..c59a544261ff --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Localization.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + + + + + + + + + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationDbContext.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationDbContext.cs new file mode 100644 index 000000000000..83e9093d6f40 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationDbContext.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; + +namespace Localization.Models +{ + public class ApplicationDbContext : IdentityDbContext + { + public ApplicationDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + // Customize the ASP.NET Core Identity model and override the defaults if needed. + // For example, you can rename the ASP.NET Core Identity table names and more. + // Add your customizations after calling base.OnModelCreating(builder); + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationUser.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationUser.cs new file mode 100644 index 000000000000..10ff89cec308 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Models/ApplicationUser.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; + +namespace Localization.Models +{ + // Add profile data for application users by adding properties to the ApplicationUser class + public class ApplicationUser : IdentityUser + { + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Program.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Program.cs new file mode 100644 index 000000000000..26f97119b026 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Program.cs @@ -0,0 +1,84 @@ +using Localization.Models; +using Localization.Services; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc.Razor; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddDbContext(options => +{ + options.UseSqlServer(builder.Configuration["Data:DefaultConnection:ConnectionString"]); +}); + +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); + +builder.Services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + +// +builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); + +builder.Services.AddMvc() + .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) + .AddDataAnnotationsLocalization(); +// + +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +// +builder.Services.Configure(options => +{ + var supportedCultures = new[] { "en-US", "fr" }; + options.SetDefaultCulture(supportedCultures[0]) + .AddSupportedCultures(supportedCultures) + .AddSupportedUICultures(supportedCultures); +}); +// + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} +else +{ + app.UseExceptionHandler("/Error"); + + // For more information on applying migrations at runtime, see: + // https://docs.microsoft.com/ef/core/managing-schemas/migrations/applying#apply-migrations-at-runtime + try + { + using var serviceScope = app.Services.GetRequiredService().CreateScope(); + serviceScope.ServiceProvider.GetService().Database.Migrate(); + } + catch + { + } +} + +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); + +// +var localizationOptions = app.Services.GetService>(); +app.UseRequestLocalization(localizationOptions.Value); +// + +app.UseAuthentication(); +app.UseAuthorization(); + +app.UseEndpoints(endpoints => +{ + endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); +}); + +app.Run(); diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.AboutController.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.AboutController.fr.resx new file mode 100644 index 000000000000..c704f3bd3bef --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.AboutController.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + localized about title + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.BookController.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.BookController.fr.resx new file mode 100644 index 000000000000..260dd3ebe90c --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.BookController.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <b>Ola</b><i> {0}</i> + + + Votre page de description de l'application . <b>app descript pg</b><i> \Resources\Controllers.BookController.fr.resx</i> + + + Votre page de contact . contact page \Resources\Controllers.BookController.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.TestController.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.TestController.fr.resx new file mode 100644 index 000000000000..7c0a7d903524 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers.TestController.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <b>Ola</b><i> {0}</i> + + + Votre page de description de l'application . <b>app descript pg</b><i> \Resources\Controllers.TestController.fr.resx</i> + + + Votre page de contact . contact page \Resources\Controllers.TestController.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/HomeController.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/HomeController.fr.resx new file mode 100644 index 000000000000..062c173f7260 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/HomeController.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ola from controllers\homecontroller.fr + + + Votre page de description de l'application . descript \Resources\Controllers\HomeController.fr.resx + + + Votre page de contact . contact page \Resources\Controllers\HomeController.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/InfoController.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/InfoController.fr.resx new file mode 100644 index 000000000000..c0b729addfc1 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Controllers/InfoController.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ola from controllers\zEBRAcontroller.fr + + + Votre page de description de l'application . descript \Resources\ controllers\zEBRAcontroller.fr + + + Votre page de contact . contact page \Resources\ controllers\zEBRAcontroller.fr + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/LocSample.SharedResource.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/LocSample.SharedResource.fr.resx new file mode 100644 index 000000000000..886669be14a6 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/LocSample.SharedResource.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ola from Resources\LocSample.SharedResource.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Resources.SharedResource.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Resources.SharedResource.fr.resx new file mode 100644 index 000000000000..339da1d786a8 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Resources.SharedResource.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ola from Resources\Resources.SharedResource.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/SharedResource.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/SharedResource.fr.resx new file mode 100644 index 000000000000..0b7627b40516 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/SharedResource.fr.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <b>Ola</b><i> {0}</i> + + + Ola from Resources\SharedResource.fr.resx + + + Loc version of "Shared Test 1" + + + Votre page de description de l'application . app descript pg - Resources\SharedResource.fr.resx + + + Votre page de contact . contact page Resources\SharedResource.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/StartUp.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/StartUp.fr.resx new file mode 100644 index 000000000000..d17b7c139b42 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/StartUp.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Votre page de description de l'application . descript \Resources\StartUp.fr.resx + + + Votre page de description de l'application . descript \Resources\StartUp.fr.resx + + + Votre page de contact . contact page \Resources\StartUp.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels.Account.RegisterViewModel2.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels.Account.RegisterViewModel2.fr.resx new file mode 100644 index 000000000000..4fdde518a6fd --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels.Account.RegisterViewModel2.fr.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmez le mot de passe . confirm + + + Email (fr) . + + + Mot de passe PW . + + + Le champ email est pas une adresse email valide. dot vers of email not valid + + + Le champ Email est requis. (dot version required) + + + Le mot de passe et la confirmation de passe ne correspondent pas. dot version no match + + + Le champ Mot de passe est nécessaire. dot vers pw require + + + Le {0} doit être d'au moins {2} caractères. The {0} must be at least {2} characters long. PW must be dot version + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels/Account/RegisterViewModel.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels/Account/RegisterViewModel.fr.resx new file mode 100644 index 000000000000..3c6b9db68295 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/ViewModels/Account/RegisterViewModel.fr.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmez le mot de passe + + + Email (fr) + + + Mot de passe + + + Le champ email est pas une adresse email valide. + + + Le champ Email est requis. (required) + + + Le mot de passe et la confirmation de passe ne correspondent pas. + + + Le champ Mot de passe est nécessaire. + + + Le {0} doit être d'au moins {2} caractères. The {0} must be at least {2} characters long. + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Home.About.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Home.About.fr.resx new file mode 100644 index 000000000000..9063e718fe20 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Home.About.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.Home.About.fr.resx + + + Utilisez cette zone pour fournir des informations supplémentaires . - use this area Resources\Views.Home.About.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Info.About.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Info.About.fr.resx new file mode 100644 index 000000000000..9063e718fe20 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Info.About.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.Home.About.fr.resx + + + Utilisez cette zone pour fournir des informations supplémentaires . - use this area Resources\Views.Home.About.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.Designer.cs new file mode 100644 index 000000000000..e346b25ba9bd --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.Designer.cs @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Views_Shared__Layout { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Views_Shared__Layout() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Shared._Layout", typeof(Views_Shared__Layout).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Sur - about Resources\Views.Shared._Layout.fr.resx. + /// + internal static string About { + get { + return ResourceManager.GetString("About", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact. + /// + internal static string Contact { + get { + return ResourceManager.GetString("Contact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Accueil hm. + /// + internal static string Home { + get { + return ResourceManager.GetString("Home", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Basculer la navigation-tog nav. + /// + internal static string Toggle_navigation { + get { + return ResourceManager.GetString("Toggle navigation", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.resx new file mode 100644 index 000000000000..3f7590846439 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._Layout.fr.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.Shared._Layout.fr.resx + + + Contact + + + Accueil hm + + + Basculer la navigation-tog nav + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._LoginPartial.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._LoginPartial.fr.resx new file mode 100644 index 000000000000..58658cf3340b --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._LoginPartial.fr.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <i>Bonjour </i> <b>{0}!</b> + + + Bonjour {0} ! + + + S'identifier (login partial) + + + Déconnecter + + + Faire en sorte + + + Enregistrez + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._SelectLanguagePartial.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._SelectLanguagePartial.fr.resx new file mode 100644 index 000000000000..0e42b4f055e4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.Shared._SelectLanguagePartial.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Langue: + + + Demande fournisseur de la culture: + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.About.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.About.fr.resx new file mode 100644 index 000000000000..edd986a61ab3 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.About.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.book.About.fr.resx + + + Utilisez cette zone pour fournir des informations supplémentaires . - use this area Resources\Views.book.About.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.Designer.cs new file mode 100644 index 000000000000..094f021a9fdc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.Designer.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Views_Home_About { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Views_Home_About() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Home.About", typeof(Views_Home_About).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Sur - about Resources\Views.Home.About.fr.resx. + /// + internal static string About { + get { + return ResourceManager.GetString("About", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Utilisez cette zone pour fournir des informations supplémentaires . - use this area Resources\Views.Home.About.fr.resx. + /// + internal static string Use_this_area_to_provide_additional_information_ { + get { + return ResourceManager.GetString("Use this area to provide additional information.", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.resx new file mode 100644 index 000000000000..654f77aeb8d6 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.book.Hello.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.Home.About.fr.resx + + + Utilisez cette zone fr s . - use this area Resources\Views.book.About.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.test.About.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.test.About.fr.resx new file mode 100644 index 000000000000..fc435fbac065 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views.test.About.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about Resources\Views.test.About.fr.resx + + + Utilisez cette zone pour fournir des informations supplémentaires . - use this area Resources\Views.test.About.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Login.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Login.fr.resx new file mode 100644 index 000000000000..d67b5da10c9e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Login.fr.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mot de passe oublié?(4get pw -Resources\Views\Account\Login.fr.resx + + + S'identifier(login) Resources\Views\Account\Login.fr.resx + + + Connectez-vous en utilisant votre compte {0} + + + Inscrivez-vous en tant que nouvel utilisateur? + + + Il n'y pas de services externes d'authentification configurés. Voir <a href="https://go.microsoft.com/fwlink/?LinkID=532715">cet article</a> pour plus de détails sur la mise en place de cette application ASP.NET pour soutenir connecter via des services externes. + + + Utiliser un compte local pour vous connecter. + + + Utiliser un autre service pour vous connecter. + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Register.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Register.fr.resx new file mode 100644 index 000000000000..2b192a9c5fea --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Account/Register.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Créer un nouveau compte.-create + + + Inscription-reg-Resources\Views\Account\Register.fr.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.Designer.cs new file mode 100644 index 000000000000..f134dbb22107 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.Designer.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources.Views.Book { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Contact { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Contact() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Book.Contact", typeof(Contact).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to fr version of Marketting from Resources\Views\Book\Contact.resx. + /// + internal static string Marketing { + get { + return ResourceManager.GetString("Marketing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to fr support from Resources\Views\Book\Contact.resx. + /// + internal static string Support { + get { + return ResourceManager.GetString("Support", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.resx new file mode 100644 index 000000000000..55afcf648284 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Contact.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + fr version of Marketting from Resources\Views\Book\Contact.resx + + + fr support from Resources\Views\Book\Contact.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.Designer.cs new file mode 100644 index 000000000000..265c81c01093 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.Designer.cs @@ -0,0 +1,352 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources.Views.Book { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Index { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Index() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Book.Index", typeof(Index).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to <h1> Book version Ajouter un contrôleur et Vue (Add a Controller and View) Resources\Views\Home\Index.fr.resx </h1>. + /// + public static string Add_a_Controller_and_View { + get { + return ResourceManager.GetString("Add a Controller and View", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ajoutez un appsetting dans la configuration et y accéder à l'application .. + /// + public static string Add_an_appsetting_in_config_and_access_it_in_app_ { + get { + return ResourceManager.GetString("Add an appsetting in config and access it in app.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ajouter des packages de clients à l'aide Bower.. + /// + public static string Add_client_packages_using_Bower_ { + get { + return ResourceManager.GetString("Add client packages using Bower.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ajouter paquets en utilisant NuGet.. + /// + public static string Add_packages_using_NuGet_ { + get { + return ResourceManager.GetString("Add packages using NuGet.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Utilisations d'application. + /// + public static string Application_uses { + get { + return ResourceManager.GetString("Application uses", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Apportez dans les bibliothèques de NuGet , Bower , et NPM , et automatiser les tâches à l'aide Grunt ou Gulp .. + /// + public static string Bring_in_libraries_from_NuGet__Bower__and_npm__and_automate_tasks_using_Grunt_or_Gulp_ { + get { + return ResourceManager.GetString("Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or " + + "Gulp.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Le développement côté client. + /// + public static string Client_side_development { + get { + return ResourceManager.GetString("Client side development", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Aperçu conceptuel de ce qui est ASP.NET 5. + /// + public static string Conceptual_overview_of_what_is_ASP_NET_5 { + get { + return ResourceManager.GetString("Conceptual overview of what is ASP.NET 5", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Développer sur différentes plateformes. + /// + public static string Develop_on_different_platforms { + get { + return ResourceManager.GetString("Develop on different platforms", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notions de base ASP.NET 5 tels que le démarrage et middleware.. + /// + public static string Fundamentals_of_ASP_NET_5_such_as_Startup_and_middleware_ { + get { + return ResourceManager.GetString("Fundamentals of ASP.NET 5 such as Startup and middleware.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Page D'accueil. + /// + public static string Home_Page { + get { + return ResourceManager.GetString("Home Page", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Comment. + /// + public static string How_to { + get { + return ResourceManager.GetString("How to", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Découvrez comment la plate-forme Azure cloud de Microsoft vous permet de construire, déployer et applications Web à grande échelle .. + /// + public static string Learn_how_Microsoft_s_Azure_cloud_platform_allows_you_to_build__deploy__and_scale_web_apps_ { + get { + return ResourceManager.GetString("Learn how Microsoft\'s Azure cloud platform allows you to build, deploy, and scale" + + " web apps.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Apprenez à créer des applications ASP.NET qui peuvent fonctionner n'importe où .. + /// + public static string Learn_how_to_build_ASP_NET_apps_that_can_run_anywhere_ { + get { + return ResourceManager.GetString("Learn how to build ASP.NET apps that can run anywhere.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Apprendre Encore Plus. + /// + public static string Learn_More { + get { + return ResourceManager.GetString("Learn More", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gérer Secrets de l'utilisateur à l'aide de Secret Manager.. + /// + public static string Manage_User_Secrets_using_Secret_Manager_ { + get { + return ResourceManager.GetString("Manage User Secrets using Secret Manager.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prochain. + /// + public static string Next { + get { + return ResourceManager.GetString("Next", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Vue D'ensemble. + /// + public static string Overview { + get { + return ResourceManager.GetString("Overview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gestion des Paquetages. + /// + public static string Package_Management { + get { + return ResourceManager.GetString("Package Management", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Précédent. + /// + public static string Previous { + get { + return ResourceManager.GetString("Previous", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Publier sur Microsoft Azure Web Apps. + /// + public static string Publish_to_Microsoft_Azure_Web_Apps { + get { + return ResourceManager.GetString("Publish to Microsoft Azure Web Apps", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lire la suite sur le site de documentation. + /// + public static string Read_more_on_the_documentation_site { + get { + return ResourceManager.GetString("Read more on the documentation site", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Déployer & Exécuter. + /// + public static string Run___Deploy { + get { + return ResourceManager.GetString("Run & Deploy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exécuter des commandes dans votre bash. + /// + public static string Run_commands_in_your_project_json { + get { + return ResourceManager.GetString("Run commands in your bash", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exécutez votre application. + /// + public static string Run_your_app { + get { + return ResourceManager.GetString("Run your app", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exécutez votre application sur .NET de base. + /// + public static string Run_your_app_on__NET_Core { + get { + return ResourceManager.GetString("Run your app on .NET Core", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pages échantillon en utilisant ASP.NET MVC 6. + /// + public static string Sample_pages_using_ASP_NET_MVC_6 { + get { + return ResourceManager.GetString("Sample pages using ASP.NET MVC 6", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sécurité. + /// + public static string Security { + get { + return ResourceManager.GetString("Security", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cibler le développement, la mise en scène ou de l'environnement de production.. + /// + public static string Target_development__staging_or_production_environment_ { + get { + return ResourceManager.GetString("Target development, staging or production environment.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Il ya de puissantes nouvelles fonctionnalités de Visual Studio pour la création d'applications web modernes .. + /// + public static string There_are_powerful_new_features_in_Visual_Studio_for_building_modern_web_apps_ { + get { + return ResourceManager.GetString("There are powerful new features in Visual Studio for building modern web apps.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Utilisez la journalisation pour enregistrer un message.. + /// + public static string Use_logging_to_log_a_message_ { + get { + return ResourceManager.GetString("Use logging to log a message.", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Utilisation des données. + /// + public static string Working_with_Data { + get { + return ResourceManager.GetString("Working with Data", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.resx new file mode 100644 index 000000000000..2bf7bd48d490 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Book/Index.resx @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <a href="https://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> et <a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> pour la gestion des bibliothèques côté client + + + <h1> Book version Ajouter un contrôleur et Vue (Add a Controller and View) Resources\Views\Home\Index.fr.resx </h1> + + + Utilisations d'application + + + Apportez dans les bibliothèques de NuGet , Bower , et NPM , et automatiser les tâches à l'aide Grunt ou Gulp . + + + Page D'accueil + + + Comment + + + Découvrez comment la plate-forme Azure cloud de Microsoft vous permet de construire, déployer et applications Web à grande échelle . + + + Apprenez à créer des applications ASP.NET qui peuvent fonctionner n'importe où . + + + Apprendre Encore Plus + + + Prochain + + + Gestion des Paquetages + + + Précédent + + + Pages échantillon en utilisant ASP.NET MVC 6 + + + Thématisation aide <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a> + + + Il ya de puissantes nouvelles fonctionnalités de Visual Studio pour la création d'applications web modernes . + + + Ajoutez un appsetting dans la configuration et y accéder à l'application . + + + Ajouter des packages de clients à l'aide Bower. + + + Ajouter paquets en utilisant NuGet. + + + Le développement côté client + + + Aperçu conceptuel de ce qui est ASP.NET 5 + + + Développer sur différentes plateformes + + + Notions de base ASP.NET 5 tels que le démarrage et middleware. + + + Gérer Secrets de l'utilisateur à l'aide de Secret Manager. + + + Vue D'ensemble + + + Publier sur Microsoft Azure Web Apps + + + Lire la suite sur le site de documentation + + + Déployer & Exécuter + + + Exécuter des commandes dans votre bash + + + Exécutez votre application + + + Exécutez votre application sur .NET de base + + + Sécurité + + + Cibler le développement, la mise en scène ou de l'environnement de production. + + + Utilisez la journalisation pour enregistrer un message. + + + Utilisation des données + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/About2.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/About2.fr.resx new file mode 100644 index 000000000000..20c204902daf --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/About2.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sur - about2 Resources\Views\Home\About.fr.resx + + + Utilisez cette zone pour fournir des informations supplémentaires . - use this area <b> folder version </b><i> Resources\Views\Home\About.fr.resx </i> + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.Designer.cs new file mode 100644 index 000000000000..8d7dd6efff4e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.Designer.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources.Views.Home { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Contact { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Contact() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Home.Contact", typeof(Contact).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to fr version of Marketting. + /// + internal static string Marketing { + get { + return ResourceManager.GetString("Marketing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to fr support from Resources\Views\Home\Contact.resx. + /// + internal static string Support { + get { + return ResourceManager.GetString("Support", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.resx new file mode 100644 index 000000000000..628032fe0a23 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Contact.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + fr version of Marketting + + + fr support from Resources\Views\Home\Contact.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Index.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Index.fr.resx new file mode 100644 index 000000000000..61ff610db34c --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Home/Index.fr.resx @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <a href="https://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> et <a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> pour la gestion des bibliothèques côté client + + + <h1>Home Version Ajouter un contrôleur et Vue (Add a Controller and View) Resources\Views\Book\Index.fr.resx </h1> + + + Utilisations d'application + + + Apportez dans les bibliothèques de NuGet , Bower , et NPM , et automatiser les tâches à l'aide Grunt ou Gulp . + + + Page D'accueil + + + Comment + + + Découvrez comment la plate-forme Azure cloud de Microsoft vous permet de construire, déployer et applications Web à grande échelle . + + + Apprenez à créer des applications ASP.NET qui peuvent fonctionner n'importe où . + + + Apprendre Encore Plus + + + Prochain + + + Gestion des Paquetages + + + Précédent + + + Pages échantillon en utilisant ASP.NET MVC 6 + + + Thématisation aide <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a> + + + Il ya de puissantes nouvelles fonctionnalités de Visual Studio pour la création d'applications web modernes . + + + Ajoutez un appsetting dans la configuration et y accéder à l'application . + + + Ajouter des packages de clients à l'aide Bower. + + + Ajouter paquets en utilisant NuGet. + + + Le développement côté client + + + Aperçu conceptuel de ce qui est ASP.NET 5 + + + Développer sur différentes plateformes + + + Notions de base ASP.NET 5 tels que le démarrage et middleware. + + + Gérer Secrets de l'utilisateur à l'aide de Secret Manager. + + + Vue D'ensemble + + + Publier sur Microsoft Azure Web Apps + + + Lire la suite sur le site de documentation + + + Déployer & Exécuter + + + Exécuter des commandes dans votre bash + + + Exécutez votre application + + + Exécutez votre application sur .NET de base + + + Sécurité + + + Cibler le développement, la mise en scène ou de l'environnement de production. + + + Utilisez la journalisation pour enregistrer un message. + + + Utilisation des données + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.Designer.cs new file mode 100644 index 000000000000..3b6985c031df --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.Designer.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources.Views.Zebra { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Contact { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Contact() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Zebra.Contact", typeof(Contact).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to fr version of Marketting from Resources\Views\Zebra\Contact.resx. + /// + internal static string Marketing { + get { + return ResourceManager.GetString("Marketing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to fr support from Resources\Views\Zebra\Contact.resx. + /// + internal static string Support { + get { + return ResourceManager.GetString("Support", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.resx new file mode 100644 index 000000000000..ffe91d289ddd --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Contact.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + fr version of Marketting from Resources\Views\Zebra\Contact.resx + + + fr support from Resources\Views\Zebra\Contact.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Index.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Index.fr.resx new file mode 100644 index 000000000000..2bf7bd48d490 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Info/Index.fr.resx @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <a href="https://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> et <a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> pour la gestion des bibliothèques côté client + + + <h1> Book version Ajouter un contrôleur et Vue (Add a Controller and View) Resources\Views\Home\Index.fr.resx </h1> + + + Utilisations d'application + + + Apportez dans les bibliothèques de NuGet , Bower , et NPM , et automatiser les tâches à l'aide Grunt ou Gulp . + + + Page D'accueil + + + Comment + + + Découvrez comment la plate-forme Azure cloud de Microsoft vous permet de construire, déployer et applications Web à grande échelle . + + + Apprenez à créer des applications ASP.NET qui peuvent fonctionner n'importe où . + + + Apprendre Encore Plus + + + Prochain + + + Gestion des Paquetages + + + Précédent + + + Pages échantillon en utilisant ASP.NET MVC 6 + + + Thématisation aide <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a> + + + Il ya de puissantes nouvelles fonctionnalités de Visual Studio pour la création d'applications web modernes . + + + Ajoutez un appsetting dans la configuration et y accéder à l'application . + + + Ajouter des packages de clients à l'aide Bower. + + + Ajouter paquets en utilisant NuGet. + + + Le développement côté client + + + Aperçu conceptuel de ce qui est ASP.NET 5 + + + Développer sur différentes plateformes + + + Notions de base ASP.NET 5 tels que le démarrage et middleware. + + + Gérer Secrets de l'utilisateur à l'aide de Secret Manager. + + + Vue D'ensemble + + + Publier sur Microsoft Azure Web Apps + + + Lire la suite sur le site de documentation + + + Déployer & Exécuter + + + Exécuter des commandes dans votre bash + + + Exécutez votre application + + + Exécutez votre application sur .NET de base + + + Sécurité + + + Cibler le développement, la mise en scène ou de l'environnement de production. + + + Utilisez la journalisation pour enregistrer un message. + + + Utilisation des données + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.Designer.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.Designer.cs new file mode 100644 index 000000000000..7c4e29459ab4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.Designer.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Localization.Resources.Views.Test { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Contact { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + internal Contact() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Localization.Resources.Views.Test.Contact", typeof(Contact).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to fr version of Marketting from Resources\Views\Test\Contact.resx. + /// + internal static string Marketing { + get { + return ResourceManager.GetString("Marketing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to fr support from Resources\Views\Test\Contact.resx. + /// + internal static string Support { + get { + return ResourceManager.GetString("Support", resourceCulture); + } + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.resx new file mode 100644 index 000000000000..c08754e9a3aa --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Contact.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + fr version of Marketting from Resources\Views\Test\Contact.resx + + + fr support from Resources\Views\Test\Contact.resx + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Index.fr.resx b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Index.fr.resx new file mode 100644 index 000000000000..2bf7bd48d490 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Resources/Views/Test/Index.fr.resx @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + <a href="https://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> et <a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> pour la gestion des bibliothèques côté client + + + <h1> Book version Ajouter un contrôleur et Vue (Add a Controller and View) Resources\Views\Home\Index.fr.resx </h1> + + + Utilisations d'application + + + Apportez dans les bibliothèques de NuGet , Bower , et NPM , et automatiser les tâches à l'aide Grunt ou Gulp . + + + Page D'accueil + + + Comment + + + Découvrez comment la plate-forme Azure cloud de Microsoft vous permet de construire, déployer et applications Web à grande échelle . + + + Apprenez à créer des applications ASP.NET qui peuvent fonctionner n'importe où . + + + Apprendre Encore Plus + + + Prochain + + + Gestion des Paquetages + + + Précédent + + + Pages échantillon en utilisant ASP.NET MVC 6 + + + Thématisation aide <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a> + + + Il ya de puissantes nouvelles fonctionnalités de Visual Studio pour la création d'applications web modernes . + + + Ajoutez un appsetting dans la configuration et y accéder à l'application . + + + Ajouter des packages de clients à l'aide Bower. + + + Ajouter paquets en utilisant NuGet. + + + Le développement côté client + + + Aperçu conceptuel de ce qui est ASP.NET 5 + + + Développer sur différentes plateformes + + + Notions de base ASP.NET 5 tels que le démarrage et middleware. + + + Gérer Secrets de l'utilisateur à l'aide de Secret Manager. + + + Vue D'ensemble + + + Publier sur Microsoft Azure Web Apps + + + Lire la suite sur le site de documentation + + + Déployer & Exécuter + + + Exécuter des commandes dans votre bash + + + Exécutez votre application + + + Exécutez votre application sur .NET de base + + + Sécurité + + + Cibler le développement, la mise en scène ou de l'environnement de production. + + + Utilisez la journalisation pour enregistrer un message. + + + Utilisation des données + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/IEmailSender.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/IEmailSender.cs new file mode 100644 index 000000000000..a974de30bfae --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/IEmailSender.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.Services +{ + public interface IEmailSender + { + Task SendEmailAsync(string email, string subject, string message); + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/ISmsSender.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/ISmsSender.cs new file mode 100644 index 000000000000..b0866e4f4aad --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/ISmsSender.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.Services +{ + public interface ISmsSender + { + Task SendSmsAsync(string number, string message); + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/MessageServices.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/MessageServices.cs new file mode 100644 index 000000000000..fa0093c2539a --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Services/MessageServices.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.Services +{ + // This class is used by the application to send Email and SMS + // when you turn on two-factor authentication in ASP.NET Core Identity. + // For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713 + public class AuthMessageSender : IEmailSender, ISmsSender + { + public Task SendEmailAsync(string email, string subject, string message) + { + // Plug in your email service here to send an email. + return Task.FromResult(0); + } + + public Task SendSmsAsync(string number, string message) + { + // Plug in your SMS service here to send a text message. + return Task.FromResult(0); + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/SharedResource.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/SharedResource.cs new file mode 100644 index 000000000000..46f13cef2109 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/SharedResource.cs @@ -0,0 +1,7 @@ +// Dummy class to group shared resources + +namespace Localization; + +public class SharedResource +{ +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ExternalLoginConfirmationViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ExternalLoginConfirmationViewModel.cs new file mode 100644 index 000000000000..1451266f7171 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ExternalLoginConfirmationViewModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Account +{ + public class ExternalLoginConfirmationViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ForgotPasswordViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ForgotPasswordViewModel.cs new file mode 100644 index 000000000000..35aeb6aa8f02 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ForgotPasswordViewModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Account +{ + public class ForgotPasswordViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/LoginViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/LoginViewModel.cs new file mode 100644 index 000000000000..48610aed9b63 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/LoginViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Account +{ + public class LoginViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [DataType(DataType.Password)] + public string Password { get; set; } + + [Display(Name = "Remember me?")] + public bool RememberMe { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/RegisterViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/RegisterViewModel.cs new file mode 100644 index 000000000000..b55b8cd4c63e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/RegisterViewModel.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; + +namespace Localization.ViewModels.Account; + +public class RegisterViewModel +{ + [Required(ErrorMessage = "The Email field is required.")] + [EmailAddress(ErrorMessage = "The Email field is not a valid email address.")] + [Display(Name = "Email")] + public string Email { get; set; } + + [Required(ErrorMessage = "The Password field is required.")] + [StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", + MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm password")] + [Compare("Password", ErrorMessage = + "The password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ResetPasswordViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ResetPasswordViewModel.cs new file mode 100644 index 000000000000..de7518eeaff2 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/ResetPasswordViewModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Account +{ + public class ResetPasswordViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm password")] + [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + + public string Code { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/SendCodeViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/SendCodeViewModel.cs new file mode 100644 index 000000000000..28d6e2ec90e9 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/SendCodeViewModel.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Localization.ViewModels.Account +{ + public class SendCodeViewModel + { + public string SelectedProvider { get; set; } + + public ICollection Providers { get; set; } + + public string ReturnUrl { get; set; } + + public bool RememberMe { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/VerifyCodeViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/VerifyCodeViewModel.cs new file mode 100644 index 000000000000..16a69b31a813 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Account/VerifyCodeViewModel.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Account +{ + public class VerifyCodeViewModel + { + [Required] + public string Provider { get; set; } + + [Required] + public string Code { get; set; } + + public string ReturnUrl { get; set; } + + [Display(Name = "Remember this browser?")] + public bool RememberBrowser { get; set; } + + [Display(Name = "Remember me?")] + public bool RememberMe { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/AddPhoneNumberViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/AddPhoneNumberViewModel.cs new file mode 100644 index 000000000000..de4617da6dad --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/AddPhoneNumberViewModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class AddPhoneNumberViewModel + { + [Required] + [Phone] + [Display(Name = "Phone number")] + public string PhoneNumber { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ChangePasswordViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ChangePasswordViewModel.cs new file mode 100644 index 000000000000..e2aae89f2076 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ChangePasswordViewModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class ChangePasswordViewModel + { + [Required] + [DataType(DataType.Password)] + [Display(Name = "Current password")] + public string OldPassword { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "New password")] + public string NewPassword { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm new password")] + [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ConfigureTwoFactorViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ConfigureTwoFactorViewModel.cs new file mode 100644 index 000000000000..c6fef6272610 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ConfigureTwoFactorViewModel.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Localization.ViewModels.Manage +{ + public class ConfigureTwoFactorViewModel + { + public string SelectedProvider { get; set; } + + public ICollection Providers { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/FactorViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/FactorViewModel.cs new file mode 100644 index 000000000000..64dd33c5b8a0 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/FactorViewModel.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class FactorViewModel + { + public string Purpose { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/IndexViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/IndexViewModel.cs new file mode 100644 index 000000000000..4d42c058802b --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/IndexViewModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; + +namespace Localization.ViewModels.Manage +{ + public class IndexViewModel + { + public bool HasPassword { get; set; } + + public IList Logins { get; set; } + + public string PhoneNumber { get; set; } + + public bool TwoFactor { get; set; } + + public bool BrowserRemembered { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ManageLoginsViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ManageLoginsViewModel.cs new file mode 100644 index 000000000000..206c0c5b33cc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/ManageLoginsViewModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Identity; + +namespace Localization.ViewModels.Manage +{ + public class ManageLoginsViewModel + { + public IList CurrentLogins { get; set; } + + public IList OtherLogins { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/RemoveLoginViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/RemoveLoginViewModel.cs new file mode 100644 index 000000000000..858b2ddbc192 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/RemoveLoginViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class RemoveLoginViewModel + { + public string LoginProvider { get; set; } + public string ProviderKey { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/SetPasswordViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/SetPasswordViewModel.cs new file mode 100644 index 000000000000..6a25c33b528f --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/SetPasswordViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class SetPasswordViewModel + { + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "New password")] + public string NewPassword { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm new password")] + [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/VerifyPhoneNumberViewModel.cs b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/VerifyPhoneNumberViewModel.cs new file mode 100644 index 000000000000..4fd40744e0f0 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/ViewModels/Manage/VerifyPhoneNumberViewModel.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Localization.ViewModels.Manage +{ + public class VerifyPhoneNumberViewModel + { + [Required] + public string Code { get; set; } + + [Required] + [Phone] + [Display(Name = "Phone number")] + public string PhoneNumber { get; set; } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ConfirmEmail.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ConfirmEmail.cshtml new file mode 100644 index 000000000000..3244fef5f1e1 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ConfirmEmail.cshtml @@ -0,0 +1,10 @@ +@{ + ViewData["Title"] = "Confirm Email"; +} + +

@ViewData["Title"].

+
+

+ Thank you for confirming your email. Please Click here to Log in. +

+
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginConfirmation.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginConfirmation.cshtml new file mode 100644 index 000000000000..fff1a8771cd4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginConfirmation.cshtml @@ -0,0 +1,35 @@ +@model ExternalLoginConfirmationViewModel +@{ + ViewData["Title"] = "Register"; +} + +

@ViewData["Title"].

+

Associate your @ViewData["LoginProvider"] account.

+ +
+

Association Form

+
+
+ +

+ You've successfully authenticated with @ViewData["LoginProvider"]. + Please enter a user name for this site below and click the Register button to finish + logging in. +

+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginFailure.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginFailure.cshtml new file mode 100644 index 000000000000..d89339e012cf --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ExternalLoginFailure.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Login Failure"; +} + +
+

@ViewData["Title"].

+

Unsuccessful login with service.

+
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPassword.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPassword.cshtml new file mode 100644 index 000000000000..8dc17c6b9db3 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPassword.cshtml @@ -0,0 +1,31 @@ +@model ForgotPasswordViewModel +@{ + ViewData["Title"] = "Forgot your password?"; +} + +

@ViewData["Title"].

+

+ For more information on how to enable reset password please see this article. +

+ +@*
+

Enter your email.

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
*@ + +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPasswordConfirmation.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPasswordConfirmation.cshtml new file mode 100644 index 000000000000..ab9bf44c8deb --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ForgotPasswordConfirmation.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Forgot Password Confirmation"; +} + +

@ViewData["Title"].

+

+ Please check your email to reset your password. +

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Lockout.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Lockout.cshtml new file mode 100644 index 000000000000..2cc946d5c475 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Lockout.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Locked out"; +} + +
+

Locked out.

+

This account has been locked out, please try again later.

+
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Login.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Login.cshtml new file mode 100644 index 000000000000..faa27bb43abb --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Login.cshtml @@ -0,0 +1,89 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@model LoginViewModel +@inject SignInManager SignInManager +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Log in"]; +} + +

@ViewData["Title"].

+
+
+
+
+

@Localizer["Use a local account to log in."]

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+

+ @Localizer["Register as a new user?"] +

+

+ @Localizer["Forgot your password?"] +

+
+
+
+
+
+

@Localizer["Use another service to log in."]

+
+ @{ + var loginProviders = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList(); + if (loginProviders.Count == 0) + { +
+

+ @Localizer["There are no external authentication services configured. See this article " + + "for details on setting up this ASP.NET application to support logging in via external services."] +

+
+ } + else + { +
+
+

+ @foreach (var provider in loginProviders) + { + + } +

+
+
+ } + } +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Register.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Register.cshtml new file mode 100644 index 000000000000..73c03f335bf4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/Register.cshtml @@ -0,0 +1,44 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@model RegisterViewModel +@inject IViewLocalizer Localizer +@{ + ViewData["Title"] = Localizer["Register"]; +} + +

@ViewData["Title"].

+ +
+

@Localizer["Create a new account."]

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPassword.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPassword.cshtml new file mode 100644 index 000000000000..2db36b07e8b5 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPassword.cshtml @@ -0,0 +1,43 @@ +@model ResetPasswordViewModel +@{ + ViewData["Title"] = "Reset password"; +} + +

@ViewData["Title"].

+ +
+

Reset your password.

+
+
+ +
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPasswordConfirmation.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPasswordConfirmation.cshtml new file mode 100644 index 000000000000..bef2e4570d6a --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/ResetPasswordConfirmation.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Reset password confirmation"; +} + +

@ViewData["Title"].

+

+ Your password has been reset. Please Click here to log in. +

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/SendCode.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/SendCode.cshtml new file mode 100644 index 000000000000..04794ee93a4c --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/SendCode.cshtml @@ -0,0 +1,21 @@ +@model SendCodeViewModel +@{ + ViewData["Title"] = "Send Verification Code"; +} + +

@ViewData["Title"].

+ +
+ +
+
+ Select Two-Factor Authentication Provider: + + +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/VerifyCode.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/VerifyCode.cshtml new file mode 100644 index 000000000000..65ceb2b51057 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Account/VerifyCode.cshtml @@ -0,0 +1,38 @@ +@model VerifyCodeViewModel +@{ + ViewData["Title"] = "Verify"; +} + +

@ViewData["Title"].

+ +
+
+ + +

@ViewData["Status"]

+
+
+ +
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/About.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/About.cshtml new file mode 100644 index 000000000000..205bc40c1b12 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/About.cshtml @@ -0,0 +1,218 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@using System.Globalization +@using Microsoft.AspNetCore.Localization; + +@inject IViewLocalizer Localizer +@inject IHtmlLocalizer SharedLocalizer + +@{ + ViewData["Title"] = Localizer["About"]; + var requestCultureFeature = (IRequestCultureFeature)ViewData["requestCultureFeature"]; + var requestCulture = (RequestCulture)ViewData["requestCulture"]; + +} +

@ViewData["Title"].

+@ViewData["Message"] +

@Localizer["Use this area to provide additional information."]

+

SL @SharedLocalizer["Hello!"]

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Winning provider + + @requestCultureFeature.Provider.GetType().Name; +
+ Request Culture + + @requestCulture.Culture.DisplayName (@requestCulture.Culture) +
+ Request UICulture + + @requestCulture.UICulture.DisplayName (@requestCulture.UICulture) +
+ Thread culture + + @CultureInfo.CurrentCulture.DisplayName (@CultureInfo.CurrentCulture) +
+ Thread UI culture + + @CultureInfo.CurrentUICulture.DisplayName (@CultureInfo.CurrentUICulture) +
+ Current date (invariant full) + + @DateTime.Now.ToString("F", System.Globalization.CultureInfo.InvariantCulture); +
+ Current date (invariant) + + @DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture); +
+ Current date (request full) + + @DateTime.Now.ToString("F"); +
+ Current date (request) + + @DateTime.Now.ToString(); +
+ Current time (invariant) + + @DateTime.Now.ToString("T", System.Globalization.CultureInfo.InvariantCulture); +
+ Current time (request) + + @DateTime.Now.ToString("T"); +
+ Big number 4 (invariant) + + @{ + + string msg = (Math.Pow(2, 42) + 0.42).ToString("N", CultureInfo.InvariantCulture); + } + @msg + +
+ Big number (request) + + @{ + msg = (Math.Pow(2, 42) + 0.42).ToString("N"); + } + @msg +
+ Negative big number (invariant) + + @{ + + msg = (-Math.Pow(2, 42) + 0.42).ToString("N", CultureInfo.InvariantCulture); + } + @msg +
+ Negative big number (request) + + @{ + + msg = (-Math.Pow(2, 42) + 0.42).ToString("N"); + } + @msg +
+ Money (invariant) + + @{ + + msg = (2199.50).ToString("C", CultureInfo.InvariantCulture); + } + @msg +
+ Money(request) + + @{ + msg = (2199.50).ToString("C"); + } + @msg +
+ Negative Money(invariant) + + @{ + + msg = (-2199.50).ToString("C", CultureInfo.InvariantCulture); + } + @msg +
+ Negative Money(request) + + @{ + msg = (-2199.50).ToString("C"); + } + @msg +
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Contact.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Contact.cshtml new file mode 100644 index 000000000000..c5a1b1e7131e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Contact.cshtml @@ -0,0 +1,21 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Contact"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ @Localizer["P"]: + 425.555.0100 +
+ +
+ @Localizer["Support"]: Support@example.com
+ @Localizer["Marketing"]: Marketing@example.com +
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Hello.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Hello.cshtml new file mode 100644 index 000000000000..f5b3dad11623 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Hello.cshtml @@ -0,0 +1,12 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+

Msg: @ViewData["Message"]

+

Msg: @ViewData["Message"]

+ +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Index.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Index.cshtml new file mode 100644 index 000000000000..df0d0790b9c4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Book/Index.cshtml @@ -0,0 +1,120 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@* The IViewLocalizer can be injected into the view. It does two things of interest: + 1. It can HTML encode *parameters* passed to resource strings (not the resource strings themselves, as they may contain + HTML) automatically, and return the result as an IHtmlContent so Razor won't HTML encode it again; + 2. It looks for localization resources for this view based on the view path, e.g. if the view's path is + "MyApplication/Views/Home/Index.cshtml", then the corresponding resource base path will be "MyApplication.Views.Home.Index" *@ + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Home Page"]; +} + + + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About.cshtml new file mode 100644 index 000000000000..018245df35cc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About.cshtml @@ -0,0 +1,11 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About2.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About2.cshtml new file mode 100644 index 000000000000..018245df35cc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/About2.cshtml @@ -0,0 +1,11 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Contact.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Contact.cshtml new file mode 100644 index 000000000000..c5a1b1e7131e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Contact.cshtml @@ -0,0 +1,21 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Contact"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ @Localizer["P"]: + 425.555.0100 +
+ +
+ @Localizer["Support"]: Support@example.com
+ @Localizer["Marketing"]: Marketing@example.com +
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Index.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Index.cshtml new file mode 100644 index 000000000000..b2c790da70cb --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Home/Index.cshtml @@ -0,0 +1,57 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@* The IViewLocalizer can be injected into the view. It does two things of interest: + 1. It can HTML encode *parameters* passed to resource strings (not the resource strings themselves, as they may contain + HTML) automatically, and return the result as an IHtmlContent so Razor won't HTML encode it again; + 2. It looks for localization resources for this view based on the view path, e.g. if the view's path is + "MyApplication/Views/Home/Index.cshtml", then the corresponding resource base path will be "MyApplication.Views.Home.Index" *@ + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Home Page"]; +} + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/About.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/About.cshtml new file mode 100644 index 000000000000..ce36e763440d --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/About.cshtml @@ -0,0 +1,12 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+ +@ViewData["Message"] + +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Contact.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Contact.cshtml new file mode 100644 index 000000000000..c5a1b1e7131e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Contact.cshtml @@ -0,0 +1,21 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Contact"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ @Localizer["P"]: + 425.555.0100 +
+ +
+ @Localizer["Support"]: Support@example.com
+ @Localizer["Marketing"]: Marketing@example.com +
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Hello.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Hello.cshtml new file mode 100644 index 000000000000..018245df35cc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Hello.cshtml @@ -0,0 +1,11 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Index.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Index.cshtml new file mode 100644 index 000000000000..df0d0790b9c4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Info/Index.cshtml @@ -0,0 +1,120 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@* The IViewLocalizer can be injected into the view. It does two things of interest: + 1. It can HTML encode *parameters* passed to resource strings (not the resource strings themselves, as they may contain + HTML) automatically, and return the result as an IHtmlContent so Razor won't HTML encode it again; + 2. It looks for localization resources for this view based on the view path, e.g. if the view's path is + "MyApplication/Views/Home/Index.cshtml", then the corresponding resource base path will be "MyApplication.Views.Home.Index" *@ + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Home Page"]; +} + + + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/AddPhoneNumber.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/AddPhoneNumber.cshtml new file mode 100644 index 000000000000..3f30957e168f --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/AddPhoneNumber.cshtml @@ -0,0 +1,27 @@ +@model AddPhoneNumberViewModel +@{ + ViewData["Title"] = "Add Phone Number"; +} + +

@ViewData["Title"].

+
+

Add a phone number.

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ChangePassword.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ChangePassword.cshtml new file mode 100644 index 000000000000..e8cbacd86d11 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ChangePassword.cshtml @@ -0,0 +1,42 @@ +@model ChangePasswordViewModel +@{ + ViewData["Title"] = "Change Password"; +} + +

@ViewData["Title"].

+ +
+

Change Password Form

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/Index.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/Index.cshtml new file mode 100644 index 000000000000..f6b4a8322ef8 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/Index.cshtml @@ -0,0 +1,77 @@ +@model IndexViewModel +@{ + ViewData["Title"] = "Manage your account"; +} + +

@ViewData["Title"].

+

@ViewData["StatusMessage"]

+
+

Change your account settings

+
+
+
Password:
+
+ [ + @if (Model.HasPassword) + { + Change + } + else + { + Create + } + ] +
+
External Logins:
+
+ @Model.Logins.Count [Manage] +
+ +
Phone Number:
+
+

+ Phone Numbers can used as a second factor of verification in two-factor authentication. + See this article + for details on setting up this ASP.NET application to support two-factor authentication using SMS. +

+ @*@(Model.PhoneNumber ?? "None") [ + @if (Model.PhoneNumber != null) + { + Change + @:  |  + Remove + } + else + { + Add + } + ]*@ +
+ +
Two-Factor Authentication:
+
+

+ There are no two-factor authentication providers configured. See this article + for setting up this application to support two-factor authentication. +

+ @*@if (Model.TwoFactor) + { +
+ + Enabled + + +
+ } + else + { +
+ + Disabled + + +
+ }*@ +
+
+
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ManageLogins.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ManageLogins.cshtml new file mode 100644 index 000000000000..a3ea3229a86d --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/ManageLogins.cshtml @@ -0,0 +1,53 @@ +@model ManageLoginsViewModel +@{ + ViewData["Title"] = "Manage your external logins"; +} + +

@ViewData["Title"].

+ +

@ViewData["StatusMessage"]

+@if (Model.CurrentLogins.Count > 0) +{ +

Registered Logins

+ + + @foreach (var account in Model.CurrentLogins) + { + + + + + } + +
@account.LoginProvider + @if ((bool)ViewData["ShowRemoveButton"]) + { +
+
+ + + +
+
+ } + else + { + @:   + } +
+} +@if (Model.OtherLogins.Count > 0) +{ +

Add another service to log in.

+
+
+
+

+ @foreach (var provider in Model.OtherLogins) + { + + } +

+
+
+} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/SetPassword.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/SetPassword.cshtml new file mode 100644 index 000000000000..8697bf884d84 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/SetPassword.cshtml @@ -0,0 +1,38 @@ +@model SetPasswordViewModel +@{ + ViewData["Title"] = "Set Password"; +} + +

+ You do not have a local username/password for this site. Add a local + account so you can log in without an external login. +

+ +
+

Set your password

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/VerifyPhoneNumber.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/VerifyPhoneNumber.cshtml new file mode 100644 index 000000000000..3d9a06d1c6d1 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Manage/VerifyPhoneNumber.cshtml @@ -0,0 +1,30 @@ +@model VerifyPhoneNumberViewModel +@{ + ViewData["Title"] = "Verify Phone Number"; +} + +

@ViewData["Title"].

+ +
+ +

Add a phone number.

+
@ViewData["Status"]
+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/Error.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/Error.cshtml new file mode 100644 index 000000000000..4852442680b6 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/Error.cshtml @@ -0,0 +1,6 @@ +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_Layout.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_Layout.cshtml new file mode 100644 index 000000000000..d0280c39baf1 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_Layout.cshtml @@ -0,0 +1,67 @@ +@using System.Globalization +@using Microsoft.AspNetCore.Http.Features +@using Microsoft.AspNetCore.Localization +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + + + + + + + @ViewData["Title"] - Localization + + + + + + + + + +
+ @RenderBody() +
+
+
+
+

© @System.DateTime.Now.Year - Localization

+
+
+ @await Html.PartialAsync("_SelectLanguagePartial") +
+
+
+
+ + + + + + + + + @RenderSection("scripts", required: false) + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_LoginPartial.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_LoginPartial.cshtml new file mode 100644 index 000000000000..c284667fe5ab --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_LoginPartial.cshtml @@ -0,0 +1,31 @@ +@using System.Security.Claims +@using Microsoft.AspNetCore.Localization +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer +@inject SignInManager SignInManager +@inject UserManager UserManager + +@if (SignInManager.IsSignedIn(User)) +{ + +} +else +{ + +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_SelectLanguagePartial.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_SelectLanguagePartial.cshtml new file mode 100644 index 000000000000..e5358f03a5b8 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_SelectLanguagePartial.cshtml @@ -0,0 +1,27 @@ +@using Microsoft.AspNetCore.Builder +@using Microsoft.AspNetCore.Http.Features +@using Microsoft.AspNetCore.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Options + +@inject IViewLocalizer Localizer +@inject IOptions LocOptions + +@{ + var requestCulture = Context.Features.Get(); + var cultureItems = LocOptions.Value.SupportedUICultures + .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) + .ToList(); + var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; +} + +
+
+ +
+
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_ValidationScriptsPartial.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 000000000000..970fc49c1a12 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/About.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/About.cshtml new file mode 100644 index 000000000000..28936a0f943c --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/About.cshtml @@ -0,0 +1,12 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@using Localization.Services + +@inject IViewLocalizer Localizer +@inject IHtmlLocalizer SharedLocalizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+ +

@SharedLocalizer["Hello!"]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Contact.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Contact.cshtml new file mode 100644 index 000000000000..c5a1b1e7131e --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Contact.cshtml @@ -0,0 +1,21 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Contact"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ @Localizer["P"]: + 425.555.0100 +
+ +
+ @Localizer["Support"]: Support@example.com
+ @Localizer["Marketing"]: Marketing@example.com +
diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Hello.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Hello.cshtml new file mode 100644 index 000000000000..018245df35cc --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Hello.cshtml @@ -0,0 +1,11 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["About"]; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

@Localizer["Use this area to provide additional information."]

diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Index.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Index.cshtml new file mode 100644 index 000000000000..df0d0790b9c4 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/Test/Index.cshtml @@ -0,0 +1,120 @@ +@using Microsoft.AspNetCore.Mvc.Localization + +@* The IViewLocalizer can be injected into the view. It does two things of interest: + 1. It can HTML encode *parameters* passed to resource strings (not the resource strings themselves, as they may contain + HTML) automatically, and return the result as an IHtmlContent so Razor won't HTML encode it again; + 2. It looks for localization resources for this view based on the view path, e.g. if the view's path is + "MyApplication/Views/Home/Index.cshtml", then the corresponding resource base path will be "MyApplication.Views.Home.Index" *@ + +@inject IViewLocalizer Localizer + +@{ + ViewData["Title"] = Localizer["Home Page"]; +} + + + + diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewImports.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewImports.cshtml new file mode 100644 index 000000000000..f3b06a140e5a --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewImports.cshtml @@ -0,0 +1,6 @@ +@using Localization +@using Localization.Models +@using Localization.ViewModels.Account +@using Localization.ViewModels.Manage +@using Microsoft.AspNetCore.Identity +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewStart.cshtml b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewStart.cshtml new file mode 100644 index 000000000000..a5f10045db97 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/appsettings.json b/aspnetcore/fundamentals/localization/sample/8.x/Localization/appsettings.json new file mode 100644 index 000000000000..d72f2fa9a330 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/appsettings.json @@ -0,0 +1,15 @@ +{ + "Data": { + "DefaultConnection": { + "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet6-Localization-4772c50f-56f3-4058-bd61-75f1352aeca7;Trusted_Connection=True;MultipleActiveResultSets=true" + } + }, + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/css/bootstrap-3.3.7.css b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/css/bootstrap-3.3.7.css new file mode 100644 index 000000000000..6a4708e438b8 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/css/bootstrap-3.3.7.css @@ -0,0 +1,6757 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + } + body { + margin: 0; + } + article, + aside, + details, + figcaption, + figure, + footer, + header, + hgroup, + main, + menu, + nav, + section, + summary { + display: block; + } + audio, + canvas, + progress, + video { + display: inline-block; + vertical-align: baseline; + } + audio:not([controls]) { + display: none; + height: 0; + } + [hidden], + template { + display: none; + } + a { + background-color: transparent; + } + a:active, + a:hover { + outline: 0; + } + abbr[title] { + border-bottom: 1px dotted; + } + b, + strong { + font-weight: bold; + } + dfn { + font-style: italic; + } + h1 { + margin: .67em 0; + font-size: 2em; + } + mark { + color: #000; + background: #ff0; + } + small { + font-size: 80%; + } + sub, + sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; + } + sup { + top: -.5em; + } + sub { + bottom: -.25em; + } + img { + border: 0; + } + svg:not(:root) { + overflow: hidden; + } + figure { + margin: 1em 40px; + } + hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + } + pre { + overflow: auto; + } + code, + kbd, + pre, + samp { + font-family: monospace, monospace; + font-size: 1em; + } + button, + input, + optgroup, + select, + textarea { + margin: 0; + font: inherit; + color: inherit; + } + button { + overflow: visible; + } + button, + select { + text-transform: none; + } + button, + html input[type="button"], + input[type="reset"], + input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; + } + button[disabled], + html input[disabled] { + cursor: default; + } + button::-moz-focus-inner, + input::-moz-focus-inner { + padding: 0; + border: 0; + } + input { + line-height: normal; + } + input[type="checkbox"], + input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + } + input[type="number"]::-webkit-inner-spin-button, + input[type="number"]::-webkit-outer-spin-button { + height: auto; + } + input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; + } + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + } + fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; + } + legend { + padding: 0; + border: 0; + } + textarea { + overflow: auto; + } + optgroup { + font-weight: bold; + } + table { + border-spacing: 0; + border-collapse: collapse; + } + td, + th { + padding: 0; + } + /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ + @media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } + } + @font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); + } + .glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + .glyphicon-asterisk:before { + content: "\002a"; + } + .glyphicon-plus:before { + content: "\002b"; + } + .glyphicon-euro:before, + .glyphicon-eur:before { + content: "\20ac"; + } + .glyphicon-minus:before { + content: "\2212"; + } + .glyphicon-cloud:before { + content: "\2601"; + } + .glyphicon-envelope:before { + content: "\2709"; + } + .glyphicon-pencil:before { + content: "\270f"; + } + .glyphicon-glass:before { + content: "\e001"; + } + .glyphicon-music:before { + content: "\e002"; + } + .glyphicon-search:before { + content: "\e003"; + } + .glyphicon-heart:before { + content: "\e005"; + } + .glyphicon-star:before { + content: "\e006"; + } + .glyphicon-star-empty:before { + content: "\e007"; + } + .glyphicon-user:before { + content: "\e008"; + } + .glyphicon-film:before { + content: "\e009"; + } + .glyphicon-th-large:before { + content: "\e010"; + } + .glyphicon-th:before { + content: "\e011"; + } + .glyphicon-th-list:before { + content: "\e012"; + } + .glyphicon-ok:before { + content: "\e013"; + } + .glyphicon-remove:before { + content: "\e014"; + } + .glyphicon-zoom-in:before { + content: "\e015"; + } + .glyphicon-zoom-out:before { + content: "\e016"; + } + .glyphicon-off:before { + content: "\e017"; + } + .glyphicon-signal:before { + content: "\e018"; + } + .glyphicon-cog:before { + content: "\e019"; + } + .glyphicon-trash:before { + content: "\e020"; + } + .glyphicon-home:before { + content: "\e021"; + } + .glyphicon-file:before { + content: "\e022"; + } + .glyphicon-time:before { + content: "\e023"; + } + .glyphicon-road:before { + content: "\e024"; + } + .glyphicon-download-alt:before { + content: "\e025"; + } + .glyphicon-download:before { + content: "\e026"; + } + .glyphicon-upload:before { + content: "\e027"; + } + .glyphicon-inbox:before { + content: "\e028"; + } + .glyphicon-play-circle:before { + content: "\e029"; + } + .glyphicon-repeat:before { + content: "\e030"; + } + .glyphicon-refresh:before { + content: "\e031"; + } + .glyphicon-list-alt:before { + content: "\e032"; + } + .glyphicon-lock:before { + content: "\e033"; + } + .glyphicon-flag:before { + content: "\e034"; + } + .glyphicon-headphones:before { + content: "\e035"; + } + .glyphicon-volume-off:before { + content: "\e036"; + } + .glyphicon-volume-down:before { + content: "\e037"; + } + .glyphicon-volume-up:before { + content: "\e038"; + } + .glyphicon-qrcode:before { + content: "\e039"; + } + .glyphicon-barcode:before { + content: "\e040"; + } + .glyphicon-tag:before { + content: "\e041"; + } + .glyphicon-tags:before { + content: "\e042"; + } + .glyphicon-book:before { + content: "\e043"; + } + .glyphicon-bookmark:before { + content: "\e044"; + } + .glyphicon-print:before { + content: "\e045"; + } + .glyphicon-camera:before { + content: "\e046"; + } + .glyphicon-font:before { + content: "\e047"; + } + .glyphicon-bold:before { + content: "\e048"; + } + .glyphicon-italic:before { + content: "\e049"; + } + .glyphicon-text-height:before { + content: "\e050"; + } + .glyphicon-text-width:before { + content: "\e051"; + } + .glyphicon-align-left:before { + content: "\e052"; + } + .glyphicon-align-center:before { + content: "\e053"; + } + .glyphicon-align-right:before { + content: "\e054"; + } + .glyphicon-align-justify:before { + content: "\e055"; + } + .glyphicon-list:before { + content: "\e056"; + } + .glyphicon-indent-left:before { + content: "\e057"; + } + .glyphicon-indent-right:before { + content: "\e058"; + } + .glyphicon-facetime-video:before { + content: "\e059"; + } + .glyphicon-picture:before { + content: "\e060"; + } + .glyphicon-map-marker:before { + content: "\e062"; + } + .glyphicon-adjust:before { + content: "\e063"; + } + .glyphicon-tint:before { + content: "\e064"; + } + .glyphicon-edit:before { + content: "\e065"; + } + .glyphicon-share:before { + content: "\e066"; + } + .glyphicon-check:before { + content: "\e067"; + } + .glyphicon-move:before { + content: "\e068"; + } + .glyphicon-step-backward:before { + content: "\e069"; + } + .glyphicon-fast-backward:before { + content: "\e070"; + } + .glyphicon-backward:before { + content: "\e071"; + } + .glyphicon-play:before { + content: "\e072"; + } + .glyphicon-pause:before { + content: "\e073"; + } + .glyphicon-stop:before { + content: "\e074"; + } + .glyphicon-forward:before { + content: "\e075"; + } + .glyphicon-fast-forward:before { + content: "\e076"; + } + .glyphicon-step-forward:before { + content: "\e077"; + } + .glyphicon-eject:before { + content: "\e078"; + } + .glyphicon-chevron-left:before { + content: "\e079"; + } + .glyphicon-chevron-right:before { + content: "\e080"; + } + .glyphicon-plus-sign:before { + content: "\e081"; + } + .glyphicon-minus-sign:before { + content: "\e082"; + } + .glyphicon-remove-sign:before { + content: "\e083"; + } + .glyphicon-ok-sign:before { + content: "\e084"; + } + .glyphicon-question-sign:before { + content: "\e085"; + } + .glyphicon-info-sign:before { + content: "\e086"; + } + .glyphicon-screenshot:before { + content: "\e087"; + } + .glyphicon-remove-circle:before { + content: "\e088"; + } + .glyphicon-ok-circle:before { + content: "\e089"; + } + .glyphicon-ban-circle:before { + content: "\e090"; + } + .glyphicon-arrow-left:before { + content: "\e091"; + } + .glyphicon-arrow-right:before { + content: "\e092"; + } + .glyphicon-arrow-up:before { + content: "\e093"; + } + .glyphicon-arrow-down:before { + content: "\e094"; + } + .glyphicon-share-alt:before { + content: "\e095"; + } + .glyphicon-resize-full:before { + content: "\e096"; + } + .glyphicon-resize-small:before { + content: "\e097"; + } + .glyphicon-exclamation-sign:before { + content: "\e101"; + } + .glyphicon-gift:before { + content: "\e102"; + } + .glyphicon-leaf:before { + content: "\e103"; + } + .glyphicon-fire:before { + content: "\e104"; + } + .glyphicon-eye-open:before { + content: "\e105"; + } + .glyphicon-eye-close:before { + content: "\e106"; + } + .glyphicon-warning-sign:before { + content: "\e107"; + } + .glyphicon-plane:before { + content: "\e108"; + } + .glyphicon-calendar:before { + content: "\e109"; + } + .glyphicon-random:before { + content: "\e110"; + } + .glyphicon-comment:before { + content: "\e111"; + } + .glyphicon-magnet:before { + content: "\e112"; + } + .glyphicon-chevron-up:before { + content: "\e113"; + } + .glyphicon-chevron-down:before { + content: "\e114"; + } + .glyphicon-retweet:before { + content: "\e115"; + } + .glyphicon-shopping-cart:before { + content: "\e116"; + } + .glyphicon-folder-close:before { + content: "\e117"; + } + .glyphicon-folder-open:before { + content: "\e118"; + } + .glyphicon-resize-vertical:before { + content: "\e119"; + } + .glyphicon-resize-horizontal:before { + content: "\e120"; + } + .glyphicon-hdd:before { + content: "\e121"; + } + .glyphicon-bullhorn:before { + content: "\e122"; + } + .glyphicon-bell:before { + content: "\e123"; + } + .glyphicon-certificate:before { + content: "\e124"; + } + .glyphicon-thumbs-up:before { + content: "\e125"; + } + .glyphicon-thumbs-down:before { + content: "\e126"; + } + .glyphicon-hand-right:before { + content: "\e127"; + } + .glyphicon-hand-left:before { + content: "\e128"; + } + .glyphicon-hand-up:before { + content: "\e129"; + } + .glyphicon-hand-down:before { + content: "\e130"; + } + .glyphicon-circle-arrow-right:before { + content: "\e131"; + } + .glyphicon-circle-arrow-left:before { + content: "\e132"; + } + .glyphicon-circle-arrow-up:before { + content: "\e133"; + } + .glyphicon-circle-arrow-down:before { + content: "\e134"; + } + .glyphicon-globe:before { + content: "\e135"; + } + .glyphicon-wrench:before { + content: "\e136"; + } + .glyphicon-tasks:before { + content: "\e137"; + } + .glyphicon-filter:before { + content: "\e138"; + } + .glyphicon-briefcase:before { + content: "\e139"; + } + .glyphicon-fullscreen:before { + content: "\e140"; + } + .glyphicon-dashboard:before { + content: "\e141"; + } + .glyphicon-paperclip:before { + content: "\e142"; + } + .glyphicon-heart-empty:before { + content: "\e143"; + } + .glyphicon-link:before { + content: "\e144"; + } + .glyphicon-phone:before { + content: "\e145"; + } + .glyphicon-pushpin:before { + content: "\e146"; + } + .glyphicon-usd:before { + content: "\e148"; + } + .glyphicon-gbp:before { + content: "\e149"; + } + .glyphicon-sort:before { + content: "\e150"; + } + .glyphicon-sort-by-alphabet:before { + content: "\e151"; + } + .glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; + } + .glyphicon-sort-by-order:before { + content: "\e153"; + } + .glyphicon-sort-by-order-alt:before { + content: "\e154"; + } + .glyphicon-sort-by-attributes:before { + content: "\e155"; + } + .glyphicon-sort-by-attributes-alt:before { + content: "\e156"; + } + .glyphicon-unchecked:before { + content: "\e157"; + } + .glyphicon-expand:before { + content: "\e158"; + } + .glyphicon-collapse-down:before { + content: "\e159"; + } + .glyphicon-collapse-up:before { + content: "\e160"; + } + .glyphicon-log-in:before { + content: "\e161"; + } + .glyphicon-flash:before { + content: "\e162"; + } + .glyphicon-log-out:before { + content: "\e163"; + } + .glyphicon-new-window:before { + content: "\e164"; + } + .glyphicon-record:before { + content: "\e165"; + } + .glyphicon-save:before { + content: "\e166"; + } + .glyphicon-open:before { + content: "\e167"; + } + .glyphicon-saved:before { + content: "\e168"; + } + .glyphicon-import:before { + content: "\e169"; + } + .glyphicon-export:before { + content: "\e170"; + } + .glyphicon-send:before { + content: "\e171"; + } + .glyphicon-floppy-disk:before { + content: "\e172"; + } + .glyphicon-floppy-saved:before { + content: "\e173"; + } + .glyphicon-floppy-remove:before { + content: "\e174"; + } + .glyphicon-floppy-save:before { + content: "\e175"; + } + .glyphicon-floppy-open:before { + content: "\e176"; + } + .glyphicon-credit-card:before { + content: "\e177"; + } + .glyphicon-transfer:before { + content: "\e178"; + } + .glyphicon-cutlery:before { + content: "\e179"; + } + .glyphicon-header:before { + content: "\e180"; + } + .glyphicon-compressed:before { + content: "\e181"; + } + .glyphicon-earphone:before { + content: "\e182"; + } + .glyphicon-phone-alt:before { + content: "\e183"; + } + .glyphicon-tower:before { + content: "\e184"; + } + .glyphicon-stats:before { + content: "\e185"; + } + .glyphicon-sd-video:before { + content: "\e186"; + } + .glyphicon-hd-video:before { + content: "\e187"; + } + .glyphicon-subtitles:before { + content: "\e188"; + } + .glyphicon-sound-stereo:before { + content: "\e189"; + } + .glyphicon-sound-dolby:before { + content: "\e190"; + } + .glyphicon-sound-5-1:before { + content: "\e191"; + } + .glyphicon-sound-6-1:before { + content: "\e192"; + } + .glyphicon-sound-7-1:before { + content: "\e193"; + } + .glyphicon-copyright-mark:before { + content: "\e194"; + } + .glyphicon-registration-mark:before { + content: "\e195"; + } + .glyphicon-cloud-download:before { + content: "\e197"; + } + .glyphicon-cloud-upload:before { + content: "\e198"; + } + .glyphicon-tree-conifer:before { + content: "\e199"; + } + .glyphicon-tree-deciduous:before { + content: "\e200"; + } + .glyphicon-cd:before { + content: "\e201"; + } + .glyphicon-save-file:before { + content: "\e202"; + } + .glyphicon-open-file:before { + content: "\e203"; + } + .glyphicon-level-up:before { + content: "\e204"; + } + .glyphicon-copy:before { + content: "\e205"; + } + .glyphicon-paste:before { + content: "\e206"; + } + .glyphicon-alert:before { + content: "\e209"; + } + .glyphicon-equalizer:before { + content: "\e210"; + } + .glyphicon-king:before { + content: "\e211"; + } + .glyphicon-queen:before { + content: "\e212"; + } + .glyphicon-pawn:before { + content: "\e213"; + } + .glyphicon-bishop:before { + content: "\e214"; + } + .glyphicon-knight:before { + content: "\e215"; + } + .glyphicon-baby-formula:before { + content: "\e216"; + } + .glyphicon-tent:before { + content: "\26fa"; + } + .glyphicon-blackboard:before { + content: "\e218"; + } + .glyphicon-bed:before { + content: "\e219"; + } + .glyphicon-apple:before { + content: "\f8ff"; + } + .glyphicon-erase:before { + content: "\e221"; + } + .glyphicon-hourglass:before { + content: "\231b"; + } + .glyphicon-lamp:before { + content: "\e223"; + } + .glyphicon-duplicate:before { + content: "\e224"; + } + .glyphicon-piggy-bank:before { + content: "\e225"; + } + .glyphicon-scissors:before { + content: "\e226"; + } + .glyphicon-bitcoin:before { + content: "\e227"; + } + .glyphicon-btc:before { + content: "\e227"; + } + .glyphicon-xbt:before { + content: "\e227"; + } + .glyphicon-yen:before { + content: "\00a5"; + } + .glyphicon-jpy:before { + content: "\00a5"; + } + .glyphicon-ruble:before { + content: "\20bd"; + } + .glyphicon-rub:before { + content: "\20bd"; + } + .glyphicon-scale:before { + content: "\e230"; + } + .glyphicon-ice-lolly:before { + content: "\e231"; + } + .glyphicon-ice-lolly-tasted:before { + content: "\e232"; + } + .glyphicon-education:before { + content: "\e233"; + } + .glyphicon-option-horizontal:before { + content: "\e234"; + } + .glyphicon-option-vertical:before { + content: "\e235"; + } + .glyphicon-menu-hamburger:before { + content: "\e236"; + } + .glyphicon-modal-window:before { + content: "\e237"; + } + .glyphicon-oil:before { + content: "\e238"; + } + .glyphicon-grain:before { + content: "\e239"; + } + .glyphicon-sunglasses:before { + content: "\e240"; + } + .glyphicon-text-size:before { + content: "\e241"; + } + .glyphicon-text-color:before { + content: "\e242"; + } + .glyphicon-text-background:before { + content: "\e243"; + } + .glyphicon-object-align-top:before { + content: "\e244"; + } + .glyphicon-object-align-bottom:before { + content: "\e245"; + } + .glyphicon-object-align-horizontal:before { + content: "\e246"; + } + .glyphicon-object-align-left:before { + content: "\e247"; + } + .glyphicon-object-align-vertical:before { + content: "\e248"; + } + .glyphicon-object-align-right:before { + content: "\e249"; + } + .glyphicon-triangle-right:before { + content: "\e250"; + } + .glyphicon-triangle-left:before { + content: "\e251"; + } + .glyphicon-triangle-bottom:before { + content: "\e252"; + } + .glyphicon-triangle-top:before { + content: "\e253"; + } + .glyphicon-console:before { + content: "\e254"; + } + .glyphicon-superscript:before { + content: "\e255"; + } + .glyphicon-subscript:before { + content: "\e256"; + } + .glyphicon-menu-left:before { + content: "\e257"; + } + .glyphicon-menu-right:before { + content: "\e258"; + } + .glyphicon-menu-down:before { + content: "\e259"; + } + .glyphicon-menu-up:before { + content: "\e260"; + } + * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + *:before, + *:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + } + body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; + } + input, + button, + select, + textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; + } + a { + color: #337ab7; + text-decoration: none; + } + a:hover, + a:focus { + color: #23527c; + text-decoration: underline; + } + a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } + figure { + margin: 0; + } + img { + vertical-align: middle; + } + .img-responsive, + .thumbnail > img, + .thumbnail a > img, + .carousel-inner > .item > img, + .carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; + } + .img-rounded { + border-radius: 6px; + } + .img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; + } + .img-circle { + border-radius: 50%; + } + hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; + } + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + } + .sr-only-focusable:active, + .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; + } + [role="button"] { + cursor: pointer; + } + h1, + h2, + h3, + h4, + h5, + h6, + .h1, + .h2, + .h3, + .h4, + .h5, + .h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; + } + h1 small, + h2 small, + h3 small, + h4 small, + h5 small, + h6 small, + .h1 small, + .h2 small, + .h3 small, + .h4 small, + .h5 small, + .h6 small, + h1 .small, + h2 .small, + h3 .small, + h4 .small, + h5 .small, + h6 .small, + .h1 .small, + .h2 .small, + .h3 .small, + .h4 .small, + .h5 .small, + .h6 .small { + font-weight: normal; + line-height: 1; + color: #777; + } + h1, + .h1, + h2, + .h2, + h3, + .h3 { + margin-top: 20px; + margin-bottom: 10px; + } + h1 small, + .h1 small, + h2 small, + .h2 small, + h3 small, + .h3 small, + h1 .small, + .h1 .small, + h2 .small, + .h2 .small, + h3 .small, + .h3 .small { + font-size: 65%; + } + h4, + .h4, + h5, + .h5, + h6, + .h6 { + margin-top: 10px; + margin-bottom: 10px; + } + h4 small, + .h4 small, + h5 small, + .h5 small, + h6 small, + .h6 small, + h4 .small, + .h4 .small, + h5 .small, + .h5 .small, + h6 .small, + .h6 .small { + font-size: 75%; + } + h1, + .h1 { + font-size: 36px; + } + h2, + .h2 { + font-size: 30px; + } + h3, + .h3 { + font-size: 24px; + } + h4, + .h4 { + font-size: 18px; + } + h5, + .h5 { + font-size: 14px; + } + h6, + .h6 { + font-size: 12px; + } + p { + margin: 0 0 10px; + } + .lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; + } + @media (min-width: 768px) { + .lead { + font-size: 21px; + } + } + small, + .small { + font-size: 85%; + } + mark, + .mark { + padding: .2em; + background-color: #fcf8e3; + } + .text-left { + text-align: left; + } + .text-right { + text-align: right; + } + .text-center { + text-align: center; + } + .text-justify { + text-align: justify; + } + .text-nowrap { + white-space: nowrap; + } + .text-lowercase { + text-transform: lowercase; + } + .text-uppercase { + text-transform: uppercase; + } + .text-capitalize { + text-transform: capitalize; + } + .text-muted { + color: #777; + } + .text-primary { + color: #337ab7; + } + a.text-primary:hover, + a.text-primary:focus { + color: #286090; + } + .text-success { + color: #3c763d; + } + a.text-success:hover, + a.text-success:focus { + color: #2b542c; + } + .text-info { + color: #31708f; + } + a.text-info:hover, + a.text-info:focus { + color: #245269; + } + .text-warning { + color: #8a6d3b; + } + a.text-warning:hover, + a.text-warning:focus { + color: #66512c; + } + .text-danger { + color: #a94442; + } + a.text-danger:hover, + a.text-danger:focus { + color: #843534; + } + .bg-primary { + color: #fff; + background-color: #337ab7; + } + a.bg-primary:hover, + a.bg-primary:focus { + background-color: #286090; + } + .bg-success { + background-color: #dff0d8; + } + a.bg-success:hover, + a.bg-success:focus { + background-color: #c1e2b3; + } + .bg-info { + background-color: #d9edf7; + } + a.bg-info:hover, + a.bg-info:focus { + background-color: #afd9ee; + } + .bg-warning { + background-color: #fcf8e3; + } + a.bg-warning:hover, + a.bg-warning:focus { + background-color: #f7ecb5; + } + .bg-danger { + background-color: #f2dede; + } + a.bg-danger:hover, + a.bg-danger:focus { + background-color: #e4b9b9; + } + .page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; + } + ul, + ol { + margin-top: 0; + margin-bottom: 10px; + } + ul ul, + ol ul, + ul ol, + ol ol { + margin-bottom: 0; + } + .list-unstyled { + padding-left: 0; + list-style: none; + } + .list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; + } + .list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; + } + dl { + margin-top: 0; + margin-bottom: 20px; + } + dt, + dd { + line-height: 1.42857143; + } + dt { + font-weight: bold; + } + dd { + margin-left: 0; + } + @media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } + } + abbr[title], + abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; + } + .initialism { + font-size: 90%; + text-transform: uppercase; + } + blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; + } + blockquote p:last-child, + blockquote ul:last-child, + blockquote ol:last-child { + margin-bottom: 0; + } + blockquote footer, + blockquote small, + blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; + } + blockquote footer:before, + blockquote small:before, + blockquote .small:before { + content: '\2014 \00A0'; + } + .blockquote-reverse, + blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; + } + .blockquote-reverse footer:before, + blockquote.pull-right footer:before, + .blockquote-reverse small:before, + blockquote.pull-right small:before, + .blockquote-reverse .small:before, + blockquote.pull-right .small:before { + content: ''; + } + .blockquote-reverse footer:after, + blockquote.pull-right footer:after, + .blockquote-reverse small:after, + blockquote.pull-right small:after, + .blockquote-reverse .small:after, + blockquote.pull-right .small:after { + content: '\00A0 \2014'; + } + address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; + } + code, + kbd, + pre, + samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + } + code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; + } + kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + } + kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; + } + pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; + } + pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; + } + .pre-scrollable { + max-height: 340px; + overflow-y: scroll; + } + .container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; + } + @media (min-width: 768px) { + .container { + width: 750px; + } + } + @media (min-width: 992px) { + .container { + width: 970px; + } + } + @media (min-width: 1200px) { + .container { + width: 1170px; + } + } + .container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; + } + .row { + margin-right: -15px; + margin-left: -15px; + } + .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; + } + .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; + } + .col-xs-12 { + width: 100%; + } + .col-xs-11 { + width: 91.66666667%; + } + .col-xs-10 { + width: 83.33333333%; + } + .col-xs-9 { + width: 75%; + } + .col-xs-8 { + width: 66.66666667%; + } + .col-xs-7 { + width: 58.33333333%; + } + .col-xs-6 { + width: 50%; + } + .col-xs-5 { + width: 41.66666667%; + } + .col-xs-4 { + width: 33.33333333%; + } + .col-xs-3 { + width: 25%; + } + .col-xs-2 { + width: 16.66666667%; + } + .col-xs-1 { + width: 8.33333333%; + } + .col-xs-pull-12 { + right: 100%; + } + .col-xs-pull-11 { + right: 91.66666667%; + } + .col-xs-pull-10 { + right: 83.33333333%; + } + .col-xs-pull-9 { + right: 75%; + } + .col-xs-pull-8 { + right: 66.66666667%; + } + .col-xs-pull-7 { + right: 58.33333333%; + } + .col-xs-pull-6 { + right: 50%; + } + .col-xs-pull-5 { + right: 41.66666667%; + } + .col-xs-pull-4 { + right: 33.33333333%; + } + .col-xs-pull-3 { + right: 25%; + } + .col-xs-pull-2 { + right: 16.66666667%; + } + .col-xs-pull-1 { + right: 8.33333333%; + } + .col-xs-pull-0 { + right: auto; + } + .col-xs-push-12 { + left: 100%; + } + .col-xs-push-11 { + left: 91.66666667%; + } + .col-xs-push-10 { + left: 83.33333333%; + } + .col-xs-push-9 { + left: 75%; + } + .col-xs-push-8 { + left: 66.66666667%; + } + .col-xs-push-7 { + left: 58.33333333%; + } + .col-xs-push-6 { + left: 50%; + } + .col-xs-push-5 { + left: 41.66666667%; + } + .col-xs-push-4 { + left: 33.33333333%; + } + .col-xs-push-3 { + left: 25%; + } + .col-xs-push-2 { + left: 16.66666667%; + } + .col-xs-push-1 { + left: 8.33333333%; + } + .col-xs-push-0 { + left: auto; + } + .col-xs-offset-12 { + margin-left: 100%; + } + .col-xs-offset-11 { + margin-left: 91.66666667%; + } + .col-xs-offset-10 { + margin-left: 83.33333333%; + } + .col-xs-offset-9 { + margin-left: 75%; + } + .col-xs-offset-8 { + margin-left: 66.66666667%; + } + .col-xs-offset-7 { + margin-left: 58.33333333%; + } + .col-xs-offset-6 { + margin-left: 50%; + } + .col-xs-offset-5 { + margin-left: 41.66666667%; + } + .col-xs-offset-4 { + margin-left: 33.33333333%; + } + .col-xs-offset-3 { + margin-left: 25%; + } + .col-xs-offset-2 { + margin-left: 16.66666667%; + } + .col-xs-offset-1 { + margin-left: 8.33333333%; + } + .col-xs-offset-0 { + margin-left: 0; + } + @media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } + } + @media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } + } + @media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } + } + table { + background-color: transparent; + } + caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; + } + th { + text-align: left; + } + .table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; + } + .table > thead > tr > th, + .table > tbody > tr > th, + .table > tfoot > tr > th, + .table > thead > tr > td, + .table > tbody > tr > td, + .table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; + } + .table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; + } + .table > caption + thead > tr:first-child > th, + .table > colgroup + thead > tr:first-child > th, + .table > thead:first-child > tr:first-child > th, + .table > caption + thead > tr:first-child > td, + .table > colgroup + thead > tr:first-child > td, + .table > thead:first-child > tr:first-child > td { + border-top: 0; + } + .table > tbody + tbody { + border-top: 2px solid #ddd; + } + .table .table { + background-color: #fff; + } + .table-condensed > thead > tr > th, + .table-condensed > tbody > tr > th, + .table-condensed > tfoot > tr > th, + .table-condensed > thead > tr > td, + .table-condensed > tbody > tr > td, + .table-condensed > tfoot > tr > td { + padding: 5px; + } + .table-bordered { + border: 1px solid #ddd; + } + .table-bordered > thead > tr > th, + .table-bordered > tbody > tr > th, + .table-bordered > tfoot > tr > th, + .table-bordered > thead > tr > td, + .table-bordered > tbody > tr > td, + .table-bordered > tfoot > tr > td { + border: 1px solid #ddd; + } + .table-bordered > thead > tr > th, + .table-bordered > thead > tr > td { + border-bottom-width: 2px; + } + .table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; + } + .table-hover > tbody > tr:hover { + background-color: #f5f5f5; + } + table col[class*="col-"] { + position: static; + display: table-column; + float: none; + } + table td[class*="col-"], + table th[class*="col-"] { + position: static; + display: table-cell; + float: none; + } + .table > thead > tr > td.active, + .table > tbody > tr > td.active, + .table > tfoot > tr > td.active, + .table > thead > tr > th.active, + .table > tbody > tr > th.active, + .table > tfoot > tr > th.active, + .table > thead > tr.active > td, + .table > tbody > tr.active > td, + .table > tfoot > tr.active > td, + .table > thead > tr.active > th, + .table > tbody > tr.active > th, + .table > tfoot > tr.active > th { + background-color: #f5f5f5; + } + .table-hover > tbody > tr > td.active:hover, + .table-hover > tbody > tr > th.active:hover, + .table-hover > tbody > tr.active:hover > td, + .table-hover > tbody > tr:hover > .active, + .table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; + } + .table > thead > tr > td.success, + .table > tbody > tr > td.success, + .table > tfoot > tr > td.success, + .table > thead > tr > th.success, + .table > tbody > tr > th.success, + .table > tfoot > tr > th.success, + .table > thead > tr.success > td, + .table > tbody > tr.success > td, + .table > tfoot > tr.success > td, + .table > thead > tr.success > th, + .table > tbody > tr.success > th, + .table > tfoot > tr.success > th { + background-color: #dff0d8; + } + .table-hover > tbody > tr > td.success:hover, + .table-hover > tbody > tr > th.success:hover, + .table-hover > tbody > tr.success:hover > td, + .table-hover > tbody > tr:hover > .success, + .table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; + } + .table > thead > tr > td.info, + .table > tbody > tr > td.info, + .table > tfoot > tr > td.info, + .table > thead > tr > th.info, + .table > tbody > tr > th.info, + .table > tfoot > tr > th.info, + .table > thead > tr.info > td, + .table > tbody > tr.info > td, + .table > tfoot > tr.info > td, + .table > thead > tr.info > th, + .table > tbody > tr.info > th, + .table > tfoot > tr.info > th { + background-color: #d9edf7; + } + .table-hover > tbody > tr > td.info:hover, + .table-hover > tbody > tr > th.info:hover, + .table-hover > tbody > tr.info:hover > td, + .table-hover > tbody > tr:hover > .info, + .table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; + } + .table > thead > tr > td.warning, + .table > tbody > tr > td.warning, + .table > tfoot > tr > td.warning, + .table > thead > tr > th.warning, + .table > tbody > tr > th.warning, + .table > tfoot > tr > th.warning, + .table > thead > tr.warning > td, + .table > tbody > tr.warning > td, + .table > tfoot > tr.warning > td, + .table > thead > tr.warning > th, + .table > tbody > tr.warning > th, + .table > tfoot > tr.warning > th { + background-color: #fcf8e3; + } + .table-hover > tbody > tr > td.warning:hover, + .table-hover > tbody > tr > th.warning:hover, + .table-hover > tbody > tr.warning:hover > td, + .table-hover > tbody > tr:hover > .warning, + .table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; + } + .table > thead > tr > td.danger, + .table > tbody > tr > td.danger, + .table > tfoot > tr > td.danger, + .table > thead > tr > th.danger, + .table > tbody > tr > th.danger, + .table > tfoot > tr > th.danger, + .table > thead > tr.danger > td, + .table > tbody > tr.danger > td, + .table > tfoot > tr.danger > td, + .table > thead > tr.danger > th, + .table > tbody > tr.danger > th, + .table > tfoot > tr.danger > th { + background-color: #f2dede; + } + .table-hover > tbody > tr > td.danger:hover, + .table-hover > tbody > tr > th.danger:hover, + .table-hover > tbody > tr.danger:hover > td, + .table-hover > tbody > tr:hover > .danger, + .table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; + } + .table-responsive { + min-height: .01%; + overflow-x: auto; + } + @media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } + } + fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; + } + legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; + } + label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; + } + input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + input[type="radio"], + input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; + } + input[type="file"] { + display: block; + } + input[type="range"] { + display: block; + width: 100%; + } + select[multiple], + select[size] { + height: auto; + } + input[type="file"]:focus, + input[type="radio"]:focus, + input[type="checkbox"]:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } + output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + } + .form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + } + .form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + } + .form-control::-moz-placeholder { + color: #999; + opacity: 1; + } + .form-control:-ms-input-placeholder { + color: #999; + } + .form-control::-webkit-input-placeholder { + color: #999; + } + .form-control::-ms-expand { + background-color: transparent; + border: 0; + } + .form-control[disabled], + .form-control[readonly], + fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; + } + .form-control[disabled], + fieldset[disabled] .form-control { + cursor: not-allowed; + } + textarea.form-control { + height: auto; + } + input[type="search"] { + -webkit-appearance: none; + } + @media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } + } + .form-group { + margin-bottom: 15px; + } + .radio, + .checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + } + .radio label, + .checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; + } + .radio input[type="radio"], + .radio-inline input[type="radio"], + .checkbox input[type="checkbox"], + .checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; + } + .radio + .radio, + .checkbox + .checkbox { + margin-top: -5px; + } + .radio-inline, + .checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; + } + .radio-inline + .radio-inline, + .checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; + } + input[type="radio"][disabled], + input[type="checkbox"][disabled], + input[type="radio"].disabled, + input[type="checkbox"].disabled, + fieldset[disabled] input[type="radio"], + fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; + } + .radio-inline.disabled, + .checkbox-inline.disabled, + fieldset[disabled] .radio-inline, + fieldset[disabled] .checkbox-inline { + cursor: not-allowed; + } + .radio.disabled label, + .checkbox.disabled label, + fieldset[disabled] .radio label, + fieldset[disabled] .checkbox label { + cursor: not-allowed; + } + .form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + } + .form-control-static.input-lg, + .form-control-static.input-sm { + padding-right: 0; + padding-left: 0; + } + .input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + select.input-sm { + height: 30px; + line-height: 30px; + } + textarea.input-sm, + select[multiple].input-sm { + height: auto; + } + .form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + .form-group-sm select.form-control { + height: 30px; + line-height: 30px; + } + .form-group-sm textarea.form-control, + .form-group-sm select[multiple].form-control { + height: auto; + } + .form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; + } + .input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; + } + select.input-lg { + height: 46px; + line-height: 46px; + } + textarea.input-lg, + select[multiple].input-lg { + height: auto; + } + .form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; + } + .form-group-lg select.form-control { + height: 46px; + line-height: 46px; + } + .form-group-lg textarea.form-control, + .form-group-lg select[multiple].form-control { + height: auto; + } + .form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; + } + .has-feedback { + position: relative; + } + .has-feedback .form-control { + padding-right: 42.5px; + } + .form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; + } + .input-lg + .form-control-feedback, + .input-group-lg + .form-control-feedback, + .form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; + } + .input-sm + .form-control-feedback, + .input-group-sm + .form-control-feedback, + .form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; + } + .has-success .help-block, + .has-success .control-label, + .has-success .radio, + .has-success .checkbox, + .has-success .radio-inline, + .has-success .checkbox-inline, + .has-success.radio label, + .has-success.checkbox label, + .has-success.radio-inline label, + .has-success.checkbox-inline label { + color: #3c763d; + } + .has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + .has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + } + .has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; + } + .has-success .form-control-feedback { + color: #3c763d; + } + .has-warning .help-block, + .has-warning .control-label, + .has-warning .radio, + .has-warning .checkbox, + .has-warning .radio-inline, + .has-warning .checkbox-inline, + .has-warning.radio label, + .has-warning.checkbox label, + .has-warning.radio-inline label, + .has-warning.checkbox-inline label { + color: #8a6d3b; + } + .has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + .has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + } + .has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; + } + .has-warning .form-control-feedback { + color: #8a6d3b; + } + .has-error .help-block, + .has-error .control-label, + .has-error .radio, + .has-error .checkbox, + .has-error .radio-inline, + .has-error .checkbox-inline, + .has-error.radio label, + .has-error.checkbox label, + .has-error.radio-inline label, + .has-error.checkbox-inline label { + color: #a94442; + } + .has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + .has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + } + .has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; + } + .has-error .form-control-feedback { + color: #a94442; + } + .has-feedback label ~ .form-control-feedback { + top: 25px; + } + .has-feedback label.sr-only ~ .form-control-feedback { + top: 0; + } + .help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; + } + @media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } + } + .form-horizontal .radio, + .form-horizontal .checkbox, + .form-horizontal .radio-inline, + .form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; + } + .form-horizontal .radio, + .form-horizontal .checkbox { + min-height: 27px; + } + .form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; + } + @media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } + } + .form-horizontal .has-feedback .form-control-feedback { + right: 15px; + } + @media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } + } + @media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } + } + .btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; + } + .btn:focus, + .btn:active:focus, + .btn.active:focus, + .btn.focus, + .btn:active.focus, + .btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } + .btn:hover, + .btn:focus, + .btn.focus { + color: #333; + text-decoration: none; + } + .btn:active, + .btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + } + .btn.disabled, + .btn[disabled], + fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; + } + a.btn.disabled, + fieldset[disabled] a.btn { + pointer-events: none; + } + .btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; + } + .btn-default:focus, + .btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; + } + .btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; + } + .btn-default:active, + .btn-default.active, + .open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; + } + .btn-default:active:hover, + .btn-default.active:hover, + .open > .dropdown-toggle.btn-default:hover, + .btn-default:active:focus, + .btn-default.active:focus, + .open > .dropdown-toggle.btn-default:focus, + .btn-default:active.focus, + .btn-default.active.focus, + .open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; + } + .btn-default:active, + .btn-default.active, + .open > .dropdown-toggle.btn-default { + background-image: none; + } + .btn-default.disabled:hover, + .btn-default[disabled]:hover, + fieldset[disabled] .btn-default:hover, + .btn-default.disabled:focus, + .btn-default[disabled]:focus, + fieldset[disabled] .btn-default:focus, + .btn-default.disabled.focus, + .btn-default[disabled].focus, + fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; + } + .btn-default .badge { + color: #fff; + background-color: #333; + } + .btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + } + .btn-primary:focus, + .btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; + } + .btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; + } + .btn-primary:active, + .btn-primary.active, + .open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; + } + .btn-primary:active:hover, + .btn-primary.active:hover, + .open > .dropdown-toggle.btn-primary:hover, + .btn-primary:active:focus, + .btn-primary.active:focus, + .open > .dropdown-toggle.btn-primary:focus, + .btn-primary:active.focus, + .btn-primary.active.focus, + .open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; + } + .btn-primary:active, + .btn-primary.active, + .open > .dropdown-toggle.btn-primary { + background-image: none; + } + .btn-primary.disabled:hover, + .btn-primary[disabled]:hover, + fieldset[disabled] .btn-primary:hover, + .btn-primary.disabled:focus, + .btn-primary[disabled]:focus, + fieldset[disabled] .btn-primary:focus, + .btn-primary.disabled.focus, + .btn-primary[disabled].focus, + fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; + } + .btn-primary .badge { + color: #337ab7; + background-color: #fff; + } + .btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; + } + .btn-success:focus, + .btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; + } + .btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; + } + .btn-success:active, + .btn-success.active, + .open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; + } + .btn-success:active:hover, + .btn-success.active:hover, + .open > .dropdown-toggle.btn-success:hover, + .btn-success:active:focus, + .btn-success.active:focus, + .open > .dropdown-toggle.btn-success:focus, + .btn-success:active.focus, + .btn-success.active.focus, + .open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; + } + .btn-success:active, + .btn-success.active, + .open > .dropdown-toggle.btn-success { + background-image: none; + } + .btn-success.disabled:hover, + .btn-success[disabled]:hover, + fieldset[disabled] .btn-success:hover, + .btn-success.disabled:focus, + .btn-success[disabled]:focus, + fieldset[disabled] .btn-success:focus, + .btn-success.disabled.focus, + .btn-success[disabled].focus, + fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; + } + .btn-success .badge { + color: #5cb85c; + background-color: #fff; + } + .btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; + } + .btn-info:focus, + .btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; + } + .btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; + } + .btn-info:active, + .btn-info.active, + .open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; + } + .btn-info:active:hover, + .btn-info.active:hover, + .open > .dropdown-toggle.btn-info:hover, + .btn-info:active:focus, + .btn-info.active:focus, + .open > .dropdown-toggle.btn-info:focus, + .btn-info:active.focus, + .btn-info.active.focus, + .open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; + } + .btn-info:active, + .btn-info.active, + .open > .dropdown-toggle.btn-info { + background-image: none; + } + .btn-info.disabled:hover, + .btn-info[disabled]:hover, + fieldset[disabled] .btn-info:hover, + .btn-info.disabled:focus, + .btn-info[disabled]:focus, + fieldset[disabled] .btn-info:focus, + .btn-info.disabled.focus, + .btn-info[disabled].focus, + fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; + } + .btn-info .badge { + color: #5bc0de; + background-color: #fff; + } + .btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; + } + .btn-warning:focus, + .btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; + } + .btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; + } + .btn-warning:active, + .btn-warning.active, + .open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; + } + .btn-warning:active:hover, + .btn-warning.active:hover, + .open > .dropdown-toggle.btn-warning:hover, + .btn-warning:active:focus, + .btn-warning.active:focus, + .open > .dropdown-toggle.btn-warning:focus, + .btn-warning:active.focus, + .btn-warning.active.focus, + .open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; + } + .btn-warning:active, + .btn-warning.active, + .open > .dropdown-toggle.btn-warning { + background-image: none; + } + .btn-warning.disabled:hover, + .btn-warning[disabled]:hover, + fieldset[disabled] .btn-warning:hover, + .btn-warning.disabled:focus, + .btn-warning[disabled]:focus, + fieldset[disabled] .btn-warning:focus, + .btn-warning.disabled.focus, + .btn-warning[disabled].focus, + fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; + } + .btn-warning .badge { + color: #f0ad4e; + background-color: #fff; + } + .btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; + } + .btn-danger:focus, + .btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; + } + .btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; + } + .btn-danger:active, + .btn-danger.active, + .open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; + } + .btn-danger:active:hover, + .btn-danger.active:hover, + .open > .dropdown-toggle.btn-danger:hover, + .btn-danger:active:focus, + .btn-danger.active:focus, + .open > .dropdown-toggle.btn-danger:focus, + .btn-danger:active.focus, + .btn-danger.active.focus, + .open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; + } + .btn-danger:active, + .btn-danger.active, + .open > .dropdown-toggle.btn-danger { + background-image: none; + } + .btn-danger.disabled:hover, + .btn-danger[disabled]:hover, + fieldset[disabled] .btn-danger:hover, + .btn-danger.disabled:focus, + .btn-danger[disabled]:focus, + fieldset[disabled] .btn-danger:focus, + .btn-danger.disabled.focus, + .btn-danger[disabled].focus, + fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; + } + .btn-danger .badge { + color: #d9534f; + background-color: #fff; + } + .btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; + } + .btn-link, + .btn-link:active, + .btn-link.active, + .btn-link[disabled], + fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + } + .btn-link, + .btn-link:hover, + .btn-link:focus, + .btn-link:active { + border-color: transparent; + } + .btn-link:hover, + .btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; + } + .btn-link[disabled]:hover, + fieldset[disabled] .btn-link:hover, + .btn-link[disabled]:focus, + fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; + } + .btn-lg, + .btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; + } + .btn-sm, + .btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + .btn-xs, + .btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + .btn-block { + display: block; + width: 100%; + } + .btn-block + .btn-block { + margin-top: 5px; + } + input[type="submit"].btn-block, + input[type="reset"].btn-block, + input[type="button"].btn-block { + width: 100%; + } + .fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; + } + .fade.in { + opacity: 1; + } + .collapse { + display: none; + } + .collapse.in { + display: block; + } + tr.collapse.in { + display: table-row; + } + tbody.collapse.in { + display: table-row-group; + } + .collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; + } + .caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + } + .dropup, + .dropdown { + position: relative; + } + .dropdown-toggle:focus { + outline: 0; + } + .dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + } + .dropdown-menu.pull-right { + right: 0; + left: auto; + } + .dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; + } + .dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; + } + .dropdown-menu > li > a:hover, + .dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; + } + .dropdown-menu > .active > a, + .dropdown-menu > .active > a:hover, + .dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; + } + .dropdown-menu > .disabled > a, + .dropdown-menu > .disabled > a:hover, + .dropdown-menu > .disabled > a:focus { + color: #777; + } + .dropdown-menu > .disabled > a:hover, + .dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + } + .open > .dropdown-menu { + display: block; + } + .open > a { + outline: 0; + } + .dropdown-menu-right { + right: 0; + left: auto; + } + .dropdown-menu-left { + right: auto; + left: 0; + } + .dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; + } + .dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; + } + .pull-right > .dropdown-menu { + right: 0; + left: auto; + } + .dropup .caret, + .navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; + } + .dropup .dropdown-menu, + .navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; + } + @media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } + } + .btn-group, + .btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; + } + .btn-group > .btn, + .btn-group-vertical > .btn { + position: relative; + float: left; + } + .btn-group > .btn:hover, + .btn-group-vertical > .btn:hover, + .btn-group > .btn:focus, + .btn-group-vertical > .btn:focus, + .btn-group > .btn:active, + .btn-group-vertical > .btn:active, + .btn-group > .btn.active, + .btn-group-vertical > .btn.active { + z-index: 2; + } + .btn-group .btn + .btn, + .btn-group .btn + .btn-group, + .btn-group .btn-group + .btn, + .btn-group .btn-group + .btn-group { + margin-left: -1px; + } + .btn-toolbar { + margin-left: -5px; + } + .btn-toolbar .btn, + .btn-toolbar .btn-group, + .btn-toolbar .input-group { + float: left; + } + .btn-toolbar > .btn, + .btn-toolbar > .btn-group, + .btn-toolbar > .input-group { + margin-left: 5px; + } + .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; + } + .btn-group > .btn:first-child { + margin-left: 0; + } + .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .btn-group > .btn:last-child:not(:first-child), + .btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .btn-group > .btn-group { + float: left; + } + .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; + } + .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, + .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .btn-group .dropdown-toggle:active, + .btn-group.open .dropdown-toggle { + outline: 0; + } + .btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; + } + .btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; + } + .btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + } + .btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; + } + .btn .caret { + margin-left: 0; + } + .btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; + } + .dropup .btn-lg .caret { + border-width: 0 5px 5px; + } + .btn-group-vertical > .btn, + .btn-group-vertical > .btn-group, + .btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + .btn-group-vertical > .btn-group > .btn { + float: none; + } + .btn-group-vertical > .btn + .btn, + .btn-group-vertical > .btn + .btn-group, + .btn-group-vertical > .btn-group + .btn, + .btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } + .btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; + } + .btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + .btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + } + .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; + } + .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, + .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; + } + .btn-group-justified > .btn, + .btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; + } + .btn-group-justified > .btn-group .btn { + width: 100%; + } + .btn-group-justified > .btn-group .dropdown-menu { + left: auto; + } + [data-toggle="buttons"] > .btn input[type="radio"], + [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], + [data-toggle="buttons"] > .btn input[type="checkbox"], + [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; + } + .input-group { + position: relative; + display: table; + border-collapse: separate; + } + .input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; + } + .input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; + } + .input-group .form-control:focus { + z-index: 3; + } + .input-group-lg > .form-control, + .input-group-lg > .input-group-addon, + .input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; + } + select.input-group-lg > .form-control, + select.input-group-lg > .input-group-addon, + select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; + } + textarea.input-group-lg > .form-control, + textarea.input-group-lg > .input-group-addon, + textarea.input-group-lg > .input-group-btn > .btn, + select[multiple].input-group-lg > .form-control, + select[multiple].input-group-lg > .input-group-addon, + select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; + } + .input-group-sm > .form-control, + .input-group-sm > .input-group-addon, + .input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + select.input-group-sm > .form-control, + select.input-group-sm > .input-group-addon, + select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; + } + textarea.input-group-sm > .form-control, + textarea.input-group-sm > .input-group-addon, + textarea.input-group-sm > .input-group-btn > .btn, + select[multiple].input-group-sm > .form-control, + select[multiple].input-group-sm > .input-group-addon, + select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; + } + .input-group-addon, + .input-group-btn, + .input-group .form-control { + display: table-cell; + } + .input-group-addon:not(:first-child):not(:last-child), + .input-group-btn:not(:first-child):not(:last-child), + .input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; + } + .input-group-addon, + .input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; + } + .input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; + } + .input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; + } + .input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; + } + .input-group-addon input[type="radio"], + .input-group-addon input[type="checkbox"] { + margin-top: 0; + } + .input-group .form-control:first-child, + .input-group-addon:first-child, + .input-group-btn:first-child > .btn, + .input-group-btn:first-child > .btn-group > .btn, + .input-group-btn:first-child > .dropdown-toggle, + .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), + .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .input-group-addon:first-child { + border-right: 0; + } + .input-group .form-control:last-child, + .input-group-addon:last-child, + .input-group-btn:last-child > .btn, + .input-group-btn:last-child > .btn-group > .btn, + .input-group-btn:last-child > .dropdown-toggle, + .input-group-btn:first-child > .btn:not(:first-child), + .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .input-group-addon:last-child { + border-left: 0; + } + .input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; + } + .input-group-btn > .btn { + position: relative; + } + .input-group-btn > .btn + .btn { + margin-left: -1px; + } + .input-group-btn > .btn:hover, + .input-group-btn > .btn:focus, + .input-group-btn > .btn:active { + z-index: 2; + } + .input-group-btn:first-child > .btn, + .input-group-btn:first-child > .btn-group { + margin-right: -1px; + } + .input-group-btn:last-child > .btn, + .input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; + } + .nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; + } + .nav > li { + position: relative; + display: block; + } + .nav > li > a { + position: relative; + display: block; + padding: 10px 15px; + } + .nav > li > a:hover, + .nav > li > a:focus { + text-decoration: none; + background-color: #eee; + } + .nav > li.disabled > a { + color: #777; + } + .nav > li.disabled > a:hover, + .nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + } + .nav .open > a, + .nav .open > a:hover, + .nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; + } + .nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; + } + .nav > li > a > img { + max-width: none; + } + .nav-tabs { + border-bottom: 1px solid #ddd; + } + .nav-tabs > li { + float: left; + margin-bottom: -1px; + } + .nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; + } + .nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; + } + .nav-tabs > li.active > a, + .nav-tabs > li.active > a:hover, + .nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + } + .nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; + } + .nav-tabs.nav-justified > li { + float: none; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; + } + .nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; + } + @media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } + } + .nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; + } + @media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } + } + .nav-pills > li { + float: left; + } + .nav-pills > li > a { + border-radius: 4px; + } + .nav-pills > li + li { + margin-left: 2px; + } + .nav-pills > li.active > a, + .nav-pills > li.active > a:hover, + .nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; + } + .nav-stacked > li { + float: none; + } + .nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; + } + .nav-justified { + width: 100%; + } + .nav-justified > li { + float: none; + } + .nav-justified > li > a { + margin-bottom: 5px; + text-align: center; + } + .nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; + } + @media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } + } + .nav-tabs-justified { + border-bottom: 0; + } + .nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; + } + @media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } + } + .tab-content > .tab-pane { + display: none; + } + .tab-content > .active { + display: block; + } + .nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; + } + @media (min-width: 768px) { + .navbar { + border-radius: 4px; + } + } + @media (min-width: 768px) { + .navbar-header { + float: left; + } + } + .navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + } + .navbar-collapse.in { + overflow-y: auto; + } + @media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } + } + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 340px; + } + @media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } + } + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; + } + @media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } + } + .navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; + } + @media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + } + @media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } + } + .navbar-fixed-top { + top: 0; + border-width: 0 0 1px; + } + .navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; + } + .navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + } + .navbar-brand:hover, + .navbar-brand:focus { + text-decoration: none; + } + .navbar-brand > img { + display: block; + } + @media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } + } + .navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; + } + .navbar-toggle:focus { + outline: 0; + } + .navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; + } + .navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; + } + @media (min-width: 768px) { + .navbar-toggle { + display: none; + } + } + .navbar-nav { + margin: 7.5px -15px; + } + .navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; + } + @media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } + } + @media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } + } + .navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + } + @media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } + } + @media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } + } + @media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + } + .navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + .navbar-btn { + margin-top: 8px; + margin-bottom: 8px; + } + .navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; + } + .navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; + } + .navbar-text { + margin-top: 15px; + margin-bottom: 15px; + } + @media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } + } + @media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } + } + .navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; + } + .navbar-default .navbar-brand { + color: #777; + } + .navbar-default .navbar-brand:hover, + .navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; + } + .navbar-default .navbar-text { + color: #777; + } + .navbar-default .navbar-nav > li > a { + color: #777; + } + .navbar-default .navbar-nav > li > a:hover, + .navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav > .active > a, + .navbar-default .navbar-nav > .active > a:hover, + .navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav > .disabled > a, + .navbar-default .navbar-nav > .disabled > a:hover, + .navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } + .navbar-default .navbar-toggle { + border-color: #ddd; + } + .navbar-default .navbar-toggle:hover, + .navbar-default .navbar-toggle:focus { + background-color: #ddd; + } + .navbar-default .navbar-toggle .icon-bar { + background-color: #888; + } + .navbar-default .navbar-collapse, + .navbar-default .navbar-form { + border-color: #e7e7e7; + } + .navbar-default .navbar-nav > .open > a, + .navbar-default .navbar-nav > .open > a:hover, + .navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; + } + @media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } + } + .navbar-default .navbar-link { + color: #777; + } + .navbar-default .navbar-link:hover { + color: #333; + } + .navbar-default .btn-link { + color: #777; + } + .navbar-default .btn-link:hover, + .navbar-default .btn-link:focus { + color: #333; + } + .navbar-default .btn-link[disabled]:hover, + fieldset[disabled] .navbar-default .btn-link:hover, + .navbar-default .btn-link[disabled]:focus, + fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; + } + .navbar-inverse { + background-color: #222; + border-color: #080808; + } + .navbar-inverse .navbar-brand { + color: #9d9d9d; + } + .navbar-inverse .navbar-brand:hover, + .navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-text { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav > li > a:hover, + .navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav > .active > a, + .navbar-inverse .navbar-nav > .active > a:hover, + .navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav > .disabled > a, + .navbar-inverse .navbar-nav > .disabled > a:hover, + .navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; + } + .navbar-inverse .navbar-toggle { + border-color: #333; + } + .navbar-inverse .navbar-toggle:hover, + .navbar-inverse .navbar-toggle:focus { + background-color: #333; + } + .navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; + } + .navbar-inverse .navbar-collapse, + .navbar-inverse .navbar-form { + border-color: #101010; + } + .navbar-inverse .navbar-nav > .open > a, + .navbar-inverse .navbar-nav > .open > a:hover, + .navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; + } + @media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } + } + .navbar-inverse .navbar-link { + color: #9d9d9d; + } + .navbar-inverse .navbar-link:hover { + color: #fff; + } + .navbar-inverse .btn-link { + color: #9d9d9d; + } + .navbar-inverse .btn-link:hover, + .navbar-inverse .btn-link:focus { + color: #fff; + } + .navbar-inverse .btn-link[disabled]:hover, + fieldset[disabled] .navbar-inverse .btn-link:hover, + .navbar-inverse .btn-link[disabled]:focus, + fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; + } + .breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; + } + .breadcrumb > li { + display: inline-block; + } + .breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; + } + .breadcrumb > .active { + color: #777; + } + .pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; + } + .pagination > li { + display: inline; + } + .pagination > li > a, + .pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; + } + .pagination > li:first-child > a, + .pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + .pagination > li:last-child > a, + .pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } + .pagination > li > a:hover, + .pagination > li > span:hover, + .pagination > li > a:focus, + .pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eee; + border-color: #ddd; + } + .pagination > .active > a, + .pagination > .active > span, + .pagination > .active > a:hover, + .pagination > .active > span:hover, + .pagination > .active > a:focus, + .pagination > .active > span:focus { + z-index: 3; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; + } + .pagination > .disabled > span, + .pagination > .disabled > span:hover, + .pagination > .disabled > span:focus, + .pagination > .disabled > a, + .pagination > .disabled > a:hover, + .pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; + } + .pagination-lg > li > a, + .pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + } + .pagination-lg > li:first-child > a, + .pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + } + .pagination-lg > li:last-child > a, + .pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + } + .pagination-sm > li > a, + .pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + } + .pagination-sm > li:first-child > a, + .pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + } + .pagination-sm > li:last-child > a, + .pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + } + .pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; + } + .pager li { + display: inline; + } + .pager li > a, + .pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; + } + .pager li > a:hover, + .pager li > a:focus { + text-decoration: none; + background-color: #eee; + } + .pager .next > a, + .pager .next > span { + float: right; + } + .pager .previous > a, + .pager .previous > span { + float: left; + } + .pager .disabled > a, + .pager .disabled > a:hover, + .pager .disabled > a:focus, + .pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; + } + .label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + } + a.label:hover, + a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; + } + .label:empty { + display: none; + } + .btn .label { + position: relative; + top: -1px; + } + .label-default { + background-color: #777; + } + .label-default[href]:hover, + .label-default[href]:focus { + background-color: #5e5e5e; + } + .label-primary { + background-color: #337ab7; + } + .label-primary[href]:hover, + .label-primary[href]:focus { + background-color: #286090; + } + .label-success { + background-color: #5cb85c; + } + .label-success[href]:hover, + .label-success[href]:focus { + background-color: #449d44; + } + .label-info { + background-color: #5bc0de; + } + .label-info[href]:hover, + .label-info[href]:focus { + background-color: #31b0d5; + } + .label-warning { + background-color: #f0ad4e; + } + .label-warning[href]:hover, + .label-warning[href]:focus { + background-color: #ec971f; + } + .label-danger { + background-color: #d9534f; + } + .label-danger[href]:hover, + .label-danger[href]:focus { + background-color: #c9302c; + } + .badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; + } + .badge:empty { + display: none; + } + .btn .badge { + position: relative; + top: -1px; + } + .btn-xs .badge, + .btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; + } + a.badge:hover, + a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; + } + .list-group-item.active > .badge, + .nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; + } + .list-group-item > .badge { + float: right; + } + .list-group-item > .badge + .badge { + margin-right: 5px; + } + .nav-pills > li > a > .badge { + margin-left: 3px; + } + .jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; + } + .jumbotron h1, + .jumbotron .h1 { + color: inherit; + } + .jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; + } + .jumbotron > hr { + border-top-color: #d5d5d5; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 15px; + padding-left: 15px; + border-radius: 6px; + } + .jumbotron .container { + max-width: 100%; + } + @media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } + } + .thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; + } + .thumbnail > img, + .thumbnail a > img { + margin-right: auto; + margin-left: auto; + } + a.thumbnail:hover, + a.thumbnail:focus, + a.thumbnail.active { + border-color: #337ab7; + } + .thumbnail .caption { + padding: 9px; + color: #333; + } + .alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; + } + .alert h4 { + margin-top: 0; + color: inherit; + } + .alert .alert-link { + font-weight: bold; + } + .alert > p, + .alert > ul { + margin-bottom: 0; + } + .alert > p + p { + margin-top: 5px; + } + .alert-dismissable, + .alert-dismissible { + padding-right: 35px; + } + .alert-dismissable .close, + .alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } + .alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; + } + .alert-success hr { + border-top-color: #c9e2b3; + } + .alert-success .alert-link { + color: #2b542c; + } + .alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; + } + .alert-info hr { + border-top-color: #a6e1ec; + } + .alert-info .alert-link { + color: #245269; + } + .alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; + } + .alert-warning hr { + border-top-color: #f7e1b5; + } + .alert-warning .alert-link { + color: #66512c; + } + .alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; + } + .alert-danger hr { + border-top-color: #e4b9c0; + } + .alert-danger .alert-link { + color: #843534; + } + @-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } + } + @-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } + } + @keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } + } + .progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + } + .progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; + } + .progress-striped .progress-bar, + .progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; + } + .progress.active .progress-bar, + .progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; + } + .progress-bar-success { + background-color: #5cb85c; + } + .progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + } + .progress-bar-info { + background-color: #5bc0de; + } + .progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + } + .progress-bar-warning { + background-color: #f0ad4e; + } + .progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + } + .progress-bar-danger { + background-color: #d9534f; + } + .progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + } + .media { + margin-top: 15px; + } + .media:first-child { + margin-top: 0; + } + .media, + .media-body { + overflow: hidden; + zoom: 1; + } + .media-body { + width: 10000px; + } + .media-object { + display: block; + } + .media-object.img-thumbnail { + max-width: none; + } + .media-right, + .media > .pull-right { + padding-left: 10px; + } + .media-left, + .media > .pull-left { + padding-right: 10px; + } + .media-left, + .media-right, + .media-body { + display: table-cell; + vertical-align: top; + } + .media-middle { + vertical-align: middle; + } + .media-bottom { + vertical-align: bottom; + } + .media-heading { + margin-top: 0; + margin-bottom: 5px; + } + .media-list { + padding-left: 0; + list-style: none; + } + .list-group { + padding-left: 0; + margin-bottom: 20px; + } + .list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; + } + .list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } + .list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + } + a.list-group-item, + button.list-group-item { + color: #555; + } + a.list-group-item .list-group-item-heading, + button.list-group-item .list-group-item-heading { + color: #333; + } + a.list-group-item:hover, + button.list-group-item:hover, + a.list-group-item:focus, + button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; + } + button.list-group-item { + width: 100%; + text-align: left; + } + .list-group-item.disabled, + .list-group-item.disabled:hover, + .list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; + } + .list-group-item.disabled .list-group-item-heading, + .list-group-item.disabled:hover .list-group-item-heading, + .list-group-item.disabled:focus .list-group-item-heading { + color: inherit; + } + .list-group-item.disabled .list-group-item-text, + .list-group-item.disabled:hover .list-group-item-text, + .list-group-item.disabled:focus .list-group-item-text { + color: #777; + } + .list-group-item.active, + .list-group-item.active:hover, + .list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; + } + .list-group-item.active .list-group-item-heading, + .list-group-item.active:hover .list-group-item-heading, + .list-group-item.active:focus .list-group-item-heading, + .list-group-item.active .list-group-item-heading > small, + .list-group-item.active:hover .list-group-item-heading > small, + .list-group-item.active:focus .list-group-item-heading > small, + .list-group-item.active .list-group-item-heading > .small, + .list-group-item.active:hover .list-group-item-heading > .small, + .list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; + } + .list-group-item.active .list-group-item-text, + .list-group-item.active:hover .list-group-item-text, + .list-group-item.active:focus .list-group-item-text { + color: #c7ddef; + } + .list-group-item-success { + color: #3c763d; + background-color: #dff0d8; + } + a.list-group-item-success, + button.list-group-item-success { + color: #3c763d; + } + a.list-group-item-success .list-group-item-heading, + button.list-group-item-success .list-group-item-heading { + color: inherit; + } + a.list-group-item-success:hover, + button.list-group-item-success:hover, + a.list-group-item-success:focus, + button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; + } + a.list-group-item-success.active, + button.list-group-item-success.active, + a.list-group-item-success.active:hover, + button.list-group-item-success.active:hover, + a.list-group-item-success.active:focus, + button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; + } + .list-group-item-info { + color: #31708f; + background-color: #d9edf7; + } + a.list-group-item-info, + button.list-group-item-info { + color: #31708f; + } + a.list-group-item-info .list-group-item-heading, + button.list-group-item-info .list-group-item-heading { + color: inherit; + } + a.list-group-item-info:hover, + button.list-group-item-info:hover, + a.list-group-item-info:focus, + button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; + } + a.list-group-item-info.active, + button.list-group-item-info.active, + a.list-group-item-info.active:hover, + button.list-group-item-info.active:hover, + a.list-group-item-info.active:focus, + button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; + } + .list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; + } + a.list-group-item-warning, + button.list-group-item-warning { + color: #8a6d3b; + } + a.list-group-item-warning .list-group-item-heading, + button.list-group-item-warning .list-group-item-heading { + color: inherit; + } + a.list-group-item-warning:hover, + button.list-group-item-warning:hover, + a.list-group-item-warning:focus, + button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; + } + a.list-group-item-warning.active, + button.list-group-item-warning.active, + a.list-group-item-warning.active:hover, + button.list-group-item-warning.active:hover, + a.list-group-item-warning.active:focus, + button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; + } + .list-group-item-danger { + color: #a94442; + background-color: #f2dede; + } + a.list-group-item-danger, + button.list-group-item-danger { + color: #a94442; + } + a.list-group-item-danger .list-group-item-heading, + button.list-group-item-danger .list-group-item-heading { + color: inherit; + } + a.list-group-item-danger:hover, + button.list-group-item-danger:hover, + a.list-group-item-danger:focus, + button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; + } + a.list-group-item-danger.active, + button.list-group-item-danger.active, + a.list-group-item-danger.active:hover, + button.list-group-item-danger.active:hover, + a.list-group-item-danger.active:focus, + button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; + } + .list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; + } + .list-group-item-text { + margin-bottom: 0; + line-height: 1.3; + } + .panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + } + .panel-body { + padding: 15px; + } + .panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + .panel-heading > .dropdown .dropdown-toggle { + color: inherit; + } + .panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; + } + .panel-title > a, + .panel-title > small, + .panel-title > .small, + .panel-title > small > a, + .panel-title > .small > a { + color: inherit; + } + .panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + } + .panel > .list-group, + .panel > .panel-collapse > .list-group { + margin-bottom: 0; + } + .panel > .list-group .list-group-item, + .panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; + } + .panel > .list-group:first-child .list-group-item:first-child, + .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + .panel > .list-group:last-child .list-group-item:last-child, + .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + } + .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; + } + .list-group + .panel-footer { + border-top-width: 0; + } + .panel > .table, + .panel > .table-responsive > .table, + .panel > .panel-collapse > .table { + margin-bottom: 0; + } + .panel > .table caption, + .panel > .table-responsive > .table caption, + .panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; + } + .panel > .table:first-child, + .panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + .panel > .table:first-child > thead:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; + } + .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; + } + .panel > .table:last-child, + .panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + } + .panel > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + } + .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; + } + .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; + } + .panel > .panel-body + .table, + .panel > .panel-body + .table-responsive, + .panel > .table + .panel-body, + .panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; + } + .panel > .table > tbody:first-child > tr:first-child th, + .panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; + } + .panel > .table-bordered, + .panel > .table-responsive > .table-bordered { + border: 0; + } + .panel > .table-bordered > thead > tr > th:first-child, + .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, + .panel > .table-bordered > tbody > tr > th:first-child, + .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, + .panel > .table-bordered > tfoot > tr > th:first-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .panel > .table-bordered > thead > tr > td:first-child, + .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, + .panel > .table-bordered > tbody > tr > td:first-child, + .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, + .panel > .table-bordered > tfoot > tr > td:first-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .panel > .table-bordered > thead > tr > th:last-child, + .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, + .panel > .table-bordered > tbody > tr > th:last-child, + .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, + .panel > .table-bordered > tfoot > tr > th:last-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .panel > .table-bordered > thead > tr > td:last-child, + .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, + .panel > .table-bordered > tbody > tr > td:last-child, + .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, + .panel > .table-bordered > tfoot > tr > td:last-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .panel > .table-bordered > thead > tr:first-child > td, + .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, + .panel > .table-bordered > tbody > tr:first-child > td, + .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, + .panel > .table-bordered > thead > tr:first-child > th, + .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, + .panel > .table-bordered > tbody > tr:first-child > th, + .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; + } + .panel > .table-bordered > tbody > tr:last-child > td, + .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, + .panel > .table-bordered > tfoot > tr:last-child > td, + .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, + .panel > .table-bordered > tbody > tr:last-child > th, + .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, + .panel > .table-bordered > tfoot > tr:last-child > th, + .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; + } + .panel > .table-responsive { + margin-bottom: 0; + border: 0; + } + .panel-group { + margin-bottom: 20px; + } + .panel-group .panel { + margin-bottom: 0; + border-radius: 4px; + } + .panel-group .panel + .panel { + margin-top: 5px; + } + .panel-group .panel-heading { + border-bottom: 0; + } + .panel-group .panel-heading + .panel-collapse > .panel-body, + .panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; + } + .panel-group .panel-footer { + border-top: 0; + } + .panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; + } + .panel-default { + border-color: #ddd; + } + .panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; + } + .panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; + } + .panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; + } + .panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; + } + .panel-primary { + border-color: #337ab7; + } + .panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; + } + .panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; + } + .panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; + } + .panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; + } + .panel-success { + border-color: #d6e9c6; + } + .panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; + } + .panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; + } + .panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; + } + .panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; + } + .panel-info { + border-color: #bce8f1; + } + .panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; + } + .panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; + } + .panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; + } + .panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; + } + .panel-warning { + border-color: #faebcc; + } + .panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; + } + .panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; + } + .panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; + } + .panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; + } + .panel-danger { + border-color: #ebccd1; + } + .panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; + } + .panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; + } + .panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; + } + .panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; + } + .embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; + } + .embed-responsive .embed-responsive-item, + .embed-responsive iframe, + .embed-responsive embed, + .embed-responsive object, + .embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; + } + .embed-responsive-16by9 { + padding-bottom: 56.25%; + } + .embed-responsive-4by3 { + padding-bottom: 75%; + } + .well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + } + .well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); + } + .well-lg { + padding: 24px; + border-radius: 6px; + } + .well-sm { + padding: 9px; + border-radius: 3px; + } + .close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; + } + .close:hover, + .close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; + } + button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + } + .modal-open { + overflow: hidden; + } + .modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; + } + .modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); + } + .modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); + } + .modal-open .modal { + overflow-x: hidden; + overflow-y: auto; + } + .modal-dialog { + position: relative; + width: auto; + margin: 10px; + } + .modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + } + .modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; + } + .modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; + } + .modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; + } + .modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + } + .modal-header .close { + margin-top: -2px; + } + .modal-title { + margin: 0; + line-height: 1.42857143; + } + .modal-body { + position: relative; + padding: 15px; + } + .modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; + } + .modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; + } + .modal-footer .btn-group .btn + .btn { + margin-left: -1px; + } + .modal-footer .btn-block + .btn-block { + margin-left: 0; + } + .modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; + } + @media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } + } + @media (min-width: 992px) { + .modal-lg { + width: 900px; + } + } + .tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; + } + .tooltip.in { + filter: alpha(opacity=90); + opacity: .9; + } + .tooltip.top { + padding: 5px 0; + margin-top: -3px; + } + .tooltip.right { + padding: 0 5px; + margin-left: 3px; + } + .tooltip.bottom { + padding: 5px 0; + margin-top: 3px; + } + .tooltip.left { + padding: 0 5px; + margin-left: -3px; + } + .tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; + } + .tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } + .tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; + } + .tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; + } + .tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; + } + .tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; + } + .tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; + } + .tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; + } + .tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; + } + .tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; + } + .popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; + } + .popover.top { + margin-top: -10px; + } + .popover.right { + margin-left: 10px; + } + .popover.bottom { + margin-top: 10px; + } + .popover.left { + margin-left: -10px; + } + .popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; + } + .popover-content { + padding: 9px 14px; + } + .popover > .arrow, + .popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } + .popover > .arrow { + border-width: 11px; + } + .popover > .arrow:after { + content: ""; + border-width: 10px; + } + .popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; + } + .popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; + } + .popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; + } + .popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; + } + .popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); + } + .popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; + } + .popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); + } + .popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; + } + .carousel { + position: relative; + } + .carousel-inner { + position: relative; + width: 100%; + overflow: hidden; + } + .carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; + } + .carousel-inner > .item > img, + .carousel-inner > .item > a > img { + line-height: 1; + } + @media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + } + .carousel-inner > .active, + .carousel-inner > .next, + .carousel-inner > .prev { + display: block; + } + .carousel-inner > .active { + left: 0; + } + .carousel-inner > .next, + .carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; + } + .carousel-inner > .next { + left: 100%; + } + .carousel-inner > .prev { + left: -100%; + } + .carousel-inner > .next.left, + .carousel-inner > .prev.right { + left: 0; + } + .carousel-inner > .active.left { + left: -100%; + } + .carousel-inner > .active.right { + left: 100%; + } + .carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; + } + .carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; + } + .carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; + } + .carousel-control:hover, + .carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; + } + .carousel-control .icon-prev, + .carousel-control .icon-next, + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; + } + .carousel-control .icon-prev, + .carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; + } + .carousel-control .icon-next, + .carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; + } + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; + } + .carousel-control .icon-prev:before { + content: '\2039'; + } + .carousel-control .icon-next:before { + content: '\203a'; + } + .carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; + } + .carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; + } + .carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; + } + .carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + } + .carousel-caption .btn { + text-shadow: none; + } + @media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } + } + .clearfix:before, + .clearfix:after, + .dl-horizontal dd:before, + .dl-horizontal dd:after, + .container:before, + .container:after, + .container-fluid:before, + .container-fluid:after, + .row:before, + .row:after, + .form-horizontal .form-group:before, + .form-horizontal .form-group:after, + .btn-toolbar:before, + .btn-toolbar:after, + .btn-group-vertical > .btn-group:before, + .btn-group-vertical > .btn-group:after, + .nav:before, + .nav:after, + .navbar:before, + .navbar:after, + .navbar-header:before, + .navbar-header:after, + .navbar-collapse:before, + .navbar-collapse:after, + .pager:before, + .pager:after, + .panel-body:before, + .panel-body:after, + .modal-header:before, + .modal-header:after, + .modal-footer:before, + .modal-footer:after { + display: table; + content: " "; + } + .clearfix:after, + .dl-horizontal dd:after, + .container:after, + .container-fluid:after, + .row:after, + .form-horizontal .form-group:after, + .btn-toolbar:after, + .btn-group-vertical > .btn-group:after, + .nav:after, + .navbar:after, + .navbar-header:after, + .navbar-collapse:after, + .pager:after, + .panel-body:after, + .modal-header:after, + .modal-footer:after { + clear: both; + } + .center-block { + display: block; + margin-right: auto; + margin-left: auto; + } + .pull-right { + float: right !important; + } + .pull-left { + float: left !important; + } + .hide { + display: none !important; + } + .show { + display: block !important; + } + .invisible { + visibility: hidden; + } + .text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; + } + .hidden { + display: none !important; + } + .affix { + position: fixed; + } + @-ms-viewport { + width: device-width; + } + .visible-xs, + .visible-sm, + .visible-md, + .visible-lg { + display: none !important; + } + .visible-xs-block, + .visible-xs-inline, + .visible-xs-inline-block, + .visible-sm-block, + .visible-sm-inline, + .visible-sm-inline-block, + .visible-md-block, + .visible-md-inline, + .visible-md-inline-block, + .visible-lg-block, + .visible-lg-inline, + .visible-lg-inline-block { + display: none !important; + } + @media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } + } + @media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } + } + @media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } + } + @media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } + } + @media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } + } + @media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } + } + @media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } + } + @media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } + } + @media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } + } + @media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } + } + @media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } + } + @media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } + } + @media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } + } + @media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } + } + @media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } + } + @media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } + } + @media (max-width: 767px) { + .hidden-xs { + display: none !important; + } + } + @media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } + } + @media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } + } + @media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } + } + .visible-print { + display: none !important; + } + @media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } + } + .visible-print-block { + display: none !important; + } + @media print { + .visible-print-block { + display: block !important; + } + } + .visible-print-inline { + display: none !important; + } + @media print { + .visible-print-inline { + display: inline !important; + } + } + .visible-print-inline-block { + display: none !important; + } + @media print { + .visible-print-inline-block { + display: inline-block !important; + } + } + @media print { + .hidden-print { + display: none !important; + } + } + /*# sourceMappingURL=bootstrap.css.map */ diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/favicon.ico b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfe873eb228f98720fe0ed18c638daa13906958f GIT binary patch literal 17174 zcmeHOJ#Q015PgP|sUltJ%A8D-(o!TUkc{NQ1+uPjPZg!4M<`cP($XUeDk>yUiu?k8 z10_|E2qK~~GdH`@9=;55lyHgjMj7wN?OyiY%vw?RV_+}{(X$}` zkiRp}d#2#VM9RE@(KQaI zUnaWs7TXteX8N); ON)^VQz<8Ga>-ryC<7BY_ literal 0 HcmV?d00001 diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/bootstrap-3.3.7.js b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/bootstrap-3.3.7.js new file mode 100644 index 000000000000..ab612bdbb5a6 --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/bootstrap-3.3.7.js @@ -0,0 +1,2377 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') + } + + +function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } + }(jQuery); + + /* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + /* jshint latedef: false */ + + +function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + + }(jQuery); + + /* ======================================================================== + * Bootstrap: popover.js v3.3.7 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.7' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + + }(jQuery); + + /* ======================================================================== + * Bootstrap: scrollspy.js v3.3.7 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.7' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: tab.js v3.3.7 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.7' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + + }(jQuery); + + /* ======================================================================== + * Bootstrap: affix.js v3.3.7 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + + +function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.7' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + + }(jQuery); diff --git a/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery-2.2.0.js b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery-2.2.0.js new file mode 100644 index 000000000000..e50863f10b6b --- /dev/null +++ b/aspnetcore/fundamentals/localization/sample/8.x/Localization/wwwroot/js/jquery-2.2.0.js @@ -0,0 +1,9831 @@ +/*! + * jQuery JavaScript Library v2.2.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-08T20:02Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + + // Pass this if window is not defined yet + }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + + // Support: Firefox 18+ + // Can't be in strict mode, several libs including ASP.NET trace + // the stack via arguments.caller.callee and Firefox dies if + // you try to trace through "use strict" call chains. (#13335) + //"use strict"; + var arr = []; + + var document = window.document; + + var slice = arr.slice; + + var concat = arr.concat; + + var push = arr.push; + + var indexOf = arr.indexOf; + + var class2type = {}; + + var toString = class2type.toString; + + var hasOwn = class2type.hasOwnProperty; + + var support = {}; + + + + var + version = "2.2.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + + jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice + }; + + jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; + }; + + jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + }, + + isPlainObject: function( obj ) { + + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf( "use strict" ) === 1 ) { + script = document.createElement( "script" ); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support + } ); + + // JSHint would error on this code due to the Symbol not being defined in ES5. + // Defining this global in .jshintrc would create a danger of using the global + // unguarded in another place, it seems safer to just disable JSHint for these + // three lines. + /* jshint ignore: start */ + if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; + } + /* jshint ignore: end */ + + // Populate the class2type map + jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + + function isArrayLike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; + } + var Sizzle = + /*! + * Sizzle CSS Selector Engine v2.2.1 + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-10-17 + */ + (function( window ) { + + var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + + // Optimize for push.apply( _, NodeList ) + try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; + } catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; + } + + function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); + } + + /** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ + function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; + } + + /** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ + function markFunction( fn ) { + fn[ expando ] = true; + return fn; + } + + /** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ + function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } + } + + /** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ + function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } + } + + /** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ + function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; + } + + /** + * Returns a function to use in pseudos for input types + * @param {String} type + */ + function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; + } + + /** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ + function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; + } + + /** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ + function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); + } + + /** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ + function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; + } + + // Expose support vars for convenience + support = Sizzle.support = {}; + + /** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ + isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; + }; + + /** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ + setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + return m ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; + }; + + Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); + }; + + Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; + }; + + Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); + }; + + Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; + }; + + Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); + }; + + /** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ + Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; + }; + + /** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ + getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; + }; + + Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } + }; + + Expr.pseudos["nth"] = Expr.pseudos["eq"]; + + // Add button/input type pseudos + for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); + } + for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); + } + + // Easy API for creating new setFilters + function setFilters() {} + setFilters.prototype = Expr.filters = Expr.pseudos; + Expr.setFilters = new setFilters(); + + tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); + }; + + function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; + } + + function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; + } + + function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; + } + + function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; + } + + function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; + } + + function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); + } + + function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); + } + + function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; + } + + compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; + }; + + /** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ + select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; + }; + + // One-time assignments + + // Sort stability + support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + + // Support: Chrome 14-35+ + // Always assume duplicates if they aren't passed to the comparison function + support.detectDuplicates = !!hasDuplicate; + + // Initialize against the default document + setDocument(); + + // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) + // Detached nodes confoundingly follow *each other* + support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; + }); + + // Support: IE<8 + // Prevent attribute/property "interpolation" + // http://msdn.microsoft.com/library/ms536429%28VS.85%29.aspx + if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; + }) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); + } + + // Support: IE<9 + // Use defaultValue in place of getAttribute("value") + if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; + }) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); + } + + // Support: IE<9 + // Use getAttributeNode to fetch booleans when getAttribute lies + if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; + }) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); + } + + return Sizzle; + + })( window ); + + + + jQuery.find = Sizzle; + jQuery.expr = Sizzle.selectors; + jQuery.expr[ ":" ] = jQuery.expr.pseudos; + jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; + jQuery.text = Sizzle.getText; + jQuery.isXMLDoc = Sizzle.isXML; + jQuery.contains = Sizzle.contains; + + + + var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }; + + + var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + }; + + + var rneedsContext = jQuery.expr.match.needsContext; + + var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); + + + + var risSimple = /^.[^:#\[\.,]*$/; + + // Implement the identical functionality for filter and not + function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + } ); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); + }; + + jQuery.fn.extend( { + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } + } ); + + + // Initialize a jQuery object + + + // A central reference to the root jQuery(document) + var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + + // Inject the element directly into the jQuery object + this.length = 1; + this[ 0 ] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + + // Give the init function the jQuery prototype for later instantiation + init.prototype = jQuery.fn; + + // Initialize central reference + rootjQuery = jQuery( document ); + + + var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + + jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } + } ); + + function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; + } + + jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } + }, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; + } ); + var rnotwhite = ( /\S+/g ); + + + + // Convert String-formatted options into Object-formatted ones + function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; + } + + /* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ + jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; + }; + + + jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( function() { + + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // Add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ); + } else { + --remaining; + } + } + } + + // If we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } + } ); + + + // The deferred used on DOM ready + var readyList; + + jQuery.fn.ready = function( fn ) { + + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }; + + jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } + } ); + + /** + * The ready event handler and self cleanup method + */ + function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); + } + + jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE9-10 only + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); + } + } + return readyList.promise( obj ); + }; + + // Kick off the DOM ready check even if the user does not + jQuery.ready.promise(); + + + + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[ 0 ], key ) : emptyGet; + }; + var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); + }; + + + + + function Data() { + this.expando = jQuery.expando + Data.uid++; + } + + Data.uid = 1; + + Data.prototype = { + + register: function( owner, initial ) { + var value = initial || {}; + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable, non-writable property + // configurability must be true to allow the property to be + // deleted with the delete operator + } else { + Object.defineProperty( owner, this.expando, { + value: value, + writable: true, + configurable: true + } ); + } + return owner[ this.expando ]; + }, + cache: function( owner ) { + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( !acceptData( owner ) ) { + return {}; + } + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + owner[ this.expando ] && owner[ this.expando ][ key ]; + }, + access: function( owner, key, value ) { + var stored; + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase( key ) ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key === undefined ) { + this.register( owner ); + + } else { + + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <= 35-45+ + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } + }; + var dataPriv = new Data(); + + var dataUser = new Data(); + + + + // Implementation Summary + // + // 1. Enforce API surface and semantic compatibility with 1.9.x branch + // 2. Improve the module's maintainability by reducing the storage + // paths to a single mechanism. + // 3. Use the same single mechanism to support "private" and "user" data. + // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + // 5. Avoid exposing implementation details on user objects (eg. expando properties) + // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + + var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + + function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; + } + + jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } + } ); + + jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data, camelKey; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // with the key as-is + data = dataUser.get( elem, key ) || + + // Try to find dashed key if it exists (gh-2779) + // This is for 2.2.x only + dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); + + if ( data !== undefined ) { + return data; + } + + camelKey = jQuery.camelCase( key ); + + // Attempt to get data from the cache + // with the key camelized + data = dataUser.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + camelKey = jQuery.camelCase( key ); + this.each( function() { + + // First, attempt to store a copy or reference of any + // data that might have been store with a camelCased key. + var data = dataUser.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + dataUser.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf( "-" ) > -1 && data !== undefined ) { + dataUser.set( this, key, value ); + } + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } + } ); + + + jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } + } ); + + jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } + } ); + var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + + var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + + var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + + var isHidden = function( elem, el ) { + + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); + }; + + + + function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; + } + var rcheckableType = ( /^(?:checkbox|radio)$/i ); + + var rtagName = ( /<([\w:-]+)/ ); + + var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + + // We have to close these tags to support XHTML (#13200) + var wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] + }; + + // Support: IE9 + wrapMap.optgroup = wrapMap.option; + + wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; + wrapMap.th = wrapMap.td; + + + function getAll( context, tag ) { + + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; + } + + + // Mark scripts as having already been evaluated + function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } + } + + + var rhtml = /<|&#?\w+;/; + + function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + } + + + ( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0-4.3, Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + } )(); + + + var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + + function returnTrue() { + return true; + } + + function returnFalse() { + return false; + } + + // Support: IE9 + // See #13393 for more info + function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } + } + + function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); + } + + /* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ + jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support (at least): Chrome, IE9 + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push( { elem: cur, handlers: matches } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split( " " ), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + + "screenX screenY toElement" ).split( " " ), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } + }; + + jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } + }; + + jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android<4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; + }; + + // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding + // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html + jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } + }; + + // Create mouseenter/leave events using mouseover/out and event-time checks + // so that event delegation works in jQuery. + // Do the same for pointerenter/pointerleave and pointerover/pointerout + // + // Support: Safari 7 only + // Safari sends mouseenter too often; see: + // https://code.google.com/p/chromium/issues/detail?id=470258 + // for the description of the bug (it existed in older Chrome versions as well). + jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" + }, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; + } ); + + jQuery.fn.extend( { + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } + } ); + + + var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + + function manipulationTarget( elem, content ) { + if ( jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; + } + + return elem; + } + + // Replace/restore the type attribute of script elements for safe DOM manipulation + function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; + } + function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + + return elem; + } + + function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } + } + + // Fix IE bugs, see support tests + function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } + } + + function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return collection; + } + + function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; + } + + jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } + } ); + + jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } + } ); + + jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; + } ); + + + var iframe, + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; + + /** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ + + // Called only from within defaultDisplay + function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + display = jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; + } + + /** + * Try to determine the default display value of an element + * @param {String} nodeName + */ + function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = ( iframe || jQuery( "