[
  {
    "path": ".dockerignore",
    "content": "**/.classpath\n**/.dockerignore\n**/.env\n**/.git\n**/.gitignore\n**/.project\n**/.settings\n**/.toolstarget\n**/.vs\n**/.vscode\n**/*.*proj.user\n**/*.dbmdl\n**/*.jfm\n**/azds.yaml\n**/bin\n**/charts\n**/docker-compose*\n**/Dockerfile*\n**/node_modules\n**/npm-debug.log\n**/obj\n**/secrets.dev.yaml\n**/values.dev.yaml\nLICENSE\nREADME.md"
  },
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n#*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n*Logs/\n"
  },
  {
    "path": "Blog.IdentityServer/Authorization/ClaimRequirement.cs",
    "content": "﻿using Microsoft.AspNetCore.Authorization;\n\nnamespace Blog.IdentityServer.Authorization\n{\n    public class ClaimRequirement : IAuthorizationRequirement\n    {\n        public ClaimRequirement(string claimName, string claimValue)\n        {\n            ClaimName = claimName;\n            ClaimValue = claimValue;\n        }\n\n        public string ClaimName { get; set; }\n        public string ClaimValue { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Authorization/ClaimsRequirementHandler.cs",
    "content": "﻿using System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authorization;\n\nnamespace Blog.IdentityServer.Authorization\n{\n    public class ClaimsRequirementHandler : AuthorizationHandler<ClaimRequirement>\n    {\n\n        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,\n                                                       ClaimRequirement requirement)\n        {\n\n            var claim = context.User.Claims.FirstOrDefault(c => c.Type == requirement.ClaimName);\n            if (claim != null && claim.Value.Contains(requirement.ClaimValue))\n            {\n                context.Succeed(requirement);\n            }\n\n            return Task.CompletedTask;\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Blog.IdentityServer.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp3.1</TargetFramework>\n    <UserSecretsId>aspnet-IdentityServerWithAspNetIdentity-04C6939F-E672-4E56-B4A5-5F064EB67F23</UserSecretsId>\n    <AssemblyName>Blog.IdentityServer</AssemblyName>\n    <RootNamespace>Blog.IdentityServer</RootNamespace>\n    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"Data\\Migrations\\**\" />\n    <Compile Remove=\"Migrations\\**\" />\n    <Compile Remove=\"Views\\Oauth2\\**\" />\n    <Content Remove=\"Data\\Migrations\\**\" />\n    <Content Remove=\"Migrations\\**\" />\n    <Content Remove=\"Views\\Oauth2\\**\" />\n    <EmbeddedResource Remove=\"Data\\Migrations\\**\" />\n    <EmbeddedResource Remove=\"Migrations\\**\" />\n    <EmbeddedResource Remove=\"Views\\Oauth2\\**\" />\n    <None Remove=\"Data\\Migrations\\**\" />\n    <None Remove=\"Migrations\\**\" />\n    <None Remove=\"Views\\Oauth2\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"Controllers\\Account\\Oauth2Controller.cs\" />\n    <Compile Remove=\"Data\\20191126135600_UpdateRoleTa.cs\" />\n    <Compile Remove=\"Data\\20191126135600_UpdateRoleTa.Designer.cs\" />\n  </ItemGroup>\n\n\n  <ItemGroup>\n    <PackageReference Include=\"AspNetCoreRateLimit\" Version=\"3.2.2\" />\n    <PackageReference Include=\"IdentityServer4\" Version=\"4.0.2\" />\n    <PackageReference Include=\"IdentityServer4.AspNetIdentity\" Version=\"4.0.2\" />\n    <PackageReference Include=\"IdentityServer4.EntityFramework\" Version=\"4.0.2\" />\n    <PackageReference Include=\"Microsoft.VisualStudio.Azure.Containers.Tools.Targets\" Version=\"1.10.8\" />\n\n\n    <PackageReference Include=\"Pomelo.EntityFrameworkCore.MySql\" Version=\"3.1.1\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"3.1.5\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Identity.EntityFrameworkCore\" Version=\"3.1.5\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\" Version=\"3.1.5\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"3.1.5\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.Extensions.Logging.Debug\" Version=\"3.1.5\" />\n    <PackageReference Include=\"Newtonsoft.Json\" Version=\"12.0.3\" />\n    \n    \n    <PackageReference Include=\"Serilog.AspNetCore\" Version=\"3.2.0\" />\n    <PackageReference Include=\"Serilog.Sinks.Console\" Version=\"3.1.2-dev-00824\" />\n    <PackageReference Include=\"Serilog.Sinks.File\" Version=\"4.1.0\" />\n    <PackageReference Include=\"System.Security.Principal.Windows\" Version=\"4.7.0\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <DotNetCliToolReference Include=\"Microsoft.Extensions.SecretManager.Tools\" Version=\"2.0.0\" />\n    <DotNetCliToolReference Include=\"Microsoft.VisualStudio.Web.CodeGeneration.Tools\" Version=\"2.0.0\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"wwwroot\\Certificates\\IS4.pfx\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"Dockerfile\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema=\"\" /></VisualStudio></ProjectExtensions>\n\n</Project>\n"
  },
  {
    "path": "Blog.IdentityServer/Config.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nusing Blog.IdentityServer.Extensions;\nusing IdentityModel;\nusing IdentityServer4;\nusing IdentityServer4.Models;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Blog.IdentityServer\n{\n    public class Config\n    {\n        // scopes define the resources in your system\n        public static IEnumerable<IdentityResource> GetIdentityResources()\n        {\n            return new List<IdentityResource>\n            {\n                new IdentityResources.OpenId(),\n                new IdentityResources.Profile(),\n                new IdentityResources.Email(),\n                new IdentityResource(\"roles\", \"角色\", new List<string> { JwtClaimTypes.Role }),\n                new IdentityResource(\"rolename\", \"角色名\", new List<string> { \"rolename\" }),\n            };\n        }\n\n        // v4更新\n        public static IEnumerable<ApiScope> GetApiScopes()\n        {\n            return new ApiScope[] {\n                 new ApiScope(\"blog.core.api\"),\n                 new ApiScope(\"blog.core.api.BlogModule\"),\n            };\n        }\n\n        public static IEnumerable<ApiResource> GetApiResources()\n        {\n            // blog.core 项目\n            return new List<ApiResource> {\n                new ApiResource(\"blog.core.api\", \"Blog.Core API\") {\n                    // include the following using claims in access token (in addition to subject id)\n                    //requires using using IdentityModel;\n                    UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Role,\"rolename\" },\n                    \n                    // v4更新\n                    Scopes={ \"blog.core.api\",\"blog.core.api.BlogModule\"},\n\n                    ApiSecrets = new List<Secret>()\n                    {\n                        new Secret(\"api_secret\".Sha256())\n                    },\n                }\n            };\n        }\n\n        // clients want to access resources (aka scopes)\n        public static IEnumerable<Client> GetClients()\n        {\n            // client\n            return new List<Client> {\n                // 1、blog.vue 前端vue项目\n                new Client {\n                    ClientId = \"blogvuejs\",\n                    ClientName = \"Blog.Vue JavaScript Client\",\n                    AllowedGrantTypes = GrantTypes.Implicit,\n                    AllowAccessTokensViaBrowser = true,\n\n                    RedirectUris =           {\n                        \"http://vueblog.neters.club/callback\",\n                        \"http://apk.neters.club/oauth2-redirect.html\",\n\n                        \"http://localhost:6688/callback\",\n                        \"http://localhost:8081/oauth2-redirect.html\",\n                    },\n                    PostLogoutRedirectUris = { \"http://vueblog.neters.club\",\"http://localhost:6688\" },\n                    AllowedCorsOrigins =     { \"http://vueblog.neters.club\",\"http://localhost:6688\" },\n\n                    AccessTokenLifetime=3600,\n\n                    AllowedScopes = {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"roles\",\n                        \"blog.core.api.BlogModule\"\n                    }\n                },\n                // 2、blog.admin 前端vue项目\n                new Client {\n                    ClientId = \"blogadminjs\",\n                    ClientName = \"Blog.Admin JavaScript Client\",\n                    AllowedGrantTypes = GrantTypes.Implicit,\n                    AllowAccessTokensViaBrowser = true,\n\n                    RedirectUris =\n                    {\n                        \"http://vueadmin.neters.club/callback\",\n                        \"http://apk.neters.club/oauth2-redirect.html\",\n\n                        \"http://localhost:2364/callback\",\n                        \"http://localhost:8081/oauth2-redirect.html\",\n                    },\n                    PostLogoutRedirectUris = { \"http://vueadmin.neters.club\",\"http://localhost:2364\" },\n                    AllowedCorsOrigins =     { \"http://vueadmin.neters.club\",\"http://localhost:2364\"  },\n\n                    AccessTokenLifetime=3600,\n\n                    AllowedScopes = {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"roles\",\n                        \"blog.core.api\"\n                    }\n                },\n                // 3、nuxt.tbug 前端nuxt项目\n                new Client {\n                    ClientId = \"tibugnuxtjs\",\n                    ClientName = \"Nuxt.tBug JavaScript Client\",\n                    AllowedGrantTypes = GrantTypes.Implicit,\n                    AllowAccessTokensViaBrowser = true,\n\n                    RedirectUris =           { \"http://tibug.neters.club/callback\" },\n                    PostLogoutRedirectUris = { \"http://tibug.neters.club\" },\n                    AllowedCorsOrigins =     { \"http://tibug.neters.club\" },\n\n                    AccessTokenLifetime=3600,\n\n                    AllowedScopes = {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"roles\",\n                        \"blog.core.api\"\n                    }\n                },\n                // 4、DDD 后端MVC项目\n                new Client\n                {\n                    ClientId = \"chrisdddmvc\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    RequireConsent = false,\n                    RequirePkce = true,\n                    AlwaysIncludeUserClaimsInIdToken=true,//将用户所有的claims包含在IdToken内\n                \n                    // where to redirect to after login\n                    RedirectUris = { \"http://ddd.neters.club/signin-oidc\" },\n\n                    // where to redirect to after logout\n                    PostLogoutRedirectUris = { \"http://ddd.neters.club/signout-callback-oidc\" },\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                    }\n                },\n                // 5、控制台客户端\n                new Client\n                {\n                    ClientId = \"Console\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                     AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true\n                    AllowedGrantTypes = new List<string>()\n                    {\n                        GrantTypes.ResourceOwnerPassword.FirstOrDefault(),\n                        GrantTypes.ClientCredentials.FirstOrDefault(),\n                        GrantTypeCustom.ResourceWeixinOpen,\n                    },\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"offline_access\",\n                        \"blog.core.api\"\n                    }\n                },\n                // 6、mvp 后端blazor.server项目\n                new Client\n                {\n                    ClientId = \"blazorserver\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    RequireConsent = false,\n                    RequirePkce = true,\n                    AlwaysIncludeUserClaimsInIdToken=true,//将用户所有的claims包含在IdToken内\n                    AllowAccessTokensViaBrowser = true,\n                \n                    // where to redirect to after login\n                    RedirectUris = { \"https://mvp.neters.club/signin-oidc\" },\n\n                    AllowedCorsOrigins =     { \"https://mvp.neters.club\" },\n                   \n                    // where to redirect to after logout\n                    PostLogoutRedirectUris = { \"https://mvp.neters.club/signout-callback-oidc\" },\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                        \"blog.core.api\"\n                    }\n                },\n\n                // 7、测试 hybrid 模式\n                new Client\n                {\n                    ClientId = \"hybridclent\",\n                    ClientName=\"Demo MVC Client\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Hybrid,\n                 \n                    RequirePkce = false,\n\n                    RedirectUris = { \"http://localhost:1003/signin-oidc\" },\n                    PostLogoutRedirectUris = { \"http://localhost:1003/signout-callback-oidc\" },\n\n                    AllowOfflineAccess=true,\n                    AlwaysIncludeUserClaimsInIdToken=true,\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                        \"blog.core.api\"\n                    }\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/AccountController.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityServer4.Services;\nusing IdentityServer4.Stores;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing IdentityServer4.Events;\nusing IdentityServer4.Models;\nusing Microsoft.AspNetCore.Identity;\nusing IdentityServer4.Extensions;\nusing System.Security.Principal;\nusing System.Security.Claims;\nusing IdentityModel;\nusing System.Linq;\nusing System;\nusing System.Collections.Generic;\nusing Blog.IdentityServer.Models;\nusing Microsoft.AspNetCore.Authorization;\nusing Blog.Core.Common.Helper;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    [SecurityHeaders]\n    public class AccountController : Controller\n    {\n        private readonly UserManager<ApplicationUser> _userManager;\n        private readonly RoleManager<ApplicationRole> _roleManager;\n        private readonly SignInManager<ApplicationUser> _signInManager;\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clientStore;\n        private readonly IAuthenticationSchemeProvider _schemeProvider;\n        private readonly IEventService _events;\n\n        public AccountController(\n            UserManager<ApplicationUser> userManager,\n            RoleManager<ApplicationRole> roleManager,\n            SignInManager<ApplicationUser> signInManager,\n            IIdentityServerInteractionService interaction,\n            IClientStore clientStore,\n            IAuthenticationSchemeProvider schemeProvider,\n            IEventService events)\n        {\n            _userManager = userManager;\n            _roleManager = roleManager;\n            _signInManager = signInManager;\n            _interaction = interaction;\n            _clientStore = clientStore;\n            _schemeProvider = schemeProvider;\n            _events = events;\n        }\n\n        /// <summary>\n        /// Show login page\n        /// </summary>\n        [HttpGet]\n        [Route(\"oauth2/authorize\")]\n        public async Task<IActionResult> Login(string returnUrl)\n        {\n            // build a model so we know what to show on the login page\n            var vm = await BuildLoginViewModelAsync(returnUrl);\n\n            if (vm.IsExternalLoginOnly)\n            {\n                // we only have one option for logging in and it's an external provider\n                return await ExternalLogin(vm.ExternalLoginScheme, returnUrl);\n            }\n\n            return View(vm);\n        }\n\n        /// <summary>\n        /// Handle postback from username/password login\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        [Route(\"oauth2/authorize\")]\n        public async Task<IActionResult> Login(LoginInputModel model, string button)\n        {\n            // check if we are in the context of an authorization request\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n            if (button != \"login\")\n            {\n                if (context != null)\n                {\n                    // if the user cancels, send a result back into IdentityServer as if they \n                    // denied the consent (even if this client does not require consent).\n                    // this will send back an access denied OIDC error response to the client.\n                    await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return this.LoadingPage(\"Redirect\", model.ReturnUrl);\n                    }\n\n                    return Redirect(model.ReturnUrl);\n                }\n                else\n                {\n                    // since we don't have a valid context, then we just go back to the home page\n                    return Redirect(\"~/\");\n                }\n            }\n\n            if (ModelState.IsValid)\n            {\n                var user = _userManager.Users.FirstOrDefault(d => (d.LoginName == model.Username || d.Email == model.Username) && !d.tdIsDelete);\n\n                if (user != null && !user.tdIsDelete)\n                {\n                    var result = await _signInManager.PasswordSignInAsync(user.LoginName, model.Password, model.RememberLogin, lockoutOnFailure: true);\n                    if (result.Succeeded)\n                    {\n                        await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName));\n\n                        // make sure the returnUrl is still valid, and if so redirect back to authorize endpoint or a local page\n                        // the IsLocalUrl check is only necessary if you want to support additional local pages, otherwise IsValidReturnUrl is more strict\n                        if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))\n                        {\n                            return Redirect(model.ReturnUrl);\n                        }\n\n                        return Redirect(\"~/\");\n                    }\n                    else\n                    {\n                        var result2 = await _signInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberLogin, lockoutOnFailure: true);\n\n                        if (result2.Succeeded)\n                        {\n                            await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName));\n\n                            // make sure the returnUrl is still valid, and if so redirect back to authorize endpoint or a local page\n                            // the IsLocalUrl check is only necessary if you want to support additional local pages, otherwise IsValidReturnUrl is more strict\n                            if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))\n                            {\n                                return Redirect(model.ReturnUrl);\n                            }\n\n                            return Redirect(\"~/\");\n                        }\n                    }\n                }\n\n                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\"));\n\n                ModelState.AddModelError(\"\", AccountOptions.InvalidCredentialsErrorMessage);\n            }\n\n            // something went wrong, show form with error\n            var vm = await BuildLoginViewModelAsync(model);\n            return View(vm);\n        }\n\n        /// <summary>\n        /// initiate roundtrip to external authentication provider\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> ExternalLogin(string provider, string returnUrl)\n        {\n            if (AccountOptions.WindowsAuthenticationSchemeName == provider)\n            {\n                // windows authentication needs special handling\n                return await ProcessWindowsLoginAsync(returnUrl);\n            }\n            else\n            {\n                // start challenge and roundtrip the return URL and \n                var props = new AuthenticationProperties()\n                {\n                    RedirectUri = Url.Action(\"ExternalLoginCallback\"),\n                    Items =\n                    {\n                        { \"returnUrl\", returnUrl },\n                        { \"scheme\", provider },\n                    }\n                };\n                return Challenge(props, provider);\n            }\n        }\n\n        /// <summary>\n        /// Post processing of external authentication\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> ExternalLoginCallback()\n        {\n            // read external identity from the temporary cookie\n            var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);\n            if (result?.Succeeded != true)\n            {\n                throw new Exception(\"External authentication error\");\n            }\n\n            // lookup our user and external provider info\n            var (user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result);\n            if (user == null)\n            {\n                // this might be where you might initiate a custom workflow for user registration\n                // in this sample we don't show how that would be done, as our sample implementation\n                // simply auto-provisions new external user\n                user = await AutoProvisionUserAsync(provider, providerUserId, claims);\n            }\n\n            // this allows us to collect any additonal claims or properties\n            // for the specific prtotocols used and store them in the local auth cookie.\n            // this is typically used to store data needed for signout from those protocols.\n            var additionalLocalClaims = new List<Claim>();\n            var localSignInProps = new AuthenticationProperties();\n            ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);\n            ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps);\n            ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps);\n\n            // issue authentication cookie for user\n            // we must issue the cookie maually, and can't use the SignInManager because\n            // it doesn't expose an API to issue additional claims from the login workflow\n            var principal = await _signInManager.CreateUserPrincipalAsync(user);\n            additionalLocalClaims.AddRange(principal.Claims);\n            var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id.ToString();\n            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id.ToString(), name));\n\n            //await HttpContext.SignInAsync(user.Id.ToString(), name, provider, localSignInProps, additionalLocalClaims.ToArray());\n\n            var isuser = new IdentityServerUser(user.Id.ToString())\n            {\n                DisplayName = name,\n                IdentityProvider = provider,\n                AdditionalClaims = additionalLocalClaims\n            };\n\n            await HttpContext.SignInAsync(isuser, localSignInProps);\n\n\n            // delete temporary cookie used during external authentication\n            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);\n\n            // validate return URL and redirect back to authorization endpoint or a local page\n            var returnUrl = result.Properties.Items[\"returnUrl\"];\n            if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl))\n            {\n                return Redirect(returnUrl);\n            }\n\n            return Redirect(\"~/\");\n        }\n\n        /// <summary>\n        /// Show logout page\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Logout(string logoutId)\n        {\n            // build a model so the logout page knows what to display\n            var vm = await BuildLogoutViewModelAsync(logoutId);\n\n            if (vm.ShowLogoutPrompt == false)\n            {\n                // if the request for logout was properly authenticated from IdentityServer, then\n                // we don't need to show the prompt and can just log the user out directly.\n                return await Logout(vm);\n            }\n\n            return View(vm);\n        }\n\n        /// <summary>\n        /// Handle logout page postback\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Logout(LogoutInputModel model)\n        {\n            // build a model so the logged out page knows what to display\n            var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n            if (User?.Identity.IsAuthenticated == true)\n            {\n                // delete local authentication cookie\n                await _signInManager.SignOutAsync();\n\n                // raise the logout event\n                await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n            }\n\n            // check if we need to trigger sign-out at an upstream identity provider\n            if (vm.TriggerExternalSignout)\n            {\n                // build a return URL so the upstream provider will redirect back\n                // to us after the user has logged out. this allows us to then\n                // complete our single sign-out processing.\n                string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n                // this triggers a redirect to the external provider for sign-out\n                return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n            }\n\n            return View(\"LoggedOut\", vm);\n        }\n\n        /*****************************************/\n        /* helper APIs for the AccountController */\n        /*****************************************/\n        private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            if (context?.IdP != null)\n            {\n                // this is meant to short circuit the UI and only trigger the one external IdP\n                return new LoginViewModel\n                {\n                    EnableLocalLogin = false,\n                    ReturnUrl = returnUrl,\n                    Username = context?.LoginHint,\n                    ExternalProviders = new ExternalProvider[] { new ExternalProvider { AuthenticationScheme = context.IdP } }\n                };\n            }\n\n            var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n            var providers = schemes\n                .Where(x => x.DisplayName != null ||\n                            (x.Name.Equals(AccountOptions.WindowsAuthenticationSchemeName, StringComparison.OrdinalIgnoreCase))\n                )\n                .Select(x => new ExternalProvider\n                {\n                    DisplayName = x.DisplayName,\n                    AuthenticationScheme = x.Name\n                }).ToList();\n\n            var allowLocal = true;\n            if (context?.Client.ClientId != null)\n            {\n                var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n                if (client != null)\n                {\n                    allowLocal = client.EnableLocalLogin;\n\n                    if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                    {\n                        providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                    }\n                }\n            }\n\n            return new LoginViewModel\n            {\n                AllowRememberLogin = AccountOptions.AllowRememberLogin,\n                EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n                ExternalProviders = providers.ToArray()\n            };\n        }\n\n        private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n        {\n            var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n            vm.Username = model.Username;\n            vm.RememberLogin = model.RememberLogin;\n            return vm;\n        }\n\n        private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n        {\n            var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n            if (User?.Identity.IsAuthenticated != true)\n            {\n                // if the user is not authenticated, then just show logged out page\n                vm.ShowLogoutPrompt = false;\n                return vm;\n            }\n\n            var context = await _interaction.GetLogoutContextAsync(logoutId);\n            if (context?.ShowSignoutPrompt == false)\n            {\n                // it's safe to automatically sign-out\n                vm.ShowLogoutPrompt = false;\n                return vm;\n            }\n\n            // show the logout prompt. this prevents attacks where the user\n            // is automatically signed out by another malicious web page.\n            return vm;\n        }\n\n        private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n        {\n            // get context information (client name, post logout redirect URI and iframe for federated signout)\n            var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n            var vm = new LoggedOutViewModel\n            {\n                AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n                PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n                ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n                SignOutIframeUrl = logout?.SignOutIFrameUrl,\n                LogoutId = logoutId\n            };\n\n            if (User?.Identity.IsAuthenticated == true)\n            {\n                var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n                if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider)\n                {\n                    var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                    if (providerSupportsSignout)\n                    {\n                        if (vm.LogoutId == null)\n                        {\n                            // if there's no current logout context, we need to create one\n                            // this captures necessary info from the current logged in user\n                            // before we signout and redirect away to the external IdP for signout\n                            vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                        }\n\n                        vm.ExternalAuthenticationScheme = idp;\n                    }\n                }\n            }\n\n            return vm;\n        }\n\n        private async Task<IActionResult> ProcessWindowsLoginAsync(string returnUrl)\n        {\n            // see if windows auth has already been requested and succeeded\n            var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);\n            if (result?.Principal is WindowsPrincipal wp)\n            {\n                // we will issue the external cookie and then redirect the\n                // user back to the external callback, in essence, tresting windows\n                // auth the same as any other external authentication mechanism\n                var props = new AuthenticationProperties()\n                {\n                    RedirectUri = Url.Action(\"ExternalLoginCallback\"),\n                    Items =\n                    {\n                        { \"returnUrl\", returnUrl },\n                        { \"scheme\", AccountOptions.WindowsAuthenticationSchemeName },\n                    }\n                };\n\n                var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);\n                id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));\n                id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));\n\n                // add the groups as claims -- be careful if the number of groups is too large\n                if (AccountOptions.IncludeWindowsGroups)\n                {\n                    var wi = wp.Identity as WindowsIdentity;\n                    var groups = wi.Groups.Translate(typeof(NTAccount));\n                    var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value));\n                    id.AddClaims(roles);\n                }\n\n                await HttpContext.SignInAsync(\n                    IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,\n                    new ClaimsPrincipal(id),\n                    props);\n                return Redirect(props.RedirectUri);\n            }\n            else\n            {\n                // trigger windows auth\n                // since windows auth don't support the redirect uri,\n                // this URL is re-triggered when we call challenge\n                return Challenge(AccountOptions.WindowsAuthenticationSchemeName);\n            }\n        }\n\n        private async Task<(ApplicationUser user, string provider, string providerUserId, IEnumerable<Claim> claims)>\n            FindUserFromExternalProviderAsync(AuthenticateResult result)\n        {\n            var externalUser = result.Principal;\n\n            // try to determine the unique id of the external user (issued by the provider)\n            // the most common claim type for that are the sub claim and the NameIdentifier\n            // depending on the external provider, some other claim type might be used\n            var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                              externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                              throw new Exception(\"Unknown userid\");\n\n            // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n            var claims = externalUser.Claims.ToList();\n            claims.Remove(userIdClaim);\n\n            var provider = result.Properties.Items[\"scheme\"];\n            var providerUserId = userIdClaim.Value;\n\n            // find external user\n            var user = await _userManager.FindByLoginAsync(provider, providerUserId);\n\n            return (user, provider, providerUserId, claims);\n        }\n\n        private async Task<ApplicationUser> AutoProvisionUserAsync(string provider, string providerUserId, IEnumerable<Claim> claims)\n        {\n            // create a list of claims that we want to transfer into our store\n            var filtered = new List<Claim>();\n\n            // user's display name\n            var name = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Name)?.Value ??\n                claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;\n            if (name != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, name));\n            }\n            else\n            {\n                var first = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.GivenName)?.Value ??\n                    claims.FirstOrDefault(x => x.Type == ClaimTypes.GivenName)?.Value;\n                var last = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.FamilyName)?.Value ??\n                    claims.FirstOrDefault(x => x.Type == ClaimTypes.Surname)?.Value;\n                if (first != null && last != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, first + \" \" + last));\n                }\n                else if (first != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, first));\n                }\n                else if (last != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, last));\n                }\n            }\n\n            // email\n            var email = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Email)?.Value ??\n               claims.FirstOrDefault(x => x.Type == ClaimTypes.Email)?.Value;\n            if (email != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Email, email));\n            }\n\n            var user = new ApplicationUser\n            {\n                UserName = Guid.NewGuid().ToString(),\n            };\n            var identityResult = await _userManager.CreateAsync(user);\n            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n            if (filtered.Any())\n            {\n                identityResult = await _userManager.AddClaimsAsync(user, filtered);\n                if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n            }\n\n            identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, providerUserId, provider));\n            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n            return user;\n        }\n\n        private void ProcessLoginCallbackForOidc(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n        {\n            // if the external system sent a session id claim, copy it over\n            // so we can use it for single sign-out\n            var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n            if (sid != null)\n            {\n                localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n            }\n\n            // if the external provider issued an id_token, we'll keep it for signout\n            var id_token = externalResult.Properties.GetTokenValue(\"id_token\");\n            if (id_token != null)\n            {\n                localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = id_token } });\n            }\n        }\n\n        private void ProcessLoginCallbackForWsFed(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n        {\n        }\n\n        private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n        {\n        }\n\n\n\n\n        [HttpGet]\n        [Route(\"account/register\")]\n        public IActionResult Register(string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            return View();\n        }\n\n        [HttpPost]\n        [Route(\"account/register\")]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null, string rName = \"AdminTest\")\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var userItem = _userManager.FindByNameAsync(model.LoginName).Result;\n\n                if (userItem == null)\n                {\n\n                    var user = new ApplicationUser\n                    {\n                        Email = model.Email,\n                        UserName = model.LoginName,\n                        LoginName = model.RealName,\n                        sex = model.Sex,\n                        age = model.Birth.Year - DateTime.Now.Year,\n                        birth = model.Birth,\n                        FirstQuestion = model.FirstQuestion,\n                        SecondQuestion = model.SecondQuestion,\n                        addr = \"\",\n                        tdIsDelete = false\n                    };\n\n\n                    result = await _userManager.CreateAsync(user, model.Password);\n\n                    if (result.Succeeded)\n                    {\n                        //var claims = new List<Claim>{\n                        //            new Claim(JwtClaimTypes.Name, model.RealName),\n                        //            new Claim(JwtClaimTypes.Email, model.Email),\n                        //            new Claim(JwtClaimTypes.EmailVerified, \"false\", ClaimValueTypes.Boolean),\n                        //            new Claim(\"rolename\", rName),\n                        //        };\n\n                        //claims.AddRange((new List<int> { 6 }).Select(s => new Claim(JwtClaimTypes.Role, s.ToString())));\n\n\n                        //result = _userManager.AddClaimsAsync(userItem, claims).Result;\n\n\n                        result = await _userManager.AddClaimsAsync(user, new Claim[]{\n                            new Claim(JwtClaimTypes.Name, model.RealName),\n                            new Claim(JwtClaimTypes.Email, model.Email),\n                            new Claim(JwtClaimTypes.EmailVerified, \"false\", ClaimValueTypes.Boolean),\n                            new Claim(JwtClaimTypes.Role, \"6\"),\n                            new Claim(\"rolename\", rName),\n                        });\n\n                        if (result.Succeeded)\n                        {\n                            // 可以直接登录\n                            //await _signInManager.SignInAsync(user, isPersistent: false);\n\n                            return RedirectToLocal(returnUrl);\n                        }\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{userItem?.UserName} already exists\");\n\n                }\n\n                AddErrors(result);\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n\n        [HttpGet]\n        [Route(\"account/users\")]\n        [Authorize]\n        public IActionResult Users(string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            var users = _userManager.Users.Where(d => !d.tdIsDelete).OrderByDescending(d => d.Id).Take(50).ToList();\n\n            return View(users);\n        }\n\n\n\n        [HttpGet(\"{id}\")]\n        [Route(\"account/edit/{id}\")]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<IActionResult> Edit(string id, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            if (id == null)\n            {\n                return NotFound();\n            }\n\n            var user = await _userManager.FindByIdAsync(id);\n\n            if (user == null)\n            {\n                return NotFound();\n            }\n\n            return View(new EditViewModel(user.Id.ToString(), user.LoginName, user.UserName, user.Email, await _userManager.GetClaimsAsync(user), user.FirstQuestion, user.SecondQuestion));\n        }\n\n\n        [HttpPost]\n        [Route(\"account/edit/{id}\")]\n        [ValidateAntiForgeryToken]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<IActionResult> Edit(EditViewModel model, string id, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var userItem = _userManager.FindByIdAsync(model.Id).Result;\n\n                if (userItem != null)\n                {\n                    var oldName = userItem.LoginName;\n                    var oldEmail = userItem.Email;\n\n                    userItem.UserName = model.LoginName;\n                    userItem.LoginName = model.UserName;\n                    userItem.Email = model.Email;\n                    userItem.RealName = model.UserName;\n\n\n                    result = await _userManager.UpdateAsync(userItem);\n\n                    if (result.Succeeded)\n                    {\n                        var removeClaimsIdRst = await _userManager.RemoveClaimsAsync(userItem,\n                            new Claim[]{\n                                new Claim(JwtClaimTypes.Name, oldName),\n                                new Claim(JwtClaimTypes.Email, oldEmail),\n                        });\n\n                        if (removeClaimsIdRst.Succeeded)\n                        {\n                            var addClaimsIdRst = await _userManager.AddClaimsAsync(userItem,\n                                new Claim[]{\n                                    new Claim(JwtClaimTypes.Name, userItem.LoginName),\n                                    new Claim(JwtClaimTypes.Email, userItem.Email),\n                            });\n\n                            if (addClaimsIdRst.Succeeded)\n                            {\n                                return RedirectToLocal(returnUrl);\n                            }\n                            else\n                            {\n                                AddErrors(addClaimsIdRst);\n\n                            }\n                        }\n                        else\n                        {\n                            AddErrors(removeClaimsIdRst);\n\n                        }\n\n\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{userItem?.UserName} no exist!\");\n                }\n\n                AddErrors(result);\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n\n\n        [HttpGet]\n        [Route(\"account/my\")]\n        [Authorize]\n        public async Task<IActionResult> My(string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n\n            var id = (int.Parse)(HttpContext.User.Claims.FirstOrDefault(c => c.Type == \"sub\")?.Value);\n            if (id <= 0)\n            {\n                return NotFound();\n            }\n\n            var user = await _userManager.FindByIdAsync(id.ToString());\n\n            if (user == null)\n            {\n                return NotFound();\n            }\n\n            return View(new EditViewModel(user.Id.ToString(), user.LoginName, user.UserName, user.Email, await _userManager.GetClaimsAsync(user), user.FirstQuestion, user.SecondQuestion));\n        }\n\n        [HttpPost]\n        [Route(\"account/my\")]\n        [ValidateAntiForgeryToken]\n        [Authorize]\n        public async Task<IActionResult> My(EditViewModel model, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var id = (int.Parse)(HttpContext.User.Claims.FirstOrDefault(c => c.Type == \"sub\")?.Value);\n                if (id <= 0)\n                {\n                    return NotFound();\n                }\n\n                // id为当前登录人\n                if (model.Id == id.ToString())\n                {\n                    var userItem = _userManager.FindByIdAsync(model.Id).Result;\n                    if (userItem != null)\n                    {\n\n\n                        var oldName = userItem.LoginName;\n                        var oldEmail = userItem.Email;\n\n                        userItem.UserName = model.LoginName;\n                        userItem.LoginName = model.UserName;\n                        userItem.Email = model.Email;\n                        userItem.RealName = model.UserName;\n                        userItem.FirstQuestion = model.FirstQuestion;\n                        userItem.SecondQuestion = model.SecondQuestion;\n\n\n                        result = await _userManager.UpdateAsync(userItem);\n\n                        if (result.Succeeded)\n                        {\n                            var removeClaimsIdRst = await _userManager.RemoveClaimsAsync(userItem,\n                                new Claim[]{\n                                new Claim(JwtClaimTypes.Name, oldName),\n                                new Claim(JwtClaimTypes.Email, oldEmail),\n                            });\n\n                            if (removeClaimsIdRst.Succeeded)\n                            {\n                                var addClaimsIdRst = await _userManager.AddClaimsAsync(userItem,\n                                    new Claim[]{\n                                    new Claim(JwtClaimTypes.Name, userItem.LoginName),\n                                    new Claim(JwtClaimTypes.Email, userItem.Email),\n                                });\n\n                                if (addClaimsIdRst.Succeeded)\n                                {\n                                    return RedirectToLocal(returnUrl);\n                                }\n                                else\n                                {\n                                    AddErrors(addClaimsIdRst);\n\n                                }\n                            }\n                            else\n                            {\n                                AddErrors(removeClaimsIdRst);\n\n                            }\n\n\n                        }\n\n\n                    }\n                    else\n                    {\n                        ModelState.AddModelError(string.Empty, $\"{userItem?.UserName} no exist!\");\n                    }\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"您无权修改该数据!\");\n                }\n                AddErrors(result);\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n\n        [HttpPost]\n        [Route(\"account/delete/{id}\")]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<JsonResult> Delete(string id)\n        {\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var userItem = _userManager.FindByIdAsync(id).Result;\n\n                if (userItem != null)\n                {\n                    userItem.tdIsDelete = true;\n\n\n                    result = await _userManager.UpdateAsync(userItem);\n\n                    if (result.Succeeded)\n                    {\n                        return Json(result);\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{userItem?.UserName} no exist!\");\n                }\n\n                AddErrors(result);\n            }\n\n            return Json(result.Errors);\n\n        }\n\n        [HttpGet]\n        [Route(\"account/confirm-email\")]\n        [AllowAnonymous]\n        public async Task<IActionResult> ConfirmEmail(string userId, string code)\n        {\n            if (userId == null || code == null)\n            {\n                return RedirectToAction(nameof(HomeController.Index), \"Home\");\n            }\n            var user = await _userManager.FindByIdAsync(userId);\n            if (user == null)\n            {\n                throw new ApplicationException($\"Unable to load user with ID '{userId}'.\");\n            }\n            var result = await _userManager.ConfirmEmailAsync(user, code);\n            return View(result.Succeeded ? \"ConfirmEmail\" : \"Error\");\n        }\n\n        [HttpGet]\n        [Route(\"account/forgot-password\")]\n        [AllowAnonymous]\n        public IActionResult ForgotPassword()\n        {\n            return View();\n        }\n\n        [HttpPost]\n        [Route(\"account/forgot-password\")]\n        [AllowAnonymous]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)\n        {\n            if (ModelState.IsValid)\n            {\n                var email = HttpContext.User.Claims.FirstOrDefault(c => c.Type == \"email\")?.Value;\n                var roleName = HttpContext.User.Claims.FirstOrDefault(c => c.Type == \"rolename\")?.Value;\n                if (email == model.Email || (roleName == \"SuperAdmin\"))\n                {\n\n                    var user = await _userManager.FindByEmailAsync(model.Email);\n                    //if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))\n                    if (user == null)\n                    {\n                        // Don't reveal that the user does not exist or is not confirmed\n                        return RedirectToAction(nameof(ForgotPasswordConfirmation), new { ResetPassword = \"邮箱不存在！\" });\n                    }\n\n                    // For more information on how to enable account confirmation and password reset please\n                    // visit https://go.microsoft.com/fwlink/?LinkID=532713\n                    var code = await _userManager.GeneratePasswordResetTokenAsync(user);\n\n                    var accessCode = MD5Helper.MD5Encrypt32(user.Id + code);\n                    var callbackUrl = Url.ResetPasswordCallbackLink(user.Id.ToString(), code, Request.Scheme, accessCode);\n\n                    var ResetPassword = $\"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>\";\n\n                    return RedirectToAction(nameof(ForgotPasswordConfirmation), new { ResetPassword = ResetPassword });\n                }\n                else if (!string.IsNullOrEmpty(model.FirstQuestion) && !string.IsNullOrEmpty(model.SecondQuestion))\n                {\n                    var user = _userManager.Users.FirstOrDefault(d => d.Email == model.Email && d.FirstQuestion == model.FirstQuestion && d.SecondQuestion == model.SecondQuestion);\n                    if (user == null)\n                    {\n                        return RedirectToAction(nameof(ForgotPasswordConfirmation), new { ResetPassword = \"密保答案错误！\" });\n                    }\n\n                    var code = await _userManager.GeneratePasswordResetTokenAsync(user);\n\n                    var accessCode = MD5Helper.MD5Encrypt32(user.Id + code);\n                    var callbackUrl = Url.ResetPasswordCallbackLink(user.Id.ToString(), code, Request.Scheme, accessCode);\n\n\n                    var ResetPassword = $\"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>\";\n\n                    return RedirectToAction(nameof(ForgotPasswordConfirmation), new { ResetPassword = ResetPassword });\n                }\n                else\n                {\n                    var forgetPwdUrl = \"https://github.com/anjoy8/Blog.IdentityServer/issues\";\n                    return RedirectToAction(nameof(AccessDenied), new { errorMsg = $\"只能在登录状态下或者输入正确密保的情况下，修改密码! <br>如果忘记密码，请联系超级管理员手动重置：<a href='{forgetPwdUrl}'>link</a>，提Issue\" });\n                }\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n        [HttpGet]\n        [Route(\"account/forgot-password-confirmation\")]\n        [AllowAnonymous]\n        public IActionResult ForgotPasswordConfirmation(string ResetPassword)\n        {\n            ViewBag.ResetPassword = ResetPassword;\n            return View();\n        }\n\n        [HttpGet]\n        [Route(\"account/reset-password\")]\n        [AllowAnonymous]\n        public IActionResult ResetPassword(string code = null, string accessCode = null, string userId = \"\")\n        {\n            if (code == null || accessCode == null)\n            {\n                return RedirectToAction(nameof(AccessDenied), new { errorMsg = \"code与accessCode必须都不能为空！\" });\n            }\n            var model = new ResetPasswordViewModel { Code = code, AccessCode = accessCode, userId = userId };\n            return View(model);\n        }\n\n        [HttpPost]\n        [Route(\"account/reset-password\")]\n        [AllowAnonymous]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)\n        {\n            if (!ModelState.IsValid)\n            {\n                return View(model);\n            }\n\n            var user = await _userManager.FindByEmailAsync(model.Email);\n            if (user == null)\n            {\n                // Don't reveal that the user does not exist\n                return RedirectToAction(nameof(ResetPasswordConfirmation));\n            }\n\n\n            // 防止篡改\n            var getAccessCode = MD5Helper.MD5Encrypt32(model.userId + model.Code);\n            if (getAccessCode != model.AccessCode)\n            {\n                return RedirectToAction(nameof(AccessDenied), new { errorMsg = \"随机码已被篡改！密码重置失败！\" });\n            }\n\n            if (user != null && user.Id.ToString() != model.userId)\n            {\n                return RedirectToAction(nameof(AccessDenied), new { errorMsg = \"不能修改他人邮箱！密码重置失败！\" });\n            }\n\n\n            var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);\n            if (result.Succeeded)\n            {\n                return RedirectToAction(nameof(ResetPasswordConfirmation));\n            }\n            AddErrors(result);\n            return View();\n        }\n\n        [HttpGet]\n        [Route(\"account/reset-password-confirmation\")]\n        [AllowAnonymous]\n        public IActionResult ResetPasswordConfirmation()\n        {\n            return View();\n        }\n\n\n        [HttpGet]\n        //[Route(\"account/access-denied\")]\n        public IActionResult AccessDenied(string errorMsg = \"\")\n        {\n            ViewBag.ErrorMsg = errorMsg;\n            return View();\n        }\n\n        private void AddErrors(IdentityResult result)\n        {\n            foreach (var error in result.Errors)\n            {\n                ModelState.AddModelError(string.Empty, error.Description);\n            }\n        }\n\n        private IActionResult RedirectToLocal(string returnUrl)\n        {\n            if (Url.IsLocalUrl(returnUrl))\n            {\n                return Redirect(returnUrl);\n            }\n            else\n            {\n                return RedirectToAction(nameof(HomeController.Index), \"Home\");\n            }\n        }\n\n\n        // Role Manager\n\n\n\n        [HttpGet]\n        [Route(\"account/Roleregister\")]\n        public IActionResult RoleRegister(string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            return View();\n        }\n\n        [HttpPost]\n        [Route(\"account/Roleregister\")]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> RoleRegister(RoleRegisterViewModel model, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var roleItem = _roleManager.FindByNameAsync(model.RoleName).Result;\n\n                if (roleItem == null)\n                {\n\n                    var role = new ApplicationRole\n                    {\n                        Name = model.RoleName\n                    };\n\n\n                    result = await _roleManager.CreateAsync(role);\n\n                    if (result.Succeeded)\n                    {\n\n                        if (result.Succeeded)\n                        {\n                            // 可以直接登录\n                            //await _signInManager.SignInAsync(user, isPersistent: false);\n\n                            return RedirectToLocal(returnUrl);\n                        }\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{roleItem?.Name} already exists\");\n\n                }\n\n                AddErrors(result);\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n\n        [HttpGet]\n        [Route(\"account/Roles\")]\n        [Authorize]\n        public IActionResult Roles(string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            var roles = _roleManager.Roles.Where(d => !d.IsDeleted).ToList();\n\n            return View(roles);\n        }\n\n\n\n        [HttpGet(\"{id}\")]\n        [Route(\"account/Roleedit/{id}\")]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<IActionResult> RoleEdit(string id, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            if (id == null)\n            {\n                return NotFound();\n            }\n\n            var user = await _roleManager.FindByIdAsync(id);\n\n            if (user == null)\n            {\n                return NotFound();\n            }\n\n            return View(new RoleEditViewModel(user.Id.ToString(), user.Name));\n        }\n\n\n        [HttpPost]\n        [Route(\"account/Roleedit/{id}\")]\n        [ValidateAntiForgeryToken]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<IActionResult> RoleEdit(RoleEditViewModel model, string id, string returnUrl = null)\n        {\n            ViewData[\"ReturnUrl\"] = returnUrl;\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var roleItem = _roleManager.FindByIdAsync(model.Id).Result;\n\n                if (roleItem != null)\n                {\n                    roleItem.Name = model.RoleName;\n\n\n                    result = await _roleManager.UpdateAsync(roleItem);\n\n                    if (result.Succeeded)\n                    {\n                        return RedirectToLocal(returnUrl);\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{roleItem?.Name} no exist!\");\n                }\n\n                AddErrors(result);\n            }\n\n            // If we got this far, something failed, redisplay form\n            return View(model);\n        }\n\n\n\n        [HttpPost]\n        [Route(\"account/Roledelete/{id}\")]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<JsonResult> RoleDelete(string id)\n        {\n            IdentityResult result = new IdentityResult();\n\n            if (ModelState.IsValid)\n            {\n                var roleItem = _roleManager.FindByIdAsync(id).Result;\n\n                if (roleItem != null)\n                {\n                    roleItem.IsDeleted = true;\n\n\n                    result = await _roleManager.UpdateAsync(roleItem);\n\n                    if (result.Succeeded)\n                    {\n                        return Json(result);\n                    }\n\n                }\n                else\n                {\n                    ModelState.AddModelError(string.Empty, $\"{roleItem?.Name} no exist!\");\n                }\n\n                AddErrors(result);\n            }\n\n            return Json(result.Errors);\n\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/AccountOptions.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = true;//自动跳回原项目\n\n        // specify the Windows authentication scheme being used\n        public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;\n        // if user uses windows auth, should we load the groups from windows\n        public static bool IncludeWindowsGroups = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/EditViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Security.Claims;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class EditViewModel\n    {\n        public EditViewModel()\n        {\n\n        }\n        public EditViewModel(string Id, string Name, string LoginName, string Email, IList<Claim> Claims, string FirstQuestion, string SecondQuestion)\n        {\n            this.Id = Id;\n            this.LoginName = LoginName;\n            this.Email = Email;\n            this.UserName = Name;\n            this.Claims = Claims;\n            this.FirstQuestion = FirstQuestion;\n            this.SecondQuestion = SecondQuestion;\n        }\n\n        public string Id { get; set; }\n\n        [Required]\n        [Display(Name = \"昵称\")]\n        public string UserName { get; set; }\n\n        [Required]\n        [Display(Name = \"登录名\")]\n        public string LoginName { get; set; }\n\n        [Required]\n        [EmailAddress]\n        [Display(Name = \"邮箱\")]\n        public string Email { get; set; }\n\n\n\n\n        [Display(Name = \"性别\")]\n        public int Sex { get; set; } = 0;\n\n        [Display(Name = \"生日\")]\n        public DateTime Birth { get; set; } = DateTime.Now;\n\n        public IList<Claim> Claims { get; set; }\n\n\n        [Display(Name = \"密保问题一：你喜欢的动漫？\")]\n        public string FirstQuestion { get; set; }\n\n        [Display(Name = \"密保问题二：你喜欢的名著？\")]\n        public string SecondQuestion { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/ExternalController.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing Blog.IdentityServer.Models;\nusing IdentityModel;\nusing IdentityServer4;\nusing IdentityServer4.Events;\nusing IdentityServer4.Models;\nusing IdentityServer4.Services;\nusing IdentityServer4.Stores;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    [SecurityHeaders]\n    [AllowAnonymous]\n    public class ExternalController : Controller\n    {\n        private readonly UserManager<ApplicationUser> _userManager;\n        private readonly SignInManager<ApplicationUser> _signInManager;\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clientStore;\n        private readonly IEventService _events;\n        private readonly ILogger<ExternalController> _logger;\n\n        public ExternalController(\n            UserManager<ApplicationUser> userManager,\n            SignInManager<ApplicationUser> signInManager,\n            IIdentityServerInteractionService interaction,\n            IClientStore clientStore,\n            IEventService events,\n            ILogger<ExternalController> logger)\n        {\n            _userManager = userManager;\n            _signInManager = signInManager;\n            _interaction = interaction;\n            _clientStore = clientStore;\n            _events = events;\n            _logger = logger;\n        }\n\n        /// <summary>\n        /// initiate roundtrip to external authentication provider\n        /// </summary>\n        [HttpGet]\n        public IActionResult Challenge(string scheme, string returnUrl)\n        {\n            if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n            // validate returnUrl - either it is a valid OIDC URL or back to a local page\n            if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n            {\n                // user might have clicked on a malicious link - should be logged\n                throw new Exception(\"invalid return URL\");\n            }\n\n            // start challenge and roundtrip the return URL and scheme \n            var props = new AuthenticationProperties\n            {\n                RedirectUri = Url.Action(nameof(Callback)),\n                Items =\n                {\n                    { \"returnUrl\", returnUrl },\n                    { \"scheme\", scheme },\n                }\n            };\n\n            return Challenge(props, scheme);\n\n        }\n\n        /// <summary>\n        /// Post processing of external authentication\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Callback()\n        {\n            // read external identity from the temporary cookie\n            var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n            if (result?.Succeeded != true)\n            {\n                throw new Exception(\"External authentication error\");\n            }\n\n            if (_logger.IsEnabled(LogLevel.Debug))\n            {\n                var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n                _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n            }\n\n            // lookup our user and external provider info\n            var (user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result);\n            if (user == null)\n            {\n                // this might be where you might initiate a custom workflow for user registration\n                // in this sample we don't show how that would be done, as our sample implementation\n                // simply auto-provisions new external user\n                user = await AutoProvisionUserAsync(provider, providerUserId, claims);\n            }\n\n            // this allows us to collect any additional claims or properties\n            // for the specific protocols used and store them in the local auth cookie.\n            // this is typically used to store data needed for signout from those protocols.\n            var additionalLocalClaims = new List<Claim>();\n            var localSignInProps = new AuthenticationProperties();\n            ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n\n            // issue authentication cookie for user\n            // we must issue the cookie maually, and can't use the SignInManager because\n            // it doesn't expose an API to issue additional claims from the login workflow\n            var principal = await _signInManager.CreateUserPrincipalAsync(user);\n            additionalLocalClaims.AddRange(principal.Claims);\n            var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id.ToString();\n\n            var isuser = new IdentityServerUser(user.Id.ToString())\n            {\n                DisplayName = name,\n                IdentityProvider = provider,\n                AdditionalClaims = additionalLocalClaims\n            };\n\n            await HttpContext.SignInAsync(isuser, localSignInProps);\n\n            // delete temporary cookie used during external authentication\n            await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n            // retrieve return URL\n            var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n            // check if external login is in the context of an OIDC request\n            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id.ToString(), name, true, context?.Client.ClientId));\n\n            if (context != null)\n            {\n                if (context.IsNativeClient())\n                {\n                    // The client is native, so this change in how to\n                    // return the response is for better UX for the end user.\n                    return this.LoadingPage(\"Redirect\", returnUrl);\n                }\n            }\n\n            return Redirect(returnUrl);\n        }\n\n        private async Task<(ApplicationUser user, string provider, string providerUserId, IEnumerable<Claim> claims)>\n            FindUserFromExternalProviderAsync(AuthenticateResult result)\n        {\n            var externalUser = result.Principal;\n\n            // try to determine the unique id of the external user (issued by the provider)\n            // the most common claim type for that are the sub claim and the NameIdentifier\n            // depending on the external provider, some other claim type might be used\n            var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                              externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                              throw new Exception(\"Unknown userid\");\n\n            // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n            var claims = externalUser.Claims.ToList();\n            claims.Remove(userIdClaim);\n\n            var provider = result.Properties.Items[\"scheme\"];\n            var providerUserId = userIdClaim.Value;\n\n            // find external user\n            var user = await _userManager.FindByLoginAsync(provider, providerUserId);\n\n            return (user, provider, providerUserId, claims);\n        }\n\n        private async Task<ApplicationUser> AutoProvisionUserAsync(string provider, string providerUserId, IEnumerable<Claim> claims)\n        {\n            // create a list of claims that we want to transfer into our store\n            var filtered = new List<Claim>();\n\n            // user's display name\n            var name = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Name)?.Value ??\n                claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;\n            if (name != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, name));\n            }\n            else\n            {\n                var first = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.GivenName)?.Value ??\n                    claims.FirstOrDefault(x => x.Type == ClaimTypes.GivenName)?.Value;\n                var last = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.FamilyName)?.Value ??\n                    claims.FirstOrDefault(x => x.Type == ClaimTypes.Surname)?.Value;\n                if (first != null && last != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, first + \" \" + last));\n                }\n                else if (first != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, first));\n                }\n                else if (last != null)\n                {\n                    filtered.Add(new Claim(JwtClaimTypes.Name, last));\n                }\n            }\n\n            // email\n            var email = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Email)?.Value ??\n               claims.FirstOrDefault(x => x.Type == ClaimTypes.Email)?.Value;\n            if (email != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Email, email));\n            }\n\n            var user = new ApplicationUser\n            {\n                UserName = Guid.NewGuid().ToString(),\n            };\n            var identityResult = await _userManager.CreateAsync(user);\n            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n            if (filtered.Any())\n            {\n                identityResult = await _userManager.AddClaimsAsync(user, filtered);\n                if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n            }\n\n            identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, providerUserId, provider));\n            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n            return user;\n        }\n\n        // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n        // this will be different for WS-Fed, SAML2p or other protocols\n        private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n        {\n            // if the external system sent a session id claim, copy it over\n            // so we can use it for single sign-out\n            var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n            if (sid != null)\n            {\n                localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n            }\n\n            // if the external provider issued an id_token, we'll keep it for signout\n            var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n            if (idToken != null)\n            {\n                localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n            }\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/ExternalProvider.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ExternalProvider\n    {\n        public string DisplayName { get; set; }\n        public string AuthenticationScheme { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/ForgotPasswordViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ForgotPasswordViewModel\n    {\n        [Required]\n        [EmailAddress]\n        public string Email { get; set; }\n\n        [Display(Name = \"密保问题一：你喜欢的动漫？\")]\n        public string FirstQuestion { get; set; }\n\n        [Display(Name = \"密保问题二：你喜欢的名著？\")]\n        public string SecondQuestion { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/LoggedOutViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class LoggedOutViewModel\n    {\n        public string PostLogoutRedirectUri { get; set; }\n        public string ClientName { get; set; }\n        public string SignOutIframeUrl { get; set; }\n\n        public bool AutomaticRedirectAfterSignOut { get; set; } = false;\n\n        public string LogoutId { get; set; }\n        public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n        public string ExternalAuthenticationScheme { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/LoginInputModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class LoginInputModel\n    {\n        [Required]\n        public string Username { get; set; }\n        [Required]\n        public string Password { get; set; }\n        public bool RememberLogin { get; set; }\n        public string ReturnUrl { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/LoginViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class LoginViewModel : LoginInputModel\n    {\n        public bool AllowRememberLogin { get; set; } = true;\n        public bool EnableLocalLogin { get; set; } = true;\n\n        public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n        public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n        public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n        public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/LogoutInputModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class LogoutInputModel\n    {\n        public string LogoutId { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/LogoutViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class LogoutViewModel : LogoutInputModel\n    {\n        public bool ShowLogoutPrompt { get; set; } = true;\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/RedirectViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class RedirectViewModel\n    {\n        public string RedirectUrl { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/RegisterViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class RegisterViewModel\n    {\n\n        [Required]\n        [Display(Name = \"昵称\")]\n        public string RealName { get; set; }\n\n        [Required]\n        [Display(Name = \"登录名\")]\n        public string LoginName { get; set; }\n\n        [Required]\n        [EmailAddress]\n        [Display(Name = \"邮箱\")]\n        public string Email { get; set; }\n\n        [Required]\n        [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n        [DataType(DataType.Password)]\n        [Display(Name = \"密码\")]\n        public string Password { get; set; }\n\n        [DataType(DataType.Password)]\n        [Display(Name = \"确认密码\")]\n        [Compare(\"Password\", ErrorMessage = \"The 密码 and 确认密码 do not match.\")]\n        public string ConfirmPassword { get; set; }\n\n\n\n        [Required]\n        [Display(Name = \"密保问题一：你喜欢的动漫？\")]\n        public string FirstQuestion { get; set; }\n\n        [Required]\n        [Display(Name = \"密保问题二：你喜欢的名著？\")]\n        public string SecondQuestion { get; set; }\n\n        [Display(Name = \"性别\")]\n        public int Sex { get; set; } = 0;\n\n        [Display(Name = \"生日\")]\n        public DateTime Birth { get; set; } = DateTime.Now;\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/ResetPasswordViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ResetPasswordViewModel\n    {\n        [Required]\n        public string userId { get; set; }\n\n        [Required]\n        [EmailAddress]\n        public string Email { get; set; }\n\n        [Required]\n        [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n        [DataType(DataType.Password)]\n        public string Password { get; set; }\n\n        [DataType(DataType.Password)]\n        [Display(Name = \"Confirm password\")]\n        [Compare(\"Password\", ErrorMessage = \"The password and confirmation password do not match.\")]\n        public string ConfirmPassword { get; set; }\n\n        public string Code { get; set; }\n        public string AccessCode { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/RoleEditViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class RoleEditViewModel\n    {\n        public RoleEditViewModel()\n        {\n           \n        }\n        public RoleEditViewModel(string Id, string Name)\n        {\n            this.Id = Id;\n            this.RoleName = Name;\n        }\n\n        public string Id { get; set; }\n\n        [Required]\n        [Display(Name = \"角色名\")]\n        public string RoleName { get; set; }\n\n       \n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/RoleRegisterViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class RoleRegisterViewModel\n    {\n\n        [Required]\n        [Display(Name = \"角色名\")]\n        public string RoleName { get; set; }\n\n        \n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Account/UrlHelperExtensions.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public static class UrlHelperExtensions\n    {\n        public static string EmailConfirmationLink(this IUrlHelper urlHelper, string userId, string code, string scheme)\n        {\n            return urlHelper.Action(\n                action: nameof(AccountController.ConfirmEmail),\n                controller: \"Account\",\n                values: new { userId, code },\n                protocol: scheme);\n        }\n\n        public static string ResetPasswordCallbackLink(this IUrlHelper urlHelper, string userId, string code, string scheme, string accessCode = \"\")\n        {\n            return urlHelper.Action(\n                action: nameof(AccountController.ResetPassword),\n                controller: \"Account\",\n                values: new { userId, code, accessCode },\n                protocol: scheme);\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/ApiResource/ApiResourceDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Controllers.ApiResource\n{\n    public class ApiResourceDto\n    {\n        public int Id { get; set; }\n        public string Name { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public string UserClaims { get; set; }\n        public string Scopes { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/ApiResource/ApiResourcesManager.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Blog.IdentityServer.Models;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing IdentityServer4.EntityFramework.Mappers;\nusing IdentityServer4.Models;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace Blog.IdentityServer.Controllers.ApiResource\n{\n    [Route(\"[controller]/[action]\")]\n    [ApiController]\n    public class ApiResourcesManager : Controller\n    {\n        private readonly ConfigurationDbContext _configurationDbContext;\n\n        public ApiResourcesManager(ConfigurationDbContext configurationDbContext)\n        {\n            _configurationDbContext = configurationDbContext;\n        }\n\n        /// <summary>\n        /// 数据列表页\n        /// </summary>\n        /// <returns></returns>\n        [HttpGet]\n        [Authorize]\n        public async Task<IActionResult> Index()\n        {\n            return View(await _configurationDbContext.ApiResources\n                .Include(d => d.UserClaims)\n                .Include(d => d.Scopes)\n                .ToListAsync());\n        }\n\n        /// <summary>\n        /// 数据修改页\n        /// </summary>\n        /// <param name=\"id\"></param>\n        /// <returns></returns>\n        [HttpGet]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public IActionResult CreateOrEdit(int id)\n        {\n            ViewBag.ApiResourceId = id;\n            return View();\n        }\n\n\n        [HttpGet]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<MessageModel<ApiResourceDto>> GetDataById(int id = 0)\n        {\n            var model = (await _configurationDbContext.ApiResources\n                .Include(d => d.UserClaims)\n                .Include(d => d.Scopes)\n                .ToListAsync()).FirstOrDefault(d => d.Id == id).ToModel();\n\n            var apiResourceDto = new ApiResourceDto();\n            if (model != null)\n            {\n                apiResourceDto = new ApiResourceDto()\n                {\n                    Name = model?.Name,\n                    DisplayName = model?.DisplayName,\n                    Description = model?.Description,\n                    UserClaims = string.Join(\",\", model?.UserClaims),\n                    Scopes = string.Join(\",\", model?.Scopes),\n                };\n            }\n\n            return new MessageModel<ApiResourceDto>()\n            {\n                success = true,\n                msg = \"获取成功\",\n                response = apiResourceDto\n            };\n        }\n\n        [HttpPost]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<MessageModel<string>> SaveData(ApiResourceDto request)\n        {\n            if (request != null && request.Id == 0)\n            {\n                IdentityServer4.Models.ApiResource apiResource = new IdentityServer4.Models.ApiResource()\n                {\n                    Name = request?.Name,\n                    DisplayName = request?.DisplayName,\n                    Description = request?.Description,\n                    Enabled = true,\n                    UserClaims = request?.UserClaims?.Split(\",\"),\n                    Scopes = request?.Scopes?.Split(\",\"),\n                };\n\n                var result = (await _configurationDbContext.ApiResources.AddAsync(apiResource.ToEntity()));\n                await _configurationDbContext.SaveChangesAsync();\n            }\n\n            if (request != null && request.Id > 0)\n            {\n\n                var modelEF = (await _configurationDbContext.ApiResources\n                    .Include(d => d.UserClaims)\n                    .Include(d => d.Scopes)\n                    .ToListAsync()).FirstOrDefault(d => d.Id == request.Id);\n\n                modelEF.Name = request?.Name;\n                modelEF.DisplayName = request?.DisplayName;\n                modelEF.Description = request?.Description;\n\n                {\n                    var apiResourceClaim = new List<IdentityServer4.EntityFramework.Entities.ApiResourceClaim>();\n                    if (!string.IsNullOrEmpty(request?.UserClaims))\n                    {\n                        request?.UserClaims.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                        {\n                            apiResourceClaim.Add(new IdentityServer4.EntityFramework.Entities.ApiResourceClaim()\n                            {\n                                ApiResource = modelEF,\n                                ApiResourceId = modelEF.Id,\n                                Type = s\n                            });\n                        });\n                        modelEF.UserClaims = apiResourceClaim;\n                    }\n                }\n\n\n                var apiResourceScopes = new List<IdentityServer4.EntityFramework.Entities.ApiResourceScope>();\n                if (!string.IsNullOrEmpty(request?.Scopes))\n                {\n                    request?.Scopes.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                    {\n                        apiResourceScopes.Add(new IdentityServer4.EntityFramework.Entities.ApiResourceScope()\n                        {\n                            ApiResource = modelEF,\n                            ApiResourceId = modelEF.Id,\n                            Scope = s\n                        });\n                    });\n                    modelEF.Scopes = apiResourceScopes;\n                }\n\n\n                var result = (_configurationDbContext.ApiResources.Update(modelEF));\n                await _configurationDbContext.SaveChangesAsync();\n            }\n\n\n            return new MessageModel<string>()\n            {\n                success = true,\n                msg = \"添加成功\",\n            };\n        }\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Client/ClientDto.cs",
    "content": "﻿namespace Blog.IdentityServer.Controllers.Client\n{\n    public class ClientDto\n    {\n        public int id { get; set; }\n        public string ClientId { get; set; }\n        public string ClientName { get; set; }\n        public string ClientSecrets { get; set; }\n        public string Description { get; set; }\n        public string AllowAccessTokensViaBrowser { get; set; }\n        public string AllowedGrantTypes { get; set; }\n        public string AllowedScopes { get; set; }\n        public string AllowedCorsOrigins { get; set; }\n        public string RedirectUris { get; set; }\n        public string PostLogoutRedirectUris { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Client/ClientsManagerController.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Blog.Core.Common.Helper;\nusing Blog.IdentityServer.Models;\nusing IdentityServer4;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing IdentityServer4.EntityFramework.Mappers;\nusing IdentityServer4.Models;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\nusing static IdentityModel.OidcConstants;\n\nnamespace Blog.IdentityServer.Controllers.Client\n{\n    [Route(\"[controller]/[action]\")]\n    [ApiController]\n    public class ClientsManagerController : Controller\n    {\n        private readonly ConfigurationDbContext _configurationDbContext;\n\n        public ClientsManagerController(ConfigurationDbContext configurationDbContext)\n        {\n            _configurationDbContext = configurationDbContext;\n        }\n\n        /// <summary>\n        /// 数据列表页\n        /// </summary>\n        /// <returns></returns>\n        [HttpGet]\n        [Authorize]\n        public async Task<IActionResult> Index()\n        {\n            return View(await _configurationDbContext.Clients\n                .Include(d => d.AllowedGrantTypes)\n                .Include(d => d.AllowedScopes)\n                .Include(d => d.AllowedCorsOrigins)\n                .Include(d => d.RedirectUris)\n                .Include(d => d.PostLogoutRedirectUris)\n                .ToListAsync());\n        }\n\n        /// <summary>\n        /// 数据修改页\n        /// </summary>\n        /// <param name=\"id\"></param>\n        /// <returns></returns>\n        [HttpGet]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public IActionResult CreateOrEdit(int id)\n        {\n            ViewBag.ClientId = id;\n            return View();\n        }\n\n\n        [HttpGet]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<MessageModel<ClientDto>> GetDataById(int id = 0)\n        {\n            var model = (await _configurationDbContext.Clients\n                .Include(d => d.AllowedGrantTypes)\n                .Include(d => d.AllowedScopes)\n                .Include(d => d.AllowedCorsOrigins)\n                .Include(d => d.RedirectUris)\n                .Include(d => d.PostLogoutRedirectUris)\n                .Include(d => d.ClientSecrets)\n                .ToListAsync()).FirstOrDefault(d => d.Id == id).ToModel();\n\n            var clientDto = new ClientDto();\n            if (model != null)\n            {\n                clientDto = new ClientDto()\n                {\n                    ClientId = model?.ClientId,\n                    ClientName = model?.ClientName,\n                    Description = model?.Description,\n                    AllowAccessTokensViaBrowser = (model?.AllowAccessTokensViaBrowser).ObjToString(),\n                    AllowedCorsOrigins = string.Join(\",\", model?.AllowedCorsOrigins),\n                    AllowedGrantTypes = string.Join(\",\", model?.AllowedGrantTypes),\n                    AllowedScopes = string.Join(\",\", model?.AllowedScopes),\n                    PostLogoutRedirectUris = string.Join(\",\", model?.PostLogoutRedirectUris),\n                    RedirectUris = string.Join(\",\", model?.RedirectUris),\n                    ClientSecrets = string.Join(\",\", model?.ClientSecrets.Select(d => d.Value)),\n                };\n            }\n\n            return new MessageModel<ClientDto>()\n            {\n                success = true,\n                msg = \"获取成功\",\n                response = clientDto\n            };\n        }\n\n        [HttpPost]\n        [Authorize(Policy = \"SuperAdmin\")]\n        public async Task<MessageModel<string>> SaveData(ClientDto request)\n        {\n            if (request != null && request.id == 0)\n            {\n                IdentityServer4.Models.Client client = new IdentityServer4.Models.Client()\n                {\n                    ClientId = request?.ClientId,\n                    ClientName = request?.ClientName,\n                    Description = request?.Description,\n                    AllowAccessTokensViaBrowser = (request?.AllowAccessTokensViaBrowser).ObjToBool(),\n                    AllowedCorsOrigins = request?.AllowedCorsOrigins?.Split(\",\"),\n                    AllowedGrantTypes = request?.AllowedGrantTypes?.Split(\",\"),\n                    AllowedScopes = request?.AllowedScopes?.Split(\",\"),\n                    PostLogoutRedirectUris = request?.PostLogoutRedirectUris?.Split(\",\"),\n                    RedirectUris = request?.RedirectUris?.Split(\",\"),\n                };\n\n                if (!string.IsNullOrEmpty(request.ClientSecrets))\n                {\n                    client.ClientSecrets = new List<Secret>() { new Secret(request.ClientSecrets.Sha256()) };\n                }\n\n                var result = (await _configurationDbContext.Clients.AddAsync(client.ToEntity()));\n                await _configurationDbContext.SaveChangesAsync();\n            }\n\n            if (request != null && request.id > 0)\n            {\n\n                var modelEF = (await _configurationDbContext.Clients\n                    .Include(d => d.AllowedGrantTypes)\n                    .Include(d => d.AllowedScopes)\n                    .Include(d => d.AllowedCorsOrigins)\n                    .Include(d => d.RedirectUris)\n                    .Include(d => d.PostLogoutRedirectUris)\n                    .ToListAsync()).FirstOrDefault(d => d.Id == request.id);\n\n                modelEF.ClientId = request?.ClientId;\n                modelEF.ClientName = request?.ClientName;\n                modelEF.Description = request?.Description;\n                modelEF.AllowAccessTokensViaBrowser = (request?.AllowAccessTokensViaBrowser).ObjToBool();\n\n                var AllowedCorsOrigins = new List<IdentityServer4.EntityFramework.Entities.ClientCorsOrigin>();\n                if (!string.IsNullOrEmpty(request?.AllowedCorsOrigins))\n                {\n                    request?.AllowedCorsOrigins.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                               {\n                                   AllowedCorsOrigins.Add(new IdentityServer4.EntityFramework.Entities.ClientCorsOrigin()\n                                   {\n                                       Client = modelEF,\n                                       ClientId = modelEF.Id,\n                                       Origin = s\n                                   });\n                               });\n                    modelEF.AllowedCorsOrigins = AllowedCorsOrigins;\n                }\n\n\n\n                var AllowedGrantTypes = new List<IdentityServer4.EntityFramework.Entities.ClientGrantType>();\n                if (!string.IsNullOrEmpty(request?.AllowedGrantTypes))\n                {\n                    request?.AllowedGrantTypes.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                    {\n                        AllowedGrantTypes.Add(new IdentityServer4.EntityFramework.Entities.ClientGrantType()\n                        {\n                            Client = modelEF,\n                            ClientId = modelEF.Id,\n                            GrantType = s\n                        });\n                    });\n                    modelEF.AllowedGrantTypes = AllowedGrantTypes;\n                }\n\n\n\n                var AllowedScopes = new List<IdentityServer4.EntityFramework.Entities.ClientScope>();\n                if (!string.IsNullOrEmpty(request?.AllowedScopes))\n                {\n                    request?.AllowedScopes.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                    {\n                        AllowedScopes.Add(new IdentityServer4.EntityFramework.Entities.ClientScope()\n                        {\n                            Client = modelEF,\n                            ClientId = modelEF.Id,\n                            Scope = s\n                        });\n                    });\n                    modelEF.AllowedScopes = AllowedScopes;\n                }\n\n\n                var PostLogoutRedirectUris = new List<IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri>();\n                if (!string.IsNullOrEmpty(request?.PostLogoutRedirectUris))\n                {\n                    request?.PostLogoutRedirectUris.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                    {\n                        PostLogoutRedirectUris.Add(new IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri()\n                        {\n                            Client = modelEF,\n                            ClientId = modelEF.Id,\n                            PostLogoutRedirectUri = s\n                        });\n                    });\n                    modelEF.PostLogoutRedirectUris = PostLogoutRedirectUris;\n                }\n\n\n                var RedirectUris = new List<IdentityServer4.EntityFramework.Entities.ClientRedirectUri>();\n                if (!string.IsNullOrEmpty(request?.RedirectUris))\n                {\n                    request?.RedirectUris.Split(\",\").Where(s => s != \"\" && s != null).ToList().ForEach(s =>\n                    {\n                        RedirectUris.Add(new IdentityServer4.EntityFramework.Entities.ClientRedirectUri()\n                        {\n                            Client = modelEF,\n                            ClientId = modelEF.Id,\n                            RedirectUri = s\n                        });\n                    });\n                    modelEF.RedirectUris = RedirectUris;\n                }\n\n                var result = (_configurationDbContext.Clients.Update(modelEF));\n                await _configurationDbContext.SaveChangesAsync();\n            }\n\n\n            return new MessageModel<string>()\n            {\n                success = true,\n                msg = \"添加成功\",\n            };\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ConsentController.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityServer4.Events;\nusing IdentityServer4.Models;\nusing IdentityServer4.Services;\nusing IdentityServer4.Extensions;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Logging;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer4.Validation;\nusing System.Collections.Generic;\nusing System;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    /// <summary>\n    /// This controller processes the consent UI\n    /// </summary>\n    [SecurityHeaders]\n    [Authorize]\n    public class ConsentController : Controller\n    {\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IEventService _events;\n        private readonly ILogger<ConsentController> _logger;\n\n        public ConsentController(\n            IIdentityServerInteractionService interaction,\n            IEventService events,\n            ILogger<ConsentController> logger)\n        {\n            _interaction = interaction;\n            _events = events;\n            _logger = logger;\n        }\n\n        /// <summary>\n        /// Shows the consent screen\n        /// </summary>\n        /// <param name=\"returnUrl\"></param>\n        /// <returns></returns>\n        [HttpGet]\n        public async Task<IActionResult> Index(string returnUrl)\n        {\n            var vm = await BuildViewModelAsync(returnUrl);\n            if (vm != null)\n            {\n                return View(\"Index\", vm);\n            }\n\n            return View(\"Error\");\n        }\n\n        /// <summary>\n        /// Handles the consent screen postback\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Index(ConsentInputModel model)\n        {\n            var result = await ProcessConsent(model);\n\n            if (result.IsRedirect)\n            {\n                var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n                if (context?.IsNativeClient() == true)\n                {\n                    // The client is native, so this change in how to\n                    // return the response is for better UX for the end user.\n                    return this.LoadingPage(\"Redirect\", result.RedirectUri);\n                }\n\n                return Redirect(result.RedirectUri);\n            }\n\n            if (result.HasValidationError)\n            {\n                ModelState.AddModelError(string.Empty, result.ValidationError);\n            }\n\n            if (result.ShowView)\n            {\n                return View(\"Index\", result.ViewModel);\n            }\n\n            return View(\"Error\");\n        }\n\n        /*****************************************/\n        /* helper APIs for the ConsentController */\n        /*****************************************/\n        private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n        {\n            var result = new ProcessConsentResult();\n\n            // validate return url is still valid\n            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (request == null) return result;\n\n            ConsentResponse grantedConsent = null;\n\n            // user clicked 'no' - send back the standard 'access_denied' response\n            if (model?.Button == \"no\")\n            {\n                grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n            }\n            // user clicked 'yes' - validate the data\n            else if (model?.Button == \"yes\")\n            {\n                // if the user consented to some scope, build the response model\n                if (model.ScopesConsented != null && model.ScopesConsented.Any())\n                {\n                    var scopes = model.ScopesConsented;\n                    if (ConsentOptions.EnableOfflineAccess == false)\n                    {\n                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);\n                    }\n\n                    grantedConsent = new ConsentResponse\n                    {\n                        RememberConsent = model.RememberConsent,\n                        ScopesValuesConsented = scopes.ToArray(),\n                        Description = model.Description\n                    };\n\n                    // emit event\n                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n                }\n                else\n                {\n                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n                }\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n            }\n\n            if (grantedConsent != null)\n            {\n                // communicate outcome of consent back to identityserver\n                await _interaction.GrantConsentAsync(request, grantedConsent);\n\n                // indicate that's it ok to redirect back to authorization endpoint\n                result.RedirectUri = model.ReturnUrl;\n                result.Client = request.Client;\n            }\n            else\n            {\n                // we need to redisplay the consent UI\n                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n            }\n\n            return result;\n        }\n\n        private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n        {\n            var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            if (request != null)\n            {\n                return CreateConsentViewModel(model, returnUrl, request);\n            }\n            else\n            {\n                _logger.LogError(\"No consent request matching request: {0}\", returnUrl);\n            }\n\n            return null;\n        }\n\n        private ConsentViewModel CreateConsentViewModel(\n            ConsentInputModel model, string returnUrl,\n            AuthorizationRequest request)\n        {\n            var vm = new ConsentViewModel\n            {\n                RememberConsent = model?.RememberConsent ?? true,\n                ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n                Description = model?.Description,\n\n                ReturnUrl = returnUrl,\n\n                ClientName = request.Client.ClientName ?? request.Client.ClientId,\n                ClientUrl = request.Client.ClientUri,\n                ClientLogoUrl = request.Client.LogoUri,\n                AllowRememberConsent = request.Client.AllowRememberConsent\n            };\n\n            vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n            var apiScopes = new List<ScopeViewModel>();\n            foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n            {\n                var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n                if (apiScope != null)\n                {\n                    var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                    apiScopes.Add(scopeVm);\n                }\n            }\n            if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n            {\n                apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n            }\n            vm.ApiScopes = apiScopes;\n\n            return vm;\n        }\n\n        private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = identity.Name,\n                DisplayName = identity.DisplayName ?? identity.Name,\n                Description = identity.Description,\n                Emphasize = identity.Emphasize,\n                Required = identity.Required,\n                Checked = check || identity.Required\n            };\n        }\n\n        public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n        {\n            var displayName = apiScope.DisplayName ?? apiScope.Name;\n            if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n            {\n                displayName += \":\" + parsedScopeValue.ParsedParameter;\n            }\n\n            return new ScopeViewModel\n            {\n                Value = parsedScopeValue.RawValue,\n                DisplayName = displayName,\n                Description = apiScope.Description,\n                Emphasize = apiScope.Emphasize,\n                Required = apiScope.Required,\n                Checked = check || apiScope.Required\n            };\n        }\n\n        private ScopeViewModel GetOfflineAccessScope(bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess,\n                DisplayName = ConsentOptions.OfflineAccessDisplayName,\n                Description = ConsentOptions.OfflineAccessDescription,\n                Emphasize = true,\n                Checked = check\n            };\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ConsentInputModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System.Collections.Generic;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ConsentInputModel\n    {\n        public string Button { get; set; }\n        public IEnumerable<string> ScopesConsented { get; set; }\n        public bool RememberConsent { get; set; }\n        public string ReturnUrl { get; set; }\n        public string Description { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ConsentOptions.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ConsentOptions\n    {\n        public static bool EnableOfflineAccess = true;\n        public static string OfflineAccessDisplayName = \"Offline Access\";\n        public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n        public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n        public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ConsentViewModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System.Collections.Generic;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ConsentViewModel : ConsentInputModel\n    {\n        public string ClientName { get; set; }\n        public string ClientUrl { get; set; }\n        public string ClientLogoUrl { get; set; }\n        public bool AllowRememberConsent { get; set; }\n\n        public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n        public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ProcessConsentResult.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nusing IdentityServer4.Models;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ProcessConsentResult\n    {\n        public bool IsRedirect => RedirectUri != null;\n        public string RedirectUri { get; set; }\n        public Client Client { get; set; }\n\n        public bool ShowView => ViewModel != null;\n        public ConsentViewModel ViewModel { get; set; }\n\n        public bool HasValidationError => ValidationError != null;\n        public string ValidationError { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Consent/ScopeViewModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ScopeViewModel\n    {\n        public string Value { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public bool Emphasize { get; set; }\n        public bool Required { get; set; }\n        public bool Checked { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Device/DeviceAuthorizationInputModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI.Device\n{\n    public class DeviceAuthorizationInputModel : ConsentInputModel\n    {\n        public string UserCode { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Device/DeviceAuthorizationViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nnamespace IdentityServer4.Quickstart.UI.Device\n{\n    public class DeviceAuthorizationViewModel : ConsentViewModel\n    {\n        public string UserCode { get; set; }\n        public bool ConfirmUserCode { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Device/DeviceController.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer4.Configuration;\nusing IdentityServer4.Events;\nusing IdentityServer4.Extensions;\nusing IdentityServer4.Models;\nusing IdentityServer4.Services;\nusing IdentityServer4.Validation;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.Options;\n\nnamespace IdentityServer4.Quickstart.UI.Device\n{\n    [Authorize]\n    [SecurityHeaders]\n    public class DeviceController : Controller\n    {\n        private readonly IDeviceFlowInteractionService _interaction;\n        private readonly IEventService _events;\n        private readonly IOptions<IdentityServerOptions> _options;\n        private readonly ILogger<DeviceController> _logger;\n\n        public DeviceController(\n            IDeviceFlowInteractionService interaction,\n            IEventService eventService,\n            IOptions<IdentityServerOptions> options,\n            ILogger<DeviceController> logger)\n        {\n            _interaction = interaction;\n            _events = eventService;\n            _options = options;\n            _logger = logger;\n        }\n\n        [HttpGet]\n        public async Task<IActionResult> Index()\n        {\n            string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n            string userCode = Request.Query[userCodeParamName];\n            if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n            var vm = await BuildViewModelAsync(userCode);\n            if (vm == null) return View(\"Error\");\n\n            vm.ConfirmUserCode = true;\n            return View(\"UserCodeConfirmation\", vm);\n        }\n\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> UserCodeCapture(string userCode)\n        {\n            var vm = await BuildViewModelAsync(userCode);\n            if (vm == null) return View(\"Error\");\n\n            return View(\"UserCodeConfirmation\", vm);\n        }\n\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n        {\n            if (model == null) throw new ArgumentNullException(nameof(model));\n\n            var result = await ProcessConsent(model);\n            if (result.HasValidationError) return View(\"Error\");\n\n            return View(\"Success\");\n        }\n\n        private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n        {\n            var result = new ProcessConsentResult();\n\n            var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n            if (request == null) return result;\n\n            ConsentResponse grantedConsent = null;\n\n            // user clicked 'no' - send back the standard 'access_denied' response\n            if (model.Button == \"no\")\n            {\n                grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n            }\n            // user clicked 'yes' - validate the data\n            else if (model.Button == \"yes\")\n            {\n                // if the user consented to some scope, build the response model\n                if (model.ScopesConsented != null && model.ScopesConsented.Any())\n                {\n                    var scopes = model.ScopesConsented;\n                    if (ConsentOptions.EnableOfflineAccess == false)\n                    {\n                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);\n                    }\n\n                    grantedConsent = new ConsentResponse\n                    {\n                        RememberConsent = model.RememberConsent,\n                        ScopesValuesConsented = scopes.ToArray(),\n                        Description = model.Description\n                    };\n\n                    // emit event\n                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n                }\n                else\n                {\n                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n                }\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n            }\n\n            if (grantedConsent != null)\n            {\n                // communicate outcome of consent back to identityserver\n                await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n                // indicate that's it ok to redirect back to authorization endpoint\n                result.RedirectUri = model.ReturnUrl;\n                result.Client = request.Client;\n            }\n            else\n            {\n                // we need to redisplay the consent UI\n                result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n            }\n\n            return result;\n        }\n\n        private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n        {\n            var request = await _interaction.GetAuthorizationContextAsync(userCode);\n            if (request != null)\n            {\n                return CreateConsentViewModel(userCode, model, request);\n            }\n\n            return null;\n        }\n\n        private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n        {\n            var vm = new DeviceAuthorizationViewModel\n            {\n                UserCode = userCode,\n                Description = model?.Description,\n\n                RememberConsent = model?.RememberConsent ?? true,\n                ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n                ClientName = request.Client.ClientName ?? request.Client.ClientId,\n                ClientUrl = request.Client.ClientUri,\n                ClientLogoUrl = request.Client.LogoUri,\n                AllowRememberConsent = request.Client.AllowRememberConsent\n            };\n\n            vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n            var apiScopes = new List<ScopeViewModel>();\n            foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n            {\n                var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n                if (apiScope != null)\n                {\n                    var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                    apiScopes.Add(scopeVm);\n                }\n            }\n            if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n            {\n                apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n            }\n            vm.ApiScopes = apiScopes;\n\n            return vm;\n        }\n\n        private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = identity.Name,\n                DisplayName = identity.DisplayName ?? identity.Name,\n                Description = identity.Description,\n                Emphasize = identity.Emphasize,\n                Required = identity.Required,\n                Checked = check || identity.Required\n            };\n        }\n\n        public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = parsedScopeValue.RawValue,\n                // todo: use the parsed scope value in the display?\n                DisplayName = apiScope.DisplayName ?? apiScope.Name,\n                Description = apiScope.Description,\n                Emphasize = apiScope.Emphasize,\n                Required = apiScope.Required,\n                Checked = check || apiScope.Required\n            };\n        }\n        private ScopeViewModel GetOfflineAccessScope(bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess,\n                DisplayName = ConsentOptions.OfflineAccessDisplayName,\n                Description = ConsentOptions.OfflineAccessDescription,\n                Emphasize = true,\n                Checked = check\n            };\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Diagnostics/DiagnosticsController.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    [SecurityHeaders]\n    [Authorize]\n    public class DiagnosticsController : Controller\n    {\n        public async Task<IActionResult> Index()\n        {\n            var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n            if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n            {\n                return NotFound();\n            }\n\n            var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n            return View(model);\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Diagnostics/DiagnosticsViewModel.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityModel;\nusing Microsoft.AspNetCore.Authentication;\nusing Newtonsoft.Json;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class DiagnosticsViewModel\n    {\n        public DiagnosticsViewModel(AuthenticateResult result)\n        {\n            AuthenticateResult = result;\n\n            if (result.Properties.Items.ContainsKey(\"client_list\"))\n            {\n                var encoded = result.Properties.Items[\"client_list\"];\n                var bytes = Base64Url.Decode(encoded);\n                var value = Encoding.UTF8.GetString(bytes);\n\n                Clients = JsonConvert.DeserializeObject<string[]>(value);\n            }\n        }\n\n        public AuthenticateResult AuthenticateResult { get; }\n        public IEnumerable<string> Clients { get; } = new List<string>();\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Extensions.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing IdentityServer4.Models;\nusing IdentityServer4.Stores;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public static class Extensions\n    {\n        /// <summary>\n        /// Determines whether the client is configured to use PKCE.\n        /// </summary>\n        /// <param name=\"store\">The store.</param>\n        /// <param name=\"client_id\">The client identifier.</param>\n        /// <returns></returns>\n        public static async Task<bool> IsPkceClientAsync(this IClientStore store, string client_id)\n        {\n            if (!string.IsNullOrWhiteSpace(client_id))\n            {\n                var client = await store.FindEnabledClientByIdAsync(client_id);\n                return client?.RequirePkce == true;\n            }\n\n            return false;\n        }\n\n        /// <summary>\n        /// Checks if the redirect URI is for a native client.\n        /// </summary>\n        /// <returns></returns>\n        public static bool IsNativeClient(this AuthorizationRequest context)\n        {\n            return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n               && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n        }\n\n        public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n        {\n            controller.HttpContext.Response.StatusCode = 200;\n            controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n\n            return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Grants/GrantsController.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityServer4.Services;\nusing IdentityServer4.Stores;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authorization;\nusing IdentityServer4.Events;\nusing IdentityServer4.Extensions;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    /// <summary>\n    /// This sample controller allows a user to revoke grants given to clients\n    /// </summary>\n    [SecurityHeaders]\n    [Authorize]\n    public class GrantsController : Controller\n    {\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clients;\n        private readonly IResourceStore _resources;\n        private readonly IEventService _events;\n\n        public GrantsController(IIdentityServerInteractionService interaction,\n            IClientStore clients,\n            IResourceStore resources,\n            IEventService events)\n        {\n            _interaction = interaction;\n            _clients = clients;\n            _resources = resources;\n            _events = events;\n        }\n\n        /// <summary>\n        /// Show list of grants\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Index()\n        {\n            return View(\"Index\", await BuildViewModelAsync());\n        }\n\n        /// <summary>\n        /// Handle postback to revoke a client\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Revoke(string clientId)\n        {\n            await _interaction.RevokeUserConsentAsync(clientId);\n            await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n            return RedirectToAction(\"Index\");\n        }\n\n        private async Task<GrantsViewModel> BuildViewModelAsync()\n        {\n            var grants = await _interaction.GetAllUserGrantsAsync();\n\n            var list = new List<GrantViewModel>();\n            foreach (var grant in grants)\n            {\n                var client = await _clients.FindClientByIdAsync(grant.ClientId);\n                if (client != null)\n                {\n                    var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                    var item = new GrantViewModel()\n                    {\n                        ClientId = client.ClientId,\n                        ClientName = client.ClientName ?? client.ClientId,\n                        ClientLogoUrl = client.LogoUri,\n                        ClientUrl = client.ClientUri,\n                        Description = grant.Description,\n                        Created = grant.CreationTime,\n                        Expires = grant.Expiration,\n                        IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                        ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                    };\n\n                    list.Add(item);\n                }\n            }\n\n            return new GrantsViewModel\n            {\n                Grants = list\n            };\n        }\n\n\n        [HttpGet]\n        [AllowAnonymous]\n        public IActionResult Config()\n        {\n            return View();\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Grants/GrantsViewModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class GrantsViewModel\n    {\n        public IEnumerable<GrantViewModel> Grants { get; set; }\n    }\n\n    public class GrantViewModel\n    {\n        public string ClientId { get; set; }\n        public string ClientName { get; set; }\n        public string ClientUrl { get; set; }\n        public string ClientLogoUrl { get; set; }\n        public string Description { get; set; }\n        public DateTime Created { get; set; }\n        public DateTime? Expires { get; set; }\n        public IEnumerable<string> IdentityGrantNames { get; set; }\n        public IEnumerable<string> ApiGrantNames { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Home/ErrorViewModel.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityServer4.Models;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class ErrorViewModel\n    {\n        public ErrorMessage Error { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Home/HomeController.cs",
    "content": "// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityServer4.Services;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.Extensions.Logging;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    [SecurityHeaders]\n    [AllowAnonymous]\n    public class HomeController : Controller\n    {\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IWebHostEnvironment _environment;\n        private readonly ILogger _logger;\n\n        public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n        {\n            _interaction = interaction;\n            _environment = environment;\n            _logger = logger;\n        }\n\n        public IActionResult Index()\n        {\n            return View();\n\n            //if (_environment.IsDevelopment())\n            //{\n            //    // only show in development\n            //    return View();\n            //}\n\n            //_logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n            //return NotFound();\n        }\n\n        /// <summary>\n        /// Shows the error page\n        /// </summary>\n        public async Task<IActionResult> Error(string errorId)\n        {\n            var vm = new ErrorViewModel();\n\n            // retrieve error details from identityserver\n            var message = await _interaction.GetErrorContextAsync(errorId);\n            if (message != null)\n            {\n                vm.Error = message;\n\n                if (!_environment.IsDevelopment())\n                {\n                    // only show in development\n                    message.ErrorDescription = null;\n                }\n            }\n\n            return View(\"Error\", vm);\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/Home/Is4ApiController.cs",
    "content": "﻿using Blog.IdentityServer.Models;\nusing Blog.IdentityServer.Models.ViewModel;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Controllers\n{\n    [Route(\"[controller]/[action]\")]\n    [ApiController]\n    public class Is4ApiController : ControllerBase\n    {\n        private readonly UserManager<ApplicationUser> _userManager;\n\n        public Is4ApiController(UserManager<ApplicationUser> userManager)\n        {\n            _userManager = userManager;\n        }\n\n\n        [HttpGet]\n        public MessageModel<AccessApiDateView> GetAchieveUsers()\n        {\n            List<ApiDate> apiDates = new List<ApiDate>();\n\n            var users = _userManager.Users.Where(d => !d.tdIsDelete).OrderByDescending(d => d.Id).ToList();\n\n            var tadayRegisterUser = users.Where(d => d.birth >= DateTime.Now.Date).Count();\n\n            apiDates = (from n in users\n                        group n by new { n.birth.Date } into g\n                        select new ApiDate\n                        {\n                            date = g.Key?.Date.ToString(\"yyyy-MM-dd\"),\n                            count = g.Count(),\n                        }).ToList();\n\n            apiDates = apiDates.OrderByDescending(d => d.date).Take(30).ToList();\n\n\n            if (apiDates.Count == 0)\n            {\n                apiDates.Add(new ApiDate()\n                {\n                    date = \"没数据,或未开启相应接口服务\",\n                    count = 0\n                });\n            }\n            return new MessageModel<AccessApiDateView>()\n            {\n                msg = \"获取成功\",\n                success = true,\n                response = new AccessApiDateView\n                {\n                    columns = new string[] { \"date\", \"count\" },\n                    rows = apiDates.OrderBy(d => d.date).ToList(),\n                    today = tadayRegisterUser,\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Controllers/SecurityHeadersAttribute.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Mvc.Filters;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class SecurityHeadersAttribute : ActionFilterAttribute\n    {\n        public override void OnResultExecuting(ResultExecutingContext context)\n        {\n            var result = context.Result;\n            if (result is ViewResult)\n            {\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n                {\n                    context.HttpContext.Response.Headers.Add(\"X-Content-Type-Options\", \"nosniff\");\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n                {\n                    context.HttpContext.Response.Headers.Add(\"X-Frame-Options\", \"SAMEORIGIN\");\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n                var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n                // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n                //csp += \"upgrade-insecure-requests;\";\n                // also an example if you need client images to be displayed from twitter\n                // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n                // once for standards compliant browsers\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n                {\n                    context.HttpContext.Response.Headers.Add(\"Content-Security-Policy\", csp);\n                }\n                // and once again for IE\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n                {\n                    context.HttpContext.Response.Headers.Add(\"X-Content-Security-Policy\", csp);\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n                var referrer_policy = \"no-referrer\";\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n                {\n                    context.HttpContext.Response.Headers.Add(\"Referrer-Policy\", referrer_policy);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Controllers/TestUsers.cs",
    "content": "﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\n\nusing IdentityModel;\nusing IdentityServer4.Test;\nusing System.Collections.Generic;\nusing System.Security.Claims;\n\nnamespace IdentityServer4.Quickstart.UI\n{\n    public class TestUsers\n    {\n        public static List<TestUser> Users = new List<TestUser>\n        {\n            new TestUser{SubjectId = \"818727\", Username = \"alice\", Password = \"alice\", \n                Claims = \n                {\n                    new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            },\n            new TestUser{SubjectId = \"88421113\", Username = \"bob\", Password = \"bob\", \n                Claims = \n                {\n                    new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json),\n                    new Claim(\"location\", \"somewhere\")\n                }\n            }\n        };\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Data/ApplicationDbContext.cs",
    "content": "﻿using Microsoft.AspNetCore.Identity.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Blog.IdentityServer.Models;\nusing Microsoft.AspNetCore.Identity;\n\nnamespace Blog.IdentityServer.Data\n{\n    //public class ApplicationDbContext : IdentityDbContext<ApplicationUser>\n    //{\n    //    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)\n    //        : base(options)\n    //    {\n    //    }\n\n    //    protected override void OnModelCreating(ModelBuilder builder)\n    //    {\n    //        base.OnModelCreating(builder);\n    //        // Customize the ASP.NET Identity model and override the defaults if needed.\n    //        // For example, you can rename the ASP.NET Identity table names and more.\n    //        // Add your customizations after calling base.OnModelCreating(builder);\n    //    }\n    //}\n\n    public class ApplicationDbContext\n    : IdentityDbContext<ApplicationUser, ApplicationRole, int, IdentityUserClaim<int>,\n    ApplicationUserRole, IdentityUserLogin<int>,\n    IdentityRoleClaim<int>, IdentityUserToken<int>>\n    {\n        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)\n            : base(options)\n        {\n        }\n\n        protected override void OnModelCreating(ModelBuilder builder)\n        {\n            base.OnModelCreating(builder);\n\n            //builder.Entity<ApplicationUserRole>(userRole =>\n            //{\n            //    userRole.HasKey(ur => new { ur.UserId, ur.RoleId });\n\n            //    userRole.HasOne(ur => ur.Role)\n            //        .WithMany(r => r.UserRoles)\n            //        .HasForeignKey(ur => ur.RoleId)\n            //        .IsRequired();\n\n            //    userRole.HasOne(ur => ur.User)\n            //        .WithMany(r => r.UserRoles)\n            //        .HasForeignKey(ur => ur.UserId)\n            //        .IsRequired();\n            //});\n\n            //// 就是这里，我们可以修改下表名等其他任意操作\n            //builder.Entity<ApplicationRole>()\n            //    .ToTable(\"Role\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/20200509165505_AppDbMigration.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Blog.IdentityServer.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    [Migration(\"20200509165505_AppDbMigration\")]\n    partial class AppDbMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.3\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationRole\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"CreateBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"CreateId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"CreateTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"IsDeleted\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"ModifyBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"ModifyId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"ModifyTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<int>(\"OrderSort\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUser\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessFailedCount\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Email\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"LockoutEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LoginName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"PhoneNumber\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"RealName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"SecurityStamp\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"addr\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"age\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"birth\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<int>(\"sex\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"tdIsDelete\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"RoleId1\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"UserId1\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.HasIndex(\"RoleId1\");\n\n                    b.HasIndex(\"UserId1\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderKey\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderDisplayName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Value\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", \"Role\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"RoleId1\");\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", \"User\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"UserId1\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/20200509165505_AppDbMigration.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql\n{\n    public partial class AppDbMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"AspNetRoles\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Name = table.Column<string>(maxLength: 256, nullable: true),\n                    NormalizedName = table.Column<string>(maxLength: 256, nullable: true),\n                    ConcurrencyStamp = table.Column<string>(nullable: true),\n                    IsDeleted = table.Column<bool>(nullable: false),\n                    Description = table.Column<string>(nullable: true),\n                    OrderSort = table.Column<int>(nullable: false),\n                    Enabled = table.Column<bool>(nullable: false),\n                    CreateId = table.Column<int>(nullable: true),\n                    CreateBy = table.Column<string>(nullable: true),\n                    CreateTime = table.Column<DateTime>(nullable: true),\n                    ModifyId = table.Column<int>(nullable: true),\n                    ModifyBy = table.Column<string>(nullable: true),\n                    ModifyTime = table.Column<DateTime>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetRoles\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUsers\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    UserName = table.Column<string>(maxLength: 256, nullable: true),\n                    NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),\n                    Email = table.Column<string>(maxLength: 256, nullable: true),\n                    NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),\n                    EmailConfirmed = table.Column<bool>(nullable: false),\n                    PasswordHash = table.Column<string>(nullable: true),\n                    SecurityStamp = table.Column<string>(nullable: true),\n                    ConcurrencyStamp = table.Column<string>(nullable: true),\n                    PhoneNumber = table.Column<string>(nullable: true),\n                    PhoneNumberConfirmed = table.Column<bool>(nullable: false),\n                    TwoFactorEnabled = table.Column<bool>(nullable: false),\n                    LockoutEnd = table.Column<DateTimeOffset>(nullable: true),\n                    LockoutEnabled = table.Column<bool>(nullable: false),\n                    AccessFailedCount = table.Column<int>(nullable: false),\n                    LoginName = table.Column<string>(nullable: true),\n                    RealName = table.Column<string>(nullable: true),\n                    sex = table.Column<int>(nullable: false),\n                    age = table.Column<int>(nullable: false),\n                    birth = table.Column<DateTime>(nullable: false),\n                    addr = table.Column<string>(nullable: true),\n                    tdIsDelete = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUsers\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetRoleClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    RoleId = table.Column<int>(nullable: false),\n                    ClaimType = table.Column<string>(nullable: true),\n                    ClaimValue = table.Column<string>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetRoleClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_AspNetRoleClaims_AspNetRoles_RoleId\",\n                        column: x => x.RoleId,\n                        principalTable: \"AspNetRoles\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    UserId = table.Column<int>(nullable: false),\n                    ClaimType = table.Column<string>(nullable: true),\n                    ClaimValue = table.Column<string>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserClaims_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserLogins\",\n                columns: table => new\n                {\n                    LoginProvider = table.Column<string>(nullable: false),\n                    ProviderKey = table.Column<string>(nullable: false),\n                    ProviderDisplayName = table.Column<string>(nullable: true),\n                    UserId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserLogins\", x => new { x.LoginProvider, x.ProviderKey });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserLogins_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserRoles\",\n                columns: table => new\n                {\n                    UserId = table.Column<int>(nullable: false),\n                    RoleId = table.Column<int>(nullable: false),\n                    UserId1 = table.Column<int>(nullable: true),\n                    RoleId1 = table.Column<int>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserRoles\", x => new { x.UserId, x.RoleId });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetRoles_RoleId\",\n                        column: x => x.RoleId,\n                        principalTable: \"AspNetRoles\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetRoles_RoleId1\",\n                        column: x => x.RoleId1,\n                        principalTable: \"AspNetRoles\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Restrict);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetUsers_UserId1\",\n                        column: x => x.UserId1,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Restrict);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserTokens\",\n                columns: table => new\n                {\n                    UserId = table.Column<int>(nullable: false),\n                    LoginProvider = table.Column<string>(nullable: false),\n                    Name = table.Column<string>(nullable: false),\n                    Value = table.Column<string>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserTokens\", x => new { x.UserId, x.LoginProvider, x.Name });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserTokens_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetRoleClaims_RoleId\",\n                table: \"AspNetRoleClaims\",\n                column: \"RoleId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"RoleNameIndex\",\n                table: \"AspNetRoles\",\n                column: \"NormalizedName\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserClaims_UserId\",\n                table: \"AspNetUserClaims\",\n                column: \"UserId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserLogins_UserId\",\n                table: \"AspNetUserLogins\",\n                column: \"UserId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserRoles_RoleId\",\n                table: \"AspNetUserRoles\",\n                column: \"RoleId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserRoles_RoleId1\",\n                table: \"AspNetUserRoles\",\n                column: \"RoleId1\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserRoles_UserId1\",\n                table: \"AspNetUserRoles\",\n                column: \"UserId1\");\n\n            migrationBuilder.CreateIndex(\n                name: \"EmailIndex\",\n                table: \"AspNetUsers\",\n                column: \"NormalizedEmail\");\n\n            migrationBuilder.CreateIndex(\n                name: \"UserNameIndex\",\n                table: \"AspNetUsers\",\n                column: \"NormalizedUserName\",\n                unique: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"AspNetRoleClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserLogins\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserRoles\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserTokens\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetRoles\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUsers\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/20210808045732_addQuestion.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Blog.IdentityServer.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    [Migration(\"20210808045732_addQuestion\")]\n    partial class addQuestion\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationRole\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"CreateBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"CreateId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"CreateTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"IsDeleted\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"ModifyBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"ModifyId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"ModifyTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<int>(\"OrderSort\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUser\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessFailedCount\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Email\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"FirstQuestion\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"LockoutEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LoginName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"PhoneNumber\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"RealName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"SecondQuestion\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"SecurityStamp\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"addr\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"age\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"birth\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<int>(\"sex\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"tdIsDelete\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"RoleId1\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"UserId1\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.HasIndex(\"RoleId1\");\n\n                    b.HasIndex(\"UserId1\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderKey\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderDisplayName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Value\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", \"Role\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"RoleId1\");\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", \"User\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"UserId1\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/20210808045732_addQuestion.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql\n{\n    public partial class addQuestion : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<string>(\n                name: \"FirstQuestion\",\n                table: \"AspNetUsers\",\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"SecondQuestion\",\n                table: \"AspNetUsers\",\n                nullable: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"FirstQuestion\",\n                table: \"AspNetUsers\");\n\n            migrationBuilder.DropColumn(\n                name: \"SecondQuestion\",\n                table: \"AspNetUsers\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/ApplicationDbContextModelSnapshot.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Blog.IdentityServer.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    partial class ApplicationDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationRole\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"CreateBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"CreateId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"CreateTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"IsDeleted\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"ModifyBy\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int?>(\"ModifyId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime?>(\"ModifyTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<int>(\"OrderSort\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUser\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessFailedCount\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Email\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"FirstQuestion\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"LockoutEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LoginName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"PhoneNumber\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"RealName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"SecondQuestion\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"SecurityStamp\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasColumnType(\"varchar(256) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"addr\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"age\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"birth\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<int>(\"sex\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"tdIsDelete\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"RoleId1\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int?>(\"UserId1\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.HasIndex(\"RoleId1\");\n\n                    b.HasIndex(\"UserId1\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"RoleId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderKey\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"ProviderDisplayName\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.Property<int>(\"UserId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"varchar(255) CHARACTER SET utf8mb4\");\n\n                    b.Property<string>(\"Value\")\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Blog.IdentityServer.Models.ApplicationUserRole\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", \"Role\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"RoleId1\");\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", \"User\")\n                        .WithMany(\"UserRoles\")\n                        .HasForeignKey(\"UserId1\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<int>\", b =>\n                {\n                    b.HasOne(\"Blog.IdentityServer.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/ConfigurationDb/20200509165153_InitialIdentityServerConfigurationDbMigrationMysql.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    [Migration(\"20200509165153_InitialIdentityServerConfigurationDbMigrationMysql\")]\n    partial class InitialIdentityServerConfigurationDbMigrationMysql\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.3\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(150) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiScope\", \"ApiScope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/ConfigurationDb/20200509165153_InitialIdentityServerConfigurationDbMigrationMysql.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.ConfigurationDb\n{\n    public partial class InitialIdentityServerConfigurationDbMigrationMysql : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"ApiResources\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Enabled = table.Column<bool>(nullable: false),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    LastAccessed = table.Column<DateTime>(nullable: true),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResources\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Clients\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Enabled = table.Column<bool>(nullable: false),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    ProtocolType = table.Column<string>(maxLength: 200, nullable: false),\n                    RequireClientSecret = table.Column<bool>(nullable: false),\n                    ClientName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    ClientUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    LogoUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    RequireConsent = table.Column<bool>(nullable: false),\n                    AllowRememberConsent = table.Column<bool>(nullable: false),\n                    AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(nullable: false),\n                    RequirePkce = table.Column<bool>(nullable: false),\n                    AllowPlainTextPkce = table.Column<bool>(nullable: false),\n                    AllowAccessTokensViaBrowser = table.Column<bool>(nullable: false),\n                    FrontChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    FrontChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                    BackChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    BackChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                    AllowOfflineAccess = table.Column<bool>(nullable: false),\n                    IdentityTokenLifetime = table.Column<int>(nullable: false),\n                    AccessTokenLifetime = table.Column<int>(nullable: false),\n                    AuthorizationCodeLifetime = table.Column<int>(nullable: false),\n                    ConsentLifetime = table.Column<int>(nullable: true),\n                    AbsoluteRefreshTokenLifetime = table.Column<int>(nullable: false),\n                    SlidingRefreshTokenLifetime = table.Column<int>(nullable: false),\n                    RefreshTokenUsage = table.Column<int>(nullable: false),\n                    UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(nullable: false),\n                    RefreshTokenExpiration = table.Column<int>(nullable: false),\n                    AccessTokenType = table.Column<int>(nullable: false),\n                    EnableLocalLogin = table.Column<bool>(nullable: false),\n                    IncludeJwtId = table.Column<bool>(nullable: false),\n                    AlwaysSendClientClaims = table.Column<bool>(nullable: false),\n                    ClientClaimsPrefix = table.Column<string>(maxLength: 200, nullable: true),\n                    PairWiseSubjectSalt = table.Column<string>(maxLength: 200, nullable: true),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    LastAccessed = table.Column<DateTime>(nullable: true),\n                    UserSsoLifetime = table.Column<int>(nullable: true),\n                    UserCodeType = table.Column<string>(maxLength: 100, nullable: true),\n                    DeviceCodeLifetime = table.Column<int>(nullable: false),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Clients\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityResources\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Enabled = table.Column<bool>(nullable: false),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Required = table.Column<bool>(nullable: false),\n                    Emphasize = table.Column<bool>(nullable: false),\n                    ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityResources\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiClaims_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiProperties_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Required = table.Column<bool>(nullable: false),\n                    Emphasize = table.Column<bool>(nullable: false),\n                    ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiScopes_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Value = table.Column<string>(maxLength: 4000, nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiSecrets_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 250, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientClaims_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientCorsOrigins\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Origin = table.Column<string>(maxLength: 150, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientCorsOrigins\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientCorsOrigins_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientGrantTypes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    GrantType = table.Column<string>(maxLength: 250, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientGrantTypes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientGrantTypes_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientIdPRestrictions\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Provider = table.Column<string>(maxLength: 200, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientIdPRestrictions\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientIdPRestrictions_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientPostLogoutRedirectUris\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    PostLogoutRedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientPostLogoutRedirectUris\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientPostLogoutRedirectUris_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientProperties_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientRedirectUris\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    RedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientRedirectUris\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientRedirectUris_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Scope = table.Column<string>(maxLength: 200, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientScopes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientScopes_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Description = table.Column<string>(maxLength: 2000, nullable: true),\n                    Value = table.Column<string>(maxLength: 4000, nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientSecrets_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    IdentityResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityClaims_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    IdentityResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityProperties_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopeClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    ApiScopeId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopeClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiScopeClaims_ApiScopes_ApiScopeId\",\n                        column: x => x.ApiScopeId,\n                        principalTable: \"ApiScopes\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiClaims_ApiResourceId\",\n                table: \"ApiClaims\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiProperties_ApiResourceId\",\n                table: \"ApiProperties\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResources_Name\",\n                table: \"ApiResources\",\n                column: \"Name\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeClaims_ApiScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ApiScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopes_ApiResourceId\",\n                table: \"ApiScopes\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopes_Name\",\n                table: \"ApiScopes\",\n                column: \"Name\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiSecrets_ApiResourceId\",\n                table: \"ApiSecrets\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientClaims_ClientId\",\n                table: \"ClientClaims\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientCorsOrigins_ClientId\",\n                table: \"ClientCorsOrigins\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientGrantTypes_ClientId\",\n                table: \"ClientGrantTypes\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientIdPRestrictions_ClientId\",\n                table: \"ClientIdPRestrictions\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientPostLogoutRedirectUris_ClientId\",\n                table: \"ClientPostLogoutRedirectUris\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientProperties_ClientId\",\n                table: \"ClientProperties\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientRedirectUris_ClientId\",\n                table: \"ClientRedirectUris\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Clients_ClientId\",\n                table: \"Clients\",\n                column: \"ClientId\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientScopes_ClientId\",\n                table: \"ClientScopes\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientSecrets_ClientId\",\n                table: \"ClientSecrets\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityClaims_IdentityResourceId\",\n                table: \"IdentityClaims\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityProperties_IdentityResourceId\",\n                table: \"IdentityProperties\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityResources_Name\",\n                table: \"IdentityResources\",\n                column: \"Name\",\n                unique: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"ApiClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopeClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientCorsOrigins\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientGrantTypes\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientIdPRestrictions\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientPostLogoutRedirectUris\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientRedirectUris\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"Clients\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityResources\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResources\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/ConfigurationDb/20200715033226_InitConfigurationDbV4.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    [Migration(\"20200715033226_InitConfigurationDbV4\")]\n    partial class InitConfigurationDbV4\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequireRequestObject\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(150) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/ConfigurationDb/20200715033226_InitConfigurationDbV4.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.ConfigurationDb\n{\n    public partial class InitConfigurationDbV4 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiClaims_ApiResources_ApiResourceId\",\n                table: \"ApiClaims\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiProperties_ApiResources_ApiResourceId\",\n                table: \"ApiProperties\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiScopeClaims_ApiScopes_ApiScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiScopes_ApiResources_ApiResourceId\",\n                table: \"ApiScopes\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_IdentityProperties_IdentityResources_IdentityResourceId\",\n                table: \"IdentityProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityClaims\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_ApiScopes_ApiResourceId\",\n                table: \"ApiScopes\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_ApiScopeClaims_ApiScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_IdentityProperties\",\n                table: \"IdentityProperties\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_ApiProperties\",\n                table: \"ApiProperties\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_ApiClaims\",\n                table: \"ApiClaims\");\n\n            migrationBuilder.DropColumn(\n                name: \"ApiResourceId\",\n                table: \"ApiScopes\");\n\n            migrationBuilder.DropColumn(\n                name: \"ApiScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.RenameTable(\n                name: \"IdentityProperties\",\n                newName: \"IdentityResourceProperties\");\n\n            migrationBuilder.RenameTable(\n                name: \"ApiProperties\",\n                newName: \"ApiResourceProperties\");\n\n            migrationBuilder.RenameTable(\n                name: \"ApiClaims\",\n                newName: \"ApiResourceClaims\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_IdentityProperties_IdentityResourceId\",\n                table: \"IdentityResourceProperties\",\n                newName: \"IX_IdentityResourceProperties_IdentityResourceId\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_ApiProperties_ApiResourceId\",\n                table: \"ApiResourceProperties\",\n                newName: \"IX_ApiResourceProperties_ApiResourceId\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_ApiClaims_ApiResourceId\",\n                table: \"ApiResourceClaims\",\n                newName: \"IX_ApiResourceClaims_ApiResourceId\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"AllowedIdentityTokenSigningAlgorithms\",\n                table: \"Clients\",\n                maxLength: 100,\n                nullable: true);\n\n            migrationBuilder.AddColumn<bool>(\n                name: \"RequireRequestObject\",\n                table: \"Clients\",\n                nullable: false,\n                defaultValue: false);\n\n            migrationBuilder.AddColumn<bool>(\n                name: \"Enabled\",\n                table: \"ApiScopes\",\n                nullable: false,\n                defaultValue: false);\n\n            migrationBuilder.AddColumn<int>(\n                name: \"ScopeId\",\n                table: \"ApiScopeClaims\",\n                nullable: false,\n                defaultValue: 0);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"AllowedAccessTokenSigningAlgorithms\",\n                table: \"ApiResources\",\n                maxLength: 100,\n                nullable: true);\n\n            migrationBuilder.AddColumn<bool>(\n                name: \"ShowInDiscoveryDocument\",\n                table: \"ApiResources\",\n                nullable: false,\n                defaultValue: false);\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_IdentityResourceProperties\",\n                table: \"IdentityResourceProperties\",\n                column: \"Id\");\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_ApiResourceProperties\",\n                table: \"ApiResourceProperties\",\n                column: \"Id\");\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_ApiResourceClaims\",\n                table: \"ApiResourceClaims\",\n                column: \"Id\");\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Scope = table.Column<string>(maxLength: 200, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceScopes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceScopes_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Value = table.Column<string>(maxLength: 4000, nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceSecrets_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopeProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ScopeId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopeProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiScopeProperties_ApiScopes_ScopeId\",\n                        column: x => x.ScopeId,\n                        principalTable: \"ApiScopes\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityResourceClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    IdentityResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityResourceClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityResourceClaims_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeClaims_ScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceScopes_ApiResourceId\",\n                table: \"ApiResourceScopes\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceSecrets_ApiResourceId\",\n                table: \"ApiResourceSecrets\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeProperties_ScopeId\",\n                table: \"ApiScopeProperties\",\n                column: \"ScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityResourceClaims_IdentityResourceId\",\n                table: \"IdentityResourceClaims\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiResourceClaims_ApiResources_ApiResourceId\",\n                table: \"ApiResourceClaims\",\n                column: \"ApiResourceId\",\n                principalTable: \"ApiResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiResourceProperties_ApiResources_ApiResourceId\",\n                table: \"ApiResourceProperties\",\n                column: \"ApiResourceId\",\n                principalTable: \"ApiResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiScopeClaims_ApiScopes_ScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ScopeId\",\n                principalTable: \"ApiScopes\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_IdentityResourceProperties_IdentityResources_IdentityResourc~\",\n                table: \"IdentityResourceProperties\",\n                column: \"IdentityResourceId\",\n                principalTable: \"IdentityResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiResourceClaims_ApiResources_ApiResourceId\",\n                table: \"ApiResourceClaims\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiResourceProperties_ApiResources_ApiResourceId\",\n                table: \"ApiResourceProperties\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_ApiScopeClaims_ApiScopes_ScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.DropForeignKey(\n                name: \"FK_IdentityResourceProperties_IdentityResources_IdentityResourc~\",\n                table: \"IdentityResourceProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResourceScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResourceSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopeProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityResourceClaims\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_ApiScopeClaims_ScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_IdentityResourceProperties\",\n                table: \"IdentityResourceProperties\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_ApiResourceProperties\",\n                table: \"ApiResourceProperties\");\n\n            migrationBuilder.DropPrimaryKey(\n                name: \"PK_ApiResourceClaims\",\n                table: \"ApiResourceClaims\");\n\n            migrationBuilder.DropColumn(\n                name: \"AllowedIdentityTokenSigningAlgorithms\",\n                table: \"Clients\");\n\n            migrationBuilder.DropColumn(\n                name: \"RequireRequestObject\",\n                table: \"Clients\");\n\n            migrationBuilder.DropColumn(\n                name: \"Enabled\",\n                table: \"ApiScopes\");\n\n            migrationBuilder.DropColumn(\n                name: \"ScopeId\",\n                table: \"ApiScopeClaims\");\n\n            migrationBuilder.DropColumn(\n                name: \"AllowedAccessTokenSigningAlgorithms\",\n                table: \"ApiResources\");\n\n            migrationBuilder.DropColumn(\n                name: \"ShowInDiscoveryDocument\",\n                table: \"ApiResources\");\n\n            migrationBuilder.RenameTable(\n                name: \"IdentityResourceProperties\",\n                newName: \"IdentityProperties\");\n\n            migrationBuilder.RenameTable(\n                name: \"ApiResourceProperties\",\n                newName: \"ApiProperties\");\n\n            migrationBuilder.RenameTable(\n                name: \"ApiResourceClaims\",\n                newName: \"ApiClaims\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_IdentityResourceProperties_IdentityResourceId\",\n                table: \"IdentityProperties\",\n                newName: \"IX_IdentityProperties_IdentityResourceId\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_ApiResourceProperties_ApiResourceId\",\n                table: \"ApiProperties\",\n                newName: \"IX_ApiProperties_ApiResourceId\");\n\n            migrationBuilder.RenameIndex(\n                name: \"IX_ApiResourceClaims_ApiResourceId\",\n                table: \"ApiClaims\",\n                newName: \"IX_ApiClaims_ApiResourceId\");\n\n            migrationBuilder.AddColumn<int>(\n                name: \"ApiResourceId\",\n                table: \"ApiScopes\",\n                type: \"int\",\n                nullable: false,\n                defaultValue: 0);\n\n            migrationBuilder.AddColumn<int>(\n                name: \"ApiScopeId\",\n                table: \"ApiScopeClaims\",\n                type: \"int\",\n                nullable: false,\n                defaultValue: 0);\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_IdentityProperties\",\n                table: \"IdentityProperties\",\n                column: \"Id\");\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_ApiProperties\",\n                table: \"ApiProperties\",\n                column: \"Id\");\n\n            migrationBuilder.AddPrimaryKey(\n                name: \"PK_ApiClaims\",\n                table: \"ApiClaims\",\n                column: \"Id\");\n\n            migrationBuilder.CreateTable(\n                name: \"ApiSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(type: \"int\", nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    ApiResourceId = table.Column<int>(type: \"int\", nullable: false),\n                    Created = table.Column<DateTime>(type: \"datetime(6)\", nullable: false),\n                    Description = table.Column<string>(type: \"varchar(1000) CHARACTER SET utf8mb4\", maxLength: 1000, nullable: true),\n                    Expiration = table.Column<DateTime>(type: \"datetime(6)\", nullable: true),\n                    Type = table.Column<string>(type: \"varchar(250) CHARACTER SET utf8mb4\", maxLength: 250, nullable: false),\n                    Value = table.Column<string>(type: \"longtext CHARACTER SET utf8mb4\", maxLength: 4000, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiSecrets_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(type: \"int\", nullable: false)\n                        .Annotation(\"MySql:ValueGenerationStrategy\", MySqlValueGenerationStrategy.IdentityColumn),\n                    IdentityResourceId = table.Column<int>(type: \"int\", nullable: false),\n                    Type = table.Column<string>(type: \"varchar(200) CHARACTER SET utf8mb4\", maxLength: 200, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityClaims_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopes_ApiResourceId\",\n                table: \"ApiScopes\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeClaims_ApiScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ApiScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiSecrets_ApiResourceId\",\n                table: \"ApiSecrets\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityClaims_IdentityResourceId\",\n                table: \"IdentityClaims\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiClaims_ApiResources_ApiResourceId\",\n                table: \"ApiClaims\",\n                column: \"ApiResourceId\",\n                principalTable: \"ApiResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiProperties_ApiResources_ApiResourceId\",\n                table: \"ApiProperties\",\n                column: \"ApiResourceId\",\n                principalTable: \"ApiResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiScopeClaims_ApiScopes_ApiScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ApiScopeId\",\n                principalTable: \"ApiScopes\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_ApiScopes_ApiResources_ApiResourceId\",\n                table: \"ApiScopes\",\n                column: \"ApiResourceId\",\n                principalTable: \"ApiResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_IdentityProperties_IdentityResources_IdentityResourceId\",\n                table: \"IdentityProperties\",\n                column: \"IdentityResourceId\",\n                principalTable: \"IdentityResources\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/ConfigurationDb/ConfigurationDbContextModelSnapshot.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    partial class ConfigurationDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"RequireRequestObject\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(150) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(1000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"tinyint(1)\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(250) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(2000) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer4.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/PersistedGrantDb/20200509165052_InitialIdentityServerPersistedGrantDbMigrationMysql.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    [Migration(\"20200509165052_InitialIdentityServerPersistedGrantDbMigrationMysql\")]\n    partial class InitialIdentityServerPersistedGrantDbMigrationMysql\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.3\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(50) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/PersistedGrantDb/20200509165052_InitialIdentityServerPersistedGrantDbMigrationMysql.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.PersistedGrantDb\n{\n    public partial class InitialIdentityServerPersistedGrantDbMigrationMysql : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"DeviceCodes\",\n                columns: table => new\n                {\n                    UserCode = table.Column<string>(maxLength: 200, nullable: false),\n                    DeviceCode = table.Column<string>(maxLength: 200, nullable: false),\n                    SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    CreationTime = table.Column<DateTime>(nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: false),\n                    Data = table.Column<string>(maxLength: 50000, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_DeviceCodes\", x => x.UserCode);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"PersistedGrants\",\n                columns: table => new\n                {\n                    Key = table.Column<string>(maxLength: 200, nullable: false),\n                    Type = table.Column<string>(maxLength: 50, nullable: false),\n                    SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    CreationTime = table.Column<DateTime>(nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Data = table.Column<string>(maxLength: 50000, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_PersistedGrants\", x => x.Key);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_DeviceCodes_DeviceCode\",\n                table: \"DeviceCodes\",\n                column: \"DeviceCode\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_DeviceCodes_Expiration\",\n                table: \"DeviceCodes\",\n                column: \"Expiration\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_Expiration\",\n                table: \"PersistedGrants\",\n                column: \"Expiration\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_SubjectId_ClientId_Type\",\n                table: \"PersistedGrants\",\n                columns: new[] { \"SubjectId\", \"ClientId\", \"Type\" });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"DeviceCodes\");\n\n            migrationBuilder.DropTable(\n                name: \"PersistedGrants\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/PersistedGrantDb/20200715032957_InitPersistedGrantDbV4.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    [Migration(\"20200715032957_InitPersistedGrantDbV4\")]\n    partial class InitPersistedGrantDbV4\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"ConsumedTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(50) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/PersistedGrantDb/20200715032957_InitPersistedGrantDbV4.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.PersistedGrantDb\n{\n    public partial class InitPersistedGrantDbV4 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"ConsumedTime\",\n                table: \"PersistedGrants\",\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Description\",\n                table: \"PersistedGrants\",\n                maxLength: 200,\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"SessionId\",\n                table: \"PersistedGrants\",\n                maxLength: 100,\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Description\",\n                table: \"DeviceCodes\",\n                maxLength: 200,\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"SessionId\",\n                table: \"DeviceCodes\",\n                maxLength: 100,\n                nullable: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_SubjectId_SessionId_Type\",\n                table: \"PersistedGrants\",\n                columns: new[] { \"SubjectId\", \"SessionId\", \"Type\" });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropIndex(\n                name: \"IX_PersistedGrants_SubjectId_SessionId_Type\",\n                table: \"PersistedGrants\");\n\n            migrationBuilder.DropColumn(\n                name: \"ConsumedTime\",\n                table: \"PersistedGrants\");\n\n            migrationBuilder.DropColumn(\n                name: \"Description\",\n                table: \"PersistedGrants\");\n\n            migrationBuilder.DropColumn(\n                name: \"SessionId\",\n                table: \"PersistedGrants\");\n\n            migrationBuilder.DropColumn(\n                name: \"Description\",\n                table: \"DeviceCodes\");\n\n            migrationBuilder.DropColumn(\n                name: \"SessionId\",\n                table: \"DeviceCodes\");\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Data/MigrationsMySql/IdentityServer/PersistedGrantDb/PersistedGrantDbContextModelSnapshot.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\nnamespace Blog.IdentityServer.Data.MigrationsMySql.IdentityServer.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    partial class PersistedGrantDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 64);\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer4.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"ConsumedTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"longtext CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime(6)\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"varchar(100) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"varchar(200) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"varchar(50) CHARACTER SET utf8mb4\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Dockerfile",
    "content": "FROM swr.cn-south-1.myhuaweicloud.com/mcr/aspnet:3.1-alpine\nWORKDIR /app\nCOPY . . \nEXPOSE 5004 \nENTRYPOINT [\"dotnet\", \"Blog.IdentityServer.dll\",\"-b\",\"0.0.0.0\"]"
  },
  {
    "path": "Blog.IdentityServer/Extensions/GrantTypeCustom.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Extensions\n{\n    /// <summary>\n    /// 自定义授权类型\n    /// </summary>\n    public class GrantTypeCustom\n    {\n        /// <summary>\n        /// GrantType - 自定义微信授权\n        /// </summary>\n        public const string ResourceWeixinOpen = \"weixinopen\";\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Extensions/IpLimitMildd.cs",
    "content": "﻿using AspNetCoreRateLimit;\nusing Microsoft.AspNetCore.Builder;\nusing System;\n\nnamespace Blog.IdentityServer.Extensions\n{\n    public static class IpLimitMildd\n    {\n        public static void UseIpLimitMildd(this IApplicationBuilder app)\n        {\n            if (app == null) throw new ArgumentNullException(nameof(app));\n\n            try\n            {\n                app.UseIpRateLimiting();\n            }\n            catch (Exception e)\n            {\n                throw;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Extensions/IpPolicyRateLimitSetup.cs",
    "content": "﻿using AspNetCoreRateLimit;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing System;\n\nnamespace Blog.IdentityServer.Extensions\n{\n    public static class IpPolicyRateLimitSetup\n    {\n        public static void AddIpPolicyRateLimitSetup(this IServiceCollection services, IConfiguration Configuration)\n        {\n            if (services == null) throw new ArgumentNullException(nameof(services));\n\n            // needed to store rate limit counters and ip rules\n            services.AddMemoryCache();\n            //load general configuration from appsettings.json\n            services.Configure<IpRateLimitOptions>(Configuration.GetSection(\"IpRateLimiting\"));\n            // inject counter and rules stores\n            services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();\n            services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();\n\n            // inject counter and rules distributed cache stores\n            //services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();\n            //services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();\n\n            // the clientId/clientIp resolvers use it.\n            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();\n            // configuration (resolvers, counter key builders)\n            services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Extensions/ResourceOwnerPasswordValidator.cs",
    "content": "﻿using Blog.IdentityServer.Models;\nusing IdentityServer4.Validation;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Extensions\n{\n    public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator\n    {\n        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n        {\n            try\n            {\n                var userName = context.UserName;\n                var password = context.Password;\n\n                //验证用户,这么可以到数据库里面验证用户名和密码是否正确\n                var claimList = await ValidateUserAsync(userName, password);\n\n                // 验证账号\n                context.Result = new GrantValidationResult\n                (\n                    subject: userName,\n                    authenticationMethod: \"custom\",\n                    claims: claimList.ToArray()\n                 );\n            }\n            catch (Exception ex)\n            {\n                //验证异常结果\n                context.Result = new GrantValidationResult()\n                {\n                    IsError = true,\n                    Error = ex.Message\n                };\n            }\n        }\n\n        /// <summary>\n        /// 验证用户\n        /// </summary>\n        /// <param name=\"loginName\"></param>\n        /// <param name=\"password\"></param>\n        /// <returns></returns>\n        private async Task<List<Claim>> ValidateUserAsync(string loginName, string password)\n        {\n            var user = new ApplicationUser();\n            \n            await Task.Run(() =>\n            {\n              // TODO\n            });\n\n            if (user == null)\n                throw new Exception(\"登录失败，用户名和密码不正确\");\n\n            return new List<Claim>()\n            {\n                new Claim(ClaimTypes.Name, $\"{loginName}\"),\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Extensions/WeiXinOpenGrantValidator.cs",
    "content": "﻿using Blog.IdentityServer.Models;\nusing IdentityServer4.Validation;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Extensions\n{\n    public class WeiXinOpenGrantValidator : IExtensionGrantValidator\n    {\n        public string GrantType => GrantTypeCustom.ResourceWeixinOpen;\n\n        public async Task ValidateAsync(ExtensionGrantValidationContext context)\n        {\n            try\n            {\n                // 参数获取\n                var openId = context.Request.Raw[\"openid\"];\n                var unionId = context.Request.Raw[\"unionid\"];\n                var userName = context.Request.Raw[\"user_name\"];\n\n                // 通过openId和unionId 参数来进行数据库的相关验证\n                var claimList = await ValidateUserAsync(openId, unionId);\n\n                //授权通过返回\n                context.Result = new GrantValidationResult\n                (\n                    subject: openId,\n                    authenticationMethod: \"custom\",\n                    claims: claimList.ToArray()\n                );\n            }\n            catch (Exception ex)\n            {\n                context.Result = new GrantValidationResult()\n                {\n                    IsError = true,\n                    Error = ex.Message\n                };\n            }\n        }\n\n        /// <summary>\n        /// 验证用户\n        /// </summary>\n        /// <param name=\"loginName\"></param>\n        /// <param name=\"password\"></param>\n        /// <returns></returns>\n        private async Task<List<Claim>> ValidateUserAsync(string openId, string unionId)\n        {\n            // 数据库查询\n            var user = new ApplicationUser();\n\n            await Task.Run(() =>\n            {\n                // TODO\n            });\n\n            if (user == null)\n            {\n                //注册用户\n            }\n\n            return new List<Claim>()\n            {\n                new Claim(ClaimTypes.Name, $\"{openId}\"),\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/Appsettings.cs",
    "content": "﻿using Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.Configuration.Json;\nusing System;\nusing System.IO;\n\nnamespace Blog.Core.Common\n{\n    /// <summary>\n    /// appsettings.json操作类\n    /// </summary>\n    public class Appsettings\n    {\n        static IConfiguration Configuration { get; set; }\n\n        //static Appsettings()\n        //{\n        //    //ReloadOnChange = true 当appsettings.json被修改时重新加载\n        //    Configuration = new ConfigurationBuilder()\n        //    .Add(new JsonConfigurationSource { Path = \"appsettings.json\", ReloadOnChange = true })//请注意要把当前appsetting.json 文件->右键->属性->复制到输出目录->始终复制\n        //    .Build();\n        //}\n\n        static Appsettings()\n        {\n            string Path = \"appsettings.json\";\n            {\n                //如果你把配置文件 是 根据环境变量来分开了，可以这样写\n                //Path = $\"appsettings.{Environment.GetEnvironmentVariable(\"ASPNETCORE_ENVIRONMENT\")}.json\";\n            }\n\n            //Configuration = new ConfigurationBuilder()\n            //.Add(new JsonConfigurationSource { Path = Path, ReloadOnChange = true })//请注意要把当前appsetting.json 文件->右键->属性->复制到输出目录->始终复制\n            //.Build();\n\n            Configuration = new ConfigurationBuilder()\n               .SetBasePath(Directory.GetCurrentDirectory())\n               .Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话，可以直接读目录里的json文件，而不是 bin 文件夹下的，所以不用修改复制属性\n               .Build();\n\n\n        }\n\n        /// <summary>\n        /// 封装要操作的字符\n        /// </summary>\n        /// <param name=\"sections\"></param>\n        /// <returns></returns>\n        public static string app(params string[] sections)\n        {\n            try\n            {\n                var val = string.Empty;\n                for (int i = 0; i < sections.Length; i++)\n                {\n                    val += sections[i] + \":\";\n                }\n\n                return Configuration[val.TrimEnd(':')];\n            }\n            catch (Exception)\n            {\n                return \"\";\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/FileHelper.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Text;\n\nnamespace Blog.Core.Common.Helper\n{\n    public class FileHelper : IDisposable\n    {\n\n        private bool _alreadyDispose = false;\n\n        #region 构造函数\n        public FileHelper()\n        {\n            //\n            // TODO: 在此处添加构造函数逻辑\n            //\n        }\n        ~FileHelper()\n        {\n            Dispose(); ;\n        }\n\n        protected virtual void Dispose(bool isDisposing)\n        {\n            if (_alreadyDispose) return;\n            _alreadyDispose = true;\n        }\n        #endregion\n\n        #region IDisposable 成员\n\n        public void Dispose()\n        {\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region 取得文件后缀名\n        /****************************************\n          * 函数名称：GetPostfixStr\n          * 功能说明：取得文件后缀名\n          * 参     数：filename:文件名称\n          * 调用示列：\n          *            string filename = \"aaa.aspx\";        \n          *            string s = EC.FileObj.GetPostfixStr(filename);         \n         *****************************************/\n        /// <summary>\n        /// 取后缀名\n        /// </summary>\n        /// <param name=\"filename\">文件名</param>\n        /// <returns>.gif|.html格式</returns>\n        public static string GetPostfixStr(string filename)\n        {\n            int start = filename.LastIndexOf(\".\");\n            int length = filename.Length;\n            string postfix = filename.Substring(start, length - start);\n            return postfix;\n        }\n        #endregion\n\n        #region 写文件\n        /****************************************\n          * 函数名称：WriteFile\n          * 功能说明：写文件,会覆盖掉以前的内容\n          * 参     数：Path:文件路径,Strings:文本内容\n          * 调用示列：\n          *            string Path = Server.MapPath(\"Default2.aspx\");       \n          *            string Strings = \"这是我写的内容啊\";\n          *            EC.FileObj.WriteFile(Path,Strings);\n         *****************************************/\n        /// <summary>\n        /// 写文件\n        /// </summary>\n        /// <param name=\"Path\">文件路径</param>\n        /// <param name=\"Strings\">文件内容</param>\n        public static void WriteFile(string Path, string Strings)\n        {\n            if (!System.IO.File.Exists(Path))\n            {\n                System.IO.FileStream f = System.IO.File.Create(Path);\n                f.Close();\n            }\n            System.IO.StreamWriter f2 = new System.IO.StreamWriter(Path, false, System.Text.Encoding.GetEncoding(\"gb2312\"));\n            f2.Write(Strings);\n            f2.Close();\n            f2.Dispose();\n        }\n\n        /// <summary>\n        /// 写文件\n        /// </summary>\n        /// <param name=\"Path\">文件路径</param>\n        /// <param name=\"Strings\">文件内容</param>\n        /// <param name=\"encode\">编码格式</param>\n        public static void WriteFile(string Path, string Strings, Encoding encode)\n        {\n            if (!System.IO.File.Exists(Path))\n            {\n                System.IO.FileStream f = System.IO.File.Create(Path);\n                f.Close();\n            }\n            System.IO.StreamWriter f2 = new System.IO.StreamWriter(Path, false, encode);\n            f2.Write(Strings);\n            f2.Close();\n            f2.Dispose();\n        }\n        #endregion\n\n        #region 读文件\n        /****************************************\n          * 函数名称：ReadFile\n          * 功能说明：读取文本内容\n          * 参     数：Path:文件路径\n          * 调用示列：\n          *            string Path = Server.MapPath(\"Default2.aspx\");       \n          *            string s = EC.FileObj.ReadFile(Path);\n         *****************************************/\n        /// <summary>\n        /// 读文件\n        /// </summary>\n        /// <param name=\"Path\">文件路径</param>\n        /// <returns></returns>\n        public static string ReadFile(string Path)\n        {\n            string s = \"\";\n            if (!System.IO.File.Exists(Path))\n                s = \"不存在相应的目录\";\n            else\n            {\n                StreamReader f2 = new StreamReader(Path, System.Text.Encoding.GetEncoding(\"gb2312\"));\n                s = f2.ReadToEnd();\n                f2.Close();\n                f2.Dispose();\n            }\n\n            return s;\n        }\n\n        /// <summary>\n        /// 读文件\n        /// </summary>\n        /// <param name=\"Path\">文件路径</param>\n        /// <param name=\"encode\">编码格式</param>\n        /// <returns></returns>\n        public static string ReadFile(string Path, Encoding encode)\n        {\n            string s = \"\";\n            if (!System.IO.File.Exists(Path))\n                s = \"不存在相应的目录\";\n            else\n            {\n                StreamReader f2 = new StreamReader(Path, encode);\n                s = f2.ReadToEnd();\n                f2.Close();\n                f2.Dispose();\n            }\n\n            return s;\n        }\n        #endregion\n\n        #region 追加文件\n        /****************************************\n          * 函数名称：FileAdd\n          * 功能说明：追加文件内容\n          * 参     数：Path:文件路径,strings:内容\n          * 调用示列：\n          *            string Path = Server.MapPath(\"Default2.aspx\");     \n          *            string Strings = \"新追加内容\";\n          *            EC.FileObj.FileAdd(Path, Strings);\n         *****************************************/\n        /// <summary>\n        /// 追加文件\n        /// </summary>\n        /// <param name=\"Path\">文件路径</param>\n        /// <param name=\"strings\">内容</param>\n        public static void FileAdd(string Path, string strings)\n        {\n            StreamWriter sw = File.AppendText(Path);\n            sw.Write(strings);\n            sw.Flush();\n            sw.Close();\n        }\n        #endregion\n\n        #region 拷贝文件\n        /****************************************\n          * 函数名称：FileCoppy\n          * 功能说明：拷贝文件\n          * 参     数：OrignFile:原始文件,NewFile:新文件路径\n          * 调用示列：\n          *            string orignFile = Server.MapPath(\"Default2.aspx\");     \n          *            string NewFile = Server.MapPath(\"Default3.aspx\");\n          *            EC.FileObj.FileCoppy(OrignFile, NewFile);\n         *****************************************/\n        /// <summary>\n        /// 拷贝文件\n        /// </summary>\n        /// <param name=\"OrignFile\">原始文件</param>\n        /// <param name=\"NewFile\">新文件路径</param>\n        public static void FileCoppy(string orignFile, string NewFile)\n        {\n            File.Copy(orignFile, NewFile, true);\n        }\n\n        #endregion\n\n        #region 删除文件\n        /****************************************\n          * 函数名称：FileDel\n          * 功能说明：删除文件\n          * 参     数：Path:文件路径\n          * 调用示列：\n          *            string Path = Server.MapPath(\"Default3.aspx\");    \n          *            EC.FileObj.FileDel(Path);\n         *****************************************/\n        /// <summary>\n        /// 删除文件\n        /// </summary>\n        /// <param name=\"Path\">路径</param>\n        public static void FileDel(string Path)\n        {\n            File.Delete(Path);\n        }\n        #endregion\n\n        #region 移动文件\n        /****************************************\n          * 函数名称：FileMove\n          * 功能说明：移动文件\n          * 参     数：OrignFile:原始路径,NewFile:新文件路径\n          * 调用示列：\n          *             string orignFile = Server.MapPath(\"../说明.txt\");    \n          *             string NewFile = Server.MapPath(\"http://www.cnblogs.com/说明.txt\");\n          *             EC.FileObj.FileMove(OrignFile, NewFile);\n         *****************************************/\n        /// <summary>\n        /// 移动文件\n        /// </summary>\n        /// <param name=\"OrignFile\">原始路径</param>\n        /// <param name=\"NewFile\">新路径</param>\n        public static void FileMove(string orignFile, string NewFile)\n        {\n            File.Move(orignFile, NewFile);\n        }\n        #endregion\n\n        #region 在当前目录下创建目录\n        /****************************************\n          * 函数名称：FolderCreate\n          * 功能说明：在当前目录下创建目录\n          * 参     数：OrignFolder:当前目录,NewFloder:新目录\n          * 调用示列：\n          *            string orignFolder = Server.MapPath(\"test/\");    \n          *            string NewFloder = \"new\";\n          *            EC.FileObj.FolderCreate(OrignFolder, NewFloder);\n         *****************************************/\n        /// <summary>\n        /// 在当前目录下创建目录\n        /// </summary>\n        /// <param name=\"OrignFolder\">当前目录</param>\n        /// <param name=\"NewFloder\">新目录</param>\n        public static void FolderCreate(string orignFolder, string NewFloder)\n        {\n            Directory.SetCurrentDirectory(orignFolder);\n            Directory.CreateDirectory(NewFloder);\n        }\n        #endregion\n\n        #region 递归删除文件夹目录及文件\n        /****************************************\n          * 函数名称：DeleteFolder\n          * 功能说明：递归删除文件夹目录及文件\n          * 参     数：dir:文件夹路径\n          * 调用示列：\n          *            string dir = Server.MapPath(\"test/\");  \n          *            EC.FileObj.DeleteFolder(dir);       \n         *****************************************/\n        /// <summary>\n        /// 递归删除文件夹目录及文件\n        /// </summary>\n        /// <param name=\"dir\"></param>\n        /// <returns></returns>\n        public static void DeleteFolder(string dir)\n        {\n            if (Directory.Exists(dir)) //如果存在这个文件夹删除之\n            {\n                foreach (string d in Directory.GetFileSystemEntries(dir))\n                {\n                    if (File.Exists(d))\n                        File.Delete(d); //直接删除其中的文件\n                    else\n                        DeleteFolder(d); //递归删除子文件夹\n                }\n                Directory.Delete(dir); //删除已空文件夹\n            }\n\n        }\n        #endregion\n\n        #region 将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。\n        /****************************************\n          * 函数名称：CopyDir\n          * 功能说明：将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。\n          * 参     数：srcPath:原始路径,aimPath:目标文件夹\n          * 调用示列：\n          *            string srcPath = Server.MapPath(\"test/\");  \n          *            string aimPath = Server.MapPath(\"test1/\");\n          *            EC.FileObj.CopyDir(srcPath,aimPath);   \n         *****************************************/\n        /// <summary>\n        /// 指定文件夹下面的所有内容copy到目标文件夹下面\n        /// </summary>\n        /// <param name=\"srcPath\">原始路径</param>\n        /// <param name=\"aimPath\">目标文件夹</param>\n        public static void CopyDir(string srcPath, string aimPath)\n        {\n            try\n            {\n                // 检查目标目录是否以目录分割字符结束如果不是则添加之\n                if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar)\n                    aimPath += Path.DirectorySeparatorChar;\n                // 判断目标目录是否存在如果不存在则新建之\n                if (!Directory.Exists(aimPath))\n                    Directory.CreateDirectory(aimPath);\n                // 得到源目录的文件列表，该里面是包含文件以及目录路径的一个数组\n                //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法\n                //string[] fileList = Directory.GetFiles(srcPath);\n                string[] fileList = Directory.GetFileSystemEntries(srcPath);\n                //遍历所有的文件和目录\n                foreach (string file in fileList)\n                {\n                    //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件\n\n                    if (Directory.Exists(file))\n                        CopyDir(file, aimPath + Path.GetFileName(file));\n                    //否则直接Copy文件\n                    else\n                        File.Copy(file, aimPath + Path.GetFileName(file), true);\n                }\n\n            }\n            catch (Exception ee)\n            {\n                throw new Exception(ee.ToString());\n            }\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/GetNetData.cs",
    "content": "﻿using System.IO;\nusing System.Net;\nusing System.Text;\n\nnamespace Blog.Core.Common.Helper\n{\n    public class GetNetData\n    {\n        public static string Get(string serviceAddress)\n        {\n\n            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);\n            request.Method = \"GET\";\n            request.ContentType = \"text/html;charset=UTF-8\";\n            HttpWebResponse response = (HttpWebResponse)request.GetResponse();\n            Stream myResponseStream = response.GetResponseStream();\n            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);\n            string retString = myStreamReader.ReadToEnd();\n            myStreamReader.Close();\n            myResponseStream.Close();\n\n            return retString;\n        }\n\n        public static string Post(string serviceAddress)\n        {\n\n            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);\n\n            request.Method = \"POST\";\n            request.ContentType = \"application/json\";\n            string strContent = @\"{ \"\"mmmm\"\": \"\"89e\"\",\"\"nnnnnn\"\": \"\"0101943\"\",\"\"kkkkkkk\"\": \"\"e8sodijf9\"\"}\";\n            using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))\n            {\n                dataStream.Write(strContent);\n                dataStream.Close();\n            }\n            HttpWebResponse response = (HttpWebResponse)request.GetResponse();\n            string encoding = response.ContentEncoding;\n            if (encoding == null || encoding.Length < 1)\n            {\n                encoding = \"UTF-8\"; //默认编码  \n            }\n            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));\n            string retString = reader.ReadToEnd();\n\n            return retString;\n\n            //解析josn\n            //JObject jo = JObject.Parse(retString);\n            //Response.Write(jo[\"message\"][\"mmmm\"].ToString());\n\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/HtmlHelper.cs",
    "content": "﻿namespace Blog.Core.Common.Helper\n{\n    public static class HtmlHelper\n    {\n        #region 去除富文本中的HTML标签\n        /// <summary>\n        /// 去除富文本中的HTML标签\n        /// </summary>\n        /// <param name=\"html\"></param>\n        /// <param name=\"length\"></param>\n        /// <returns></returns>\n        public static string ReplaceHtmlTag(string html, int length = 0)\n        {\n            string strText = System.Text.RegularExpressions.Regex.Replace(html, \"<[^>]+>\", \"\");\n            strText = System.Text.RegularExpressions.Regex.Replace(strText, \"&[^;]+;\", \"\");\n\n            if (length > 0 && strText.Length > length)\n                return strText.Substring(0, length);\n\n            return strText;\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/JsonHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace Blog.Core.Common.Helper\n{\n    public class JsonHelper\n    {\n        /// <summary>\n        /// 转换对象为JSON格式数据\n        /// </summary>\n        /// <typeparam name=\"T\">类</typeparam>\n        /// <param name=\"obj\">对象</param>\n        /// <returns>字符格式的JSON数据</returns>\n        public static string GetJSON<T>(object obj)\n        {\n            string result = String.Empty;\n            try\n            {\n                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =\n                new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));\n                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())\n                {\n                    serializer.WriteObject(ms, obj);\n                    result = System.Text.Encoding.UTF8.GetString(ms.ToArray());\n                }\n            }\n            catch (Exception ex)\n            {\n                throw ex;\n            }\n            return result;\n        }\n        /// <summary>\n        /// 转换List<T>的数据为JSON格式\n        /// </summary>\n        /// <typeparam name=\"T\">类</typeparam>\n        /// <param name=\"vals\">列表值</param>\n        /// <returns>JSON格式数据</returns>\n        public string JSON<T>(List<T> vals)\n        {\n            System.Text.StringBuilder st = new System.Text.StringBuilder();\n            try\n            {\n                System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));\n\n                foreach (T city in vals)\n                {\n                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())\n                    {\n                        s.WriteObject(ms, city);\n                        st.Append(System.Text.Encoding.UTF8.GetString(ms.ToArray()));\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                throw ex;\n            }\n\n            return st.ToString();\n        }\n        /// <summary>\n        /// JSON格式字符转换为T类型的对象\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"jsonStr\"></param>\n        /// <returns></returns>\n        public static T ParseFormByJson<T>(string jsonStr)\n        {\n            T obj = Activator.CreateInstance<T>();\n            using (System.IO.MemoryStream ms =\n            new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonStr)))\n            {\n                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =\n                new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));\n                return (T)serializer.ReadObject(ms);\n            }\n        }\n\n        public string JSON1<SendData>(List<SendData> vals)\n        {\n            System.Text.StringBuilder st = new System.Text.StringBuilder();\n            try\n            {\n                System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(SendData));\n\n                foreach (SendData city in vals)\n                {\n                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())\n                    {\n                        s.WriteObject(ms, city);\n                        st.Append(System.Text.Encoding.UTF8.GetString(ms.ToArray()));\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                throw ex;\n            }\n\n            return st.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/MD5Hepler.cs",
    "content": "﻿using System;\nusing System.Security.Cryptography;\nusing System.Text;\n\nnamespace Blog.Core.Common.Helper\n{\n    public class MD5Helper\n    {\n        /// <summary>\n        /// 16位MD5加密\n        /// </summary>\n        /// <param name=\"password\"></param>\n        /// <returns></returns>\n        public static string MD5Encrypt16(string password)\n        {\n            var md5 = new MD5CryptoServiceProvider();\n            string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);\n            t2 = t2.Replace(\"-\", string.Empty);\n            return t2;\n        }\n\n        /// <summary>\n        /// 32位MD5加密\n        /// </summary>\n        /// <param name=\"password\"></param>\n        /// <returns></returns>\n        public static string MD5Encrypt32(string password = \"\")\n        {\n            string pwd = string.Empty;\n            try\n            {\n                if (!string.IsNullOrEmpty(password) && !string.IsNullOrWhiteSpace(password))\n                {\n                    MD5 md5 = MD5.Create(); //实例化一个md5对像\n                    // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　\n                    byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));\n                    // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得\n                    foreach (var item in s)\n                    {\n                        // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 \n                        pwd = string.Concat(pwd, item.ToString(\"X2\"));\n                    }\n                }\n            }\n            catch\n            {\n                throw new Exception($\"错误的 password 字符串:【{password}】\");\n            }\n            return pwd;\n        }\n\n        /// <summary>\n        /// 64位MD5加密\n        /// </summary>\n        /// <param name=\"password\"></param>\n        /// <returns></returns>\n        public static string MD5Encrypt64(string password)\n        {\n            // 实例化一个md5对像\n            // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　\n            MD5 md5 = MD5.Create();\n            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));\n            return Convert.ToBase64String(s);\n        }\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/RecursionHelper.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\n\nnamespace Blog.Core.Common.Helper\n{\n    /// <summary>\n    /// 泛型递归求树形结构\n    /// </summary>\n    public static class RecursionHelper\n    {\n        public static void LoopToAppendChildren(List<PermissionTree> all, PermissionTree curItem, int pid, bool needbtn)\n        {\n\n            var subItems = all.Where(ee => ee.Pid == curItem.value).ToList();\n\n            var btnItems = subItems.Where(ss => ss.isbtn == true).ToList();\n            if (subItems.Count > 0)\n            {\n                curItem.btns = new List<PermissionTree>();\n                curItem.btns.AddRange(btnItems);\n            }\n            else\n            {\n                curItem.btns = null;\n            }\n\n            if (!needbtn)\n            {\n                subItems = subItems.Where(ss => ss.isbtn == false).ToList();\n            }\n            if (subItems.Count > 0)\n            {\n                curItem.children = new List<PermissionTree>();\n                curItem.children.AddRange(subItems);\n            }\n            else\n            {\n                curItem.children = null;\n            }\n\n            if (curItem.isbtn)\n            {\n                //curItem.label += \"按钮\";\n            }\n\n            foreach (var subItem in subItems)\n            {\n                if (subItem.value == pid && pid > 0)\n                {\n                    //subItem.disabled = true;//禁用当前节点\n                }\n                LoopToAppendChildren(all, subItem, pid, needbtn);\n            }\n        }\n\n\n\n        public static void LoopNaviBarAppendChildren(List<NavigationBar> all, NavigationBar curItem)\n        {\n\n            var subItems = all.Where(ee => ee.pid == curItem.id).ToList();\n\n            if (subItems.Count > 0)\n            {\n                curItem.children = new List<NavigationBar>();\n                curItem.children.AddRange(subItems);\n            }\n            else\n            {\n                curItem.children = null;\n            }\n\n\n            foreach (var subItem in subItems)\n            {\n                LoopNaviBarAppendChildren(all, subItem);\n            }\n        }\n\n\n\n        public static void LoopToAppendChildrenT<T>(List<T> all, T curItem, string parentIdName = \"Pid\", string idName = \"value\", string childrenName = \"children\")\n        {\n            var subItems = all.Where(ee => ee.GetType().GetProperty(parentIdName).GetValue(ee, null).ToString() == curItem.GetType().GetProperty(idName).GetValue(curItem, null).ToString()).ToList(); \n\n            if (subItems.Count > 0) curItem.GetType().GetField(childrenName).SetValue(curItem, subItems);\n            foreach (var subItem in subItems)\n            {\n                LoopToAppendChildrenT(all, subItem);\n            }\n        }\n    }\n\n    public class PermissionTree\n    {\n        public int value { get; set; }\n        public int Pid { get; set; }\n        public string label { get; set; }\n        public int order { get; set; }\n        public bool isbtn { get; set; }\n        public bool disabled { get; set; }\n        public List<PermissionTree> children { get; set; }\n        public List<PermissionTree> btns { get; set; }\n    }\n    public class NavigationBar\n    {\n        public int id { get; set; }\n        public int pid { get; set; }\n        public int order { get; set; }\n        public string name { get; set; }\n        public string path { get; set; }\n        public string iconCls { get; set; }\n        public NavigationBarMeta meta { get; set; }\n        public List<NavigationBar> children { get; set; }\n    }\n\n    public class NavigationBarMeta\n    {\n        public string title { get; set; }\n        public bool requireAuth { get; set; } = true;\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/SerializeHelper.cs",
    "content": "﻿using Newtonsoft.Json;\nusing System.Text;\n\nnamespace Blog.Core.Common.Helper\n{\n    public class SerializeHelper\n    {\n        /// <summary>\n        /// 序列化\n        /// </summary>\n        /// <param name=\"item\"></param>\n        /// <returns></returns>\n        public static byte[] Serialize(object item)\n        {\n            var jsonString = JsonConvert.SerializeObject(item);\n\n            return Encoding.UTF8.GetBytes(jsonString);\n        }\n        /// <summary>\n        /// 反序列化\n        /// </summary>\n        /// <typeparam name=\"TEntity\"></typeparam>\n        /// <param name=\"value\"></param>\n        /// <returns></returns>\n        public static TEntity Deserialize<TEntity>(byte[] value)\n        {\n            if (value == null)\n            {\n                return default(TEntity);\n            }\n            var jsonString = Encoding.UTF8.GetString(value);\n            return JsonConvert.DeserializeObject<TEntity>(jsonString);\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/UnicodeHelper.cs",
    "content": "﻿using System;\nusing System.Text;\nusing System.Text.RegularExpressions;\n\nnamespace Blog.Core.Common.Helper\n{\n    public static class UnicodeHelper\n    {\n        /// <summary>\n        /// 字符串转Unicode码\n        /// </summary>\n        /// <returns>The to unicode.</returns>\n        /// <param name=\"value\">Value.</param>\n        public static string StringToUnicode(string value)\n        {\n            byte[] bytes = Encoding.Unicode.GetBytes(value);\n            StringBuilder stringBuilder = new StringBuilder();\n            for (int i = 0; i < bytes.Length; i += 2)\n            {\n                // 取两个字符，每个字符都是右对齐。\n                stringBuilder.AppendFormat(\"u{0}{1}\", bytes[i + 1].ToString(\"x\").PadLeft(2, '0'), bytes[i].ToString(\"x\").PadLeft(2, '0'));\n            }\n            return stringBuilder.ToString();\n        }\n\n        /// <summary>\n        /// Unicode转字符串\n        /// </summary>\n        /// <returns>The to string.</returns>\n        /// <param name=\"unicode\">Unicode.</param>\n        public static string UnicodeToString(string unicode)\n        {\n            unicode = unicode.Replace(\"%\", \"\\\\\");\n\n            return new Regex(@\"\\\\u([0-9A-F]{4})\", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(\n                 unicode, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result(\"$1\"), 16)));\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Helper/UtilConvert.cs",
    "content": "﻿using System;\nnamespace Blog.IdentityServer\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public static class UtilConvert\n    {\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static int ObjToInt(this object thisValue)\n        {\n            int reval = 0;\n            if (thisValue == null) return 0;\n            if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return reval;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <param name=\"errorValue\"></param>\n        /// <returns></returns>\n        public static int ObjToInt(this object thisValue, int errorValue)\n        {\n            int reval = 0;\n            if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return errorValue;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static double ObjToMoney(this object thisValue)\n        {\n            double reval = 0;\n            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return 0;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <param name=\"errorValue\"></param>\n        /// <returns></returns>\n        public static double ObjToMoney(this object thisValue, double errorValue)\n        {\n            double reval = 0;\n            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return errorValue;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static string ObjToString(this object thisValue)\n        {\n            if (thisValue != null) return thisValue.ToString().Trim();\n            return \"\";\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <param name=\"errorValue\"></param>\n        /// <returns></returns>\n        public static string ObjToString(this object thisValue, string errorValue)\n        {\n            if (thisValue != null) return thisValue.ToString().Trim();\n            return errorValue;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static Decimal ObjToDecimal(this object thisValue)\n        {\n            Decimal reval = 0;\n            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return 0;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <param name=\"errorValue\"></param>\n        /// <returns></returns>\n        public static Decimal ObjToDecimal(this object thisValue, decimal errorValue)\n        {\n            Decimal reval = 0;\n            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return errorValue;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static DateTime ObjToDate(this object thisValue)\n        {\n            DateTime reval = DateTime.MinValue;\n            if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))\n            {\n                reval = Convert.ToDateTime(thisValue);\n            }\n            return reval;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <param name=\"errorValue\"></param>\n        /// <returns></returns>\n        public static DateTime ObjToDate(this object thisValue, DateTime errorValue)\n        {\n            DateTime reval = DateTime.MinValue;\n            if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return errorValue;\n        }\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"thisValue\"></param>\n        /// <returns></returns>\n        public static bool ObjToBool(this object thisValue)\n        {\n            bool reval = false;\n            if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))\n            {\n                return reval;\n            }\n            return reval;\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/InMemoryConfig.cs",
    "content": "﻿using IdentityServer4.Models;\nusing IdentityServer4.Test;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer\n{\n    public static class InMemoryConfig\n    {\n        // 这个 Authorization Server 保护了哪些 API （资源）\n        public static IEnumerable<ApiResource> GetApiResources()\n        {\n            return new[]\n            {\n                    new ApiResource(\"blog.core.api\", \"Blog.Core API\")\n                };\n        }\n        // 哪些客户端 Client（应用） 可以使用这个 Authorization Server\n        public static IEnumerable<Client> GetClients()\n        {\n            return new[]\n            {\n                    new Client\n                    {\n                        ClientId = \"blogvuejs\",//定义客户端 Id\n                        ClientSecrets = new [] { new Secret(\"secret\".Sha256()) },//Client用来获取token\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,//这里使用的是通过用户名密码和ClientCredentials来换取token的方式. ClientCredentials允许Client只使用ClientSecrets来获取token. 这比较适合那种没有用户参与的api动作\n                        AllowedScopes = new [] { \"blog.core.api\" }// 允许访问的 API 资源\n                    }\n                };\n        }\n        // 指定可以使用 Authorization Server 授权的 Users（用户）\n        public static IEnumerable<TestUser> Users()\n        {\n            return new[]\n            {\n                    new TestUser\n                    {\n                        SubjectId = \"1\",\n                        Username = \"laozhang\",\n                        Password = \"laozhang\"\n                    }\n            };\n        }\n    }\n\n}\n"
  },
  {
    "path": "Blog.IdentityServer/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 ansonzhang\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Blog.IdentityServer/Models/ApplicationRole.cs",
    "content": "﻿using Microsoft.AspNetCore.Identity;\nusing System;\nusing System.Collections.Generic;\n\nnamespace Blog.IdentityServer.Models\n{\n    // Add profile data for application roles by adding properties to the ApplicationRole class\n    public class ApplicationRole : IdentityRole<int>\n    {\n\n        public bool IsDeleted { get; set; }\n        public string Description { get; set; }\n        /// <summary>\n        ///排序\n        /// </summary>\n        public int OrderSort { get; set; }\n        /// <summary>\n        /// 是否激活\n        /// </summary>\n        public bool Enabled { get; set; }\n        /// <summary>\n        /// 创建ID\n        /// </summary>\n        public int? CreateId { get; set; }\n        /// <summary>\n        /// 创建者\n        /// </summary>\n        public string CreateBy { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime? CreateTime { get; set; } = DateTime.Now;\n        /// <summary>\n        /// 修改ID\n        /// </summary>\n        public int? ModifyId { get; set; }\n        /// <summary>\n        /// 修改者\n        /// </summary>\n        public string ModifyBy { get; set; }\n        /// <summary>\n        /// 修改时间\n        /// </summary>\n        public DateTime? ModifyTime { get; set; } = DateTime.Now;\n        public ICollection<ApplicationUserRole> UserRoles { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/ApplicationUser.cs",
    "content": "﻿using Microsoft.AspNetCore.Identity;\nusing System;\nusing System.Collections.Generic;\n\nnamespace Blog.IdentityServer.Models\n{\n    // Add profile data for application users by adding properties to the ApplicationUser class\n    public class ApplicationUser : IdentityUser<int>\n    {\n\n        public string LoginName { get; set; }\n\n        public string RealName { get; set; }\n\n        public int sex { get; set; } = 0;\n\n        public int age { get; set; }\n\n        public DateTime birth { get; set; } = DateTime.Now;\n\n        public string addr { get; set; }\n        public string FirstQuestion { get; set; }\n        public string SecondQuestion { get; set; }\n\n        public bool tdIsDelete { get; set; }\n\n        public ICollection<ApplicationUserRole> UserRoles { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/ApplicationUserRole.cs",
    "content": "﻿using Microsoft.AspNetCore.Identity;\n\nnamespace Blog.IdentityServer.Models\n{\n    public class ApplicationUserRole : IdentityUserRole<int>\n    {\n        public virtual ApplicationUser User { get; set; }\n        public virtual ApplicationRole Role { get; set; }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Models/Bak/Role.cs",
    "content": "﻿using System;\n\nnamespace Blog.IdentityServer.Models\n{\n    /// <summary>\n    /// 角色表\n    /// </summary>\n    public class Role : RootEntity\n    {\n        public Role()\n        {\n            OrderSort = 1;\n            CreateTime = DateTime.Now;\n            ModifyTime = DateTime.Now;\n            IsDeleted = false;\n        }\n        public Role(string name)\n        {\n            Name = name;\n            Description = \"\";\n            OrderSort = 1;\n            Enabled = true;\n            CreateTime = DateTime.Now;\n            ModifyTime = DateTime.Now;\n\n        }\n\n        /// <summary>\n        ///获取或设置是否禁用，逻辑上的删除，非物理删除\n        /// </summary>\n        public bool? IsDeleted { get; set; }\n        /// <summary>\n        /// 角色名\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        ///描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        ///排序\n        /// </summary>\n        public int OrderSort { get; set; }\n        /// <summary>\n        /// 是否激活\n        /// </summary>\n        public bool Enabled { get; set; }\n        /// <summary>\n        /// 创建ID\n        /// </summary>\n        public int? CreateId { get; set; }\n        /// <summary>\n        /// 创建者\n        /// </summary>\n        public string CreateBy { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime? CreateTime { get; set; } = DateTime.Now;\n        /// <summary>\n        /// 修改ID\n        /// </summary>\n        public int? ModifyId { get; set; }\n        /// <summary>\n        /// 修改者\n        /// </summary>\n        public string ModifyBy { get; set; }\n        /// <summary>\n        /// 修改时间\n        /// </summary>\n        public DateTime? ModifyTime { get; set; } = DateTime.Now;\n\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/Bak/RootEntity.cs",
    "content": "﻿namespace Blog.IdentityServer.Models\n{\n    public class RootEntity\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public int Id { get; set; }\n\n      \n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/Models/Bak/UserRole.cs",
    "content": "﻿using System;\n\nnamespace Blog.IdentityServer.Models\n{\n    /// <summary>\n    /// 用户跟角色关联表\n    /// </summary>\n    public class UserRole : RootEntity\n    {\n        public UserRole() { }\n\n        public UserRole(int uid, int rid)\n        {\n            UserId = uid;\n            RoleId = rid;\n            CreateTime = DateTime.Now;\n            IsDeleted = false;\n            CreateId = uid;\n            CreateTime = DateTime.Now;\n        }\n\n\n\n        /// <summary>\n        ///获取或设置是否禁用，逻辑上的删除，非物理删除\n        /// </summary>\n        public bool? IsDeleted { get; set; }\n        /// <summary>\n        /// 用户ID\n        /// </summary>\n        public int UserId { get; set; }\n        /// <summary>\n        /// 角色ID\n        /// </summary>\n        public int RoleId { get; set; }\n        /// <summary>\n        /// 创建ID\n        /// </summary>\n        public int? CreateId { get; set; }\n        /// <summary>\n        /// 创建者\n        /// </summary>\n        public string CreateBy { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime? CreateTime { get; set; }\n        /// <summary>\n        /// 修改ID\n        /// </summary>\n        public int? ModifyId { get; set; }\n        /// <summary>\n        /// 修改者\n        /// </summary>\n        public string ModifyBy { get; set; }\n        /// <summary>\n        /// 修改时间\n        /// </summary>\n        public DateTime? ModifyTime { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/Bak/sysUserInfo.cs",
    "content": "﻿using System;\n\nnamespace Blog.IdentityServer.Models\n{\n    /// <summary>\n    /// 用户信息表\n    /// </summary>\n    public class sysUserInfo\n    {\n        public sysUserInfo() { }\n\n        public sysUserInfo(string loginName, string loginPWD)\n        {\n            uLoginName = loginName;\n            uLoginPWD = loginPWD;\n            uRealName = uLoginName;\n            uStatus = 0;\n            uCreateTime = DateTime.Now;\n            uUpdateTime = DateTime.Now;\n            uLastErrTime = DateTime.Now;\n            uErrorCount = 0;\n            name = \"\";\n\n        }\n        /// <summary>\n        /// 用户ID\n        /// </summary>\n        public int uID { get; set; }\n        /// <summary>\n        /// 登录账号\n        /// </summary>\n        public string uLoginName { get; set; }\n        /// <summary>\n        /// 登录密码\n        /// </summary>\n        public string uLoginPWD { get; set; }\n        /// <summary>\n        /// 真实姓名\n        /// </summary>\n        public string uRealName { get; set; }\n        /// <summary>\n        /// 状态\n        /// </summary>\n        public int uStatus { get; set; }\n        /// <summary>\n        /// 备注\n        /// </summary>\n        public string uRemark { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public System.DateTime uCreateTime { get; set; } = DateTime.Now;\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public System.DateTime uUpdateTime { get; set; } = DateTime.Now;\n\n        /// <summary>\n        ///最后登录时间 \n        /// </summary>\n        public DateTime uLastErrTime { get; set; }= DateTime.Now;\n\n        /// <summary>\n        ///错误次数 \n        /// </summary>\n        public int uErrorCount { get; set; }\n\n\n\n        /// <summary>\n        /// 登录账号\n        /// </summary>\n        public string name { get; set; }\n\n        // 性别\n        public int sex { get; set; } = 0;\n        // 年龄\n        public int age { get; set; }\n        // 生日\n        public DateTime birth { get; set; } = DateTime.Now;\n        // 地址\n        public string addr { get; set; }\n\n        public bool tdIsDelete { get; set; }\n\n\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/Dtos/MessageModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Models\n{\n    /// <summary>\n    /// 通用返回信息类\n    /// </summary>\n    public class MessageModel<T>\n    {\n        /// <summary>\n        /// 状态码\n        /// </summary>\n        public int status { get; set; } = 200;\n        /// <summary>\n        /// 操作是否成功\n        /// </summary>\n        public bool success { get; set; } = false;\n        /// <summary>\n        /// 返回信息\n        /// </summary>\n        public string msg { get; set; } = \"服务器异常\";\n        /// <summary>\n        /// 返回数据集合\n        /// </summary>\n        public T response { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Models/ViewModel/AccessApiDateView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Blog.IdentityServer.Models.ViewModel\n{\n    public class AccessApiDateView\n    {\n        public int today { get; set; }\n        public string[] columns { get; set; }\n        public List<ApiDate> rows { get; set; }\n    }\n    public class ApiDate\n    {\n        public string date { get; set; }\n        public int count { get; set; }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Program.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing Blog.IdentityServer;\nusing Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.Extensions.Logging;\nusing Serilog;\nusing Serilog.Events;\nusing Serilog.Sinks.SystemConsole.Themes;\n\nnamespace Blog.IdentityServer\n{\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            Console.Title = \"IdentityServerWithEfAndAspNetIdentity\";\n\n            Log.Logger = new LoggerConfiguration()\n                .MinimumLevel.Debug()\n                .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n                .Enrich.FromLogContext()\n                .WriteTo.File(@\"Logs/identityserver4_log.txt\")\n                .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Literate)\n                .CreateLogger();\n\n            var seed = args.Contains(\"/seed\");\n            if (seed)\n            {\n                args = args.Except(new[] { \"/seed\" }).ToArray();\n            }\n\n            var host = CreateHostBuilder(args).Build();\n\n            if (seed)\n            {\n                SeedData.EnsureSeedData(host.Services);\n            }\n\n            host.Run();\n        }\n\n        public static IHostBuilder CreateHostBuilder(string[] args) =>\n         Host.CreateDefaultBuilder(args)\n           .ConfigureWebHostDefaults(webBuilder =>\n           {\n               webBuilder\n               .ConfigureKestrel(serverOptions =>\n               {\n                   serverOptions.AllowSynchronousIO = true;//启用同步 IO\n               })\n               .UseStartup<Startup>()\n               .UseUrls(\"http://*:5004\")\n               .ConfigureLogging((hostingContext, builder) =>\n               {\n                   builder.ClearProviders();\n                   builder.SetMinimumLevel(LogLevel.Trace);\n                   builder.AddConfiguration(hostingContext.Configuration.GetSection(\"Logging\"));\n                   builder.AddConsole();\n                   builder.AddDebug();\n               });\n           });\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Properties/PublishProfiles/FolderProfile.pubxml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n此文件由 Web 项目的发布/打包过程使用。可以通过编辑此 MSBuild 文件\n自定义此过程的行为。为了解与此相关的更多内容，请访问 https://go.microsoft.com/fwlink/?LinkID=208121。 \n-->\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <WebPublishMethod>FileSystem</WebPublishMethod>\n    <PublishProvider>FileSystem</PublishProvider>\n    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>\n    <LastUsedPlatform>Any CPU</LastUsedPlatform>\n    <SiteUrlToLaunchAfterPublish />\n    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>\n    <ExcludeApp_Data>False</ExcludeApp_Data>\n    <ProjectGuid>1db65298-136c-41bc-b2cd-ba5bba3d7a23</ProjectGuid>\n    <publishUrl>bin\\Release\\netcoreapp3.0\\publish\\</publishUrl>\n    <DeleteExistingFiles>False</DeleteExistingFiles>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Blog.IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Blog.IdentityServer\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"http://localhost:5004\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"Docker\": {\n      \"commandName\": \"Docker\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"{Scheme}://{ServiceHost}:{ServicePort}/\",\n      \"publishAllPorts\": true\n    }\n  }\n}"
  },
  {
    "path": "Blog.IdentityServer/SameSiteHandlingExtensions.cs",
    "content": "using Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace Blog.IdentityServer\n{\n    // copied from https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/\n    public static class SameSiteHandlingExtensions\n    {\n        public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)\n        {\n            services.Configure<CookiePolicyOptions>(options =>\n            {\n                options.MinimumSameSitePolicy = SameSiteMode.Unspecified;\n                options.OnAppendCookie = cookieContext => \n                    CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);\n                options.OnDeleteCookie = cookieContext => \n                    CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);\n            });\n\n            return services;\n        }\n        \n        private static void CheckSameSite(HttpContext httpContext, CookieOptions options)\n        {\n            if (options.SameSite == SameSiteMode.None)\n            {\n                var userAgent = httpContext.Request.Headers[\"User-Agent\"].ToString();\n                if (DisallowsSameSiteNone(userAgent))\n                {\n                    // For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)\n                    options.SameSite = SameSiteMode.Unspecified;\n                }\n            }\n        }\n\n        private static bool DisallowsSameSiteNone(string userAgent)\n        {\n            // Cover all iOS based browsers here. This includes:\n            // - Safari on iOS 12 for iPhone, iPod Touch, iPad\n            // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad\n            // - Chrome on iOS 12 for iPhone, iPod Touch, iPad\n            // All of which are broken by SameSite=None, because they use the iOS networking stack\n            if (userAgent.Contains(\"CPU iPhone OS 12\") || userAgent.Contains(\"iPad; CPU OS 12\"))\n            {\n                return true;\n            }\n\n            // Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:\n            // - Safari on Mac OS X.\n            // This does not include:\n            // - Chrome on Mac OS X\n            // Because they do not use the Mac OS networking stack.\n            if (userAgent.Contains(\"Macintosh; Intel Mac OS X 10_14\") && \n                userAgent.Contains(\"Version/\") && userAgent.Contains(\"Safari\"))\n            {\n                return true;\n            }\n\n            // Cover Chrome 50-69, because some versions are broken by SameSite=None, \n            // and none in this range require it.\n            // Note: this covers some pre-Chromium Edge versions, \n            // but pre-Chromium Edge does not require SameSite=None.\n            if (userAgent.Contains(\"Chrome\"))\n            {\n                return true;\n            }\n\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "Blog.IdentityServer/SeedData.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Security.Claims;\nusing IdentityModel;\nusing IdentityServer4.EntityFramework.DbContexts;\nusing IdentityServer4.EntityFramework.Mappers;\nusing Blog.IdentityServer;\nusing Blog.IdentityServer.Data;\nusing Blog.IdentityServer.Models;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\nusing Blog.Core.Common.Helper;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace Blog.IdentityServer\n{\n    public class SeedData\n    {\n        private static string GitJsonFileFormat = \"https://gitee.com/laozhangIsPhi/Blog.Data.Share/raw/master/BlogCore.Data.json/{0}.tsv\";\n\n        public static void EnsureSeedData(IServiceProvider serviceProvider)\n        {\n            /*\n             * 1、本项目同时支持Mysql和Sqlserver，默认Mysql，迁移文件已经配置好，在Data文件夹下，\n             * 直接执行三步 update-database xxxxcontext 即可。\n             * update-database -c PersistedGrantDbContext\n             * update-database -c ConfigurationDbContext\n             * update-database -c ApplicationDbContext\n             * \n             * 2、如果自己处理，删掉data下的MigrationsMySql文件夹\n             * 如果你使用sqlserver，可以先从迁移开始，下边有步骤\n             * 当然你也可以都删掉，自己重新做迁移。\n             * \n             * 3、迁移完成后，执行dotnet run /seed\n             *  \n             *  \n             *  1、PM> add-migration InitialIdentityServerPersistedGrantDbMigrationMysql -c PersistedGrantDbContext -o Data/MigrationsMySql/IdentityServer/PersistedGrantDb \n                Build started...\n                Build succeeded.\n                To undo this action, use Remove-Migration.\n                2、PM> update-database -c PersistedGrantDbContext\n                Build started...\n                Build succeeded.\n                Applying migration '20200509165052_InitialIdentityServerPersistedGrantDbMigrationMysql'.\n                Done.\n                3、PM> add-migration InitialIdentityServerConfigurationDbMigrationMysql -c ConfigurationDbContext -o Data/MigrationsMySql/IdentityServer/ConfigurationDb\n                Build started...\n                Build succeeded.\n                To undo this action, use Remove-Migration.\n                4、PM> update-database -c ConfigurationDbContext\n                Build started...\n                Build succeeded.\n                Applying migration '20200509165153_InitialIdentityServerConfigurationDbMigrationMysql'.\n                Done.\n                5、PM> add-migration AppDbMigration -c ApplicationDbContext -o Data/MigrationsMySql\n                Build started...\n                Build succeeded.\n                To undo this action, use Remove-Migration.\n                6、PM> update-database -c ApplicationDbContext\n                Build started...\n                Build succeeded.\n                Applying migration '20200509165505_AppDbMigration'.\n                Done.\n             * \n             */\n\n            Console.WriteLine(\"Seeding database...\");\n\n            using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())\n            {\n                scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();\n\n                {\n                    var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();\n                    context.Database.Migrate();\n                    EnsureSeedData(context);\n                }\n\n                {\n                    var context = scope.ServiceProvider.GetService<ApplicationDbContext>();\n                    context.Database.Migrate();\n\n                    var userMgr = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();\n                    var roleMgr = scope.ServiceProvider.GetRequiredService<RoleManager<ApplicationRole>>();\n\n                    var BlogCore_Users = JsonHelper.ParseFormByJson<List<sysUserInfo>>(GetNetData.Get(string.Format(GitJsonFileFormat, \"sysUserInfo\")));\n                    var BlogCore_Roles = JsonHelper.ParseFormByJson<List<Role>>(GetNetData.Get(string.Format(GitJsonFileFormat, \"Role\")));\n                    var BlogCore_UserRoles = JsonHelper.ParseFormByJson<List<UserRole>>(GetNetData.Get(string.Format(GitJsonFileFormat, \"UserRole\")));\n\n                    foreach (var user in BlogCore_Users)\n                    {\n                        if (user == null || user.uLoginName == null)\n                        {\n                            continue;\n                        }\n                        var userItem = userMgr.FindByNameAsync(user.uLoginName).Result;\n                        var rid = BlogCore_UserRoles.FirstOrDefault(d => d.UserId == user.uID)?.RoleId;\n                        var rName = BlogCore_Roles.Where(d => d.Id == rid).Select(d=>d.Id).ToList();\n                        var roleName = BlogCore_Roles.FirstOrDefault(d => d.Id == rid)?.Name;\n\n                        if (userItem == null)\n                        {\n                            if (rid > 0 && rName.Count>0)\n                            {\n                                userItem = new ApplicationUser\n                                {\n                                    UserName = user.uLoginName,\n                                    LoginName = user.uLoginName,\n                                    sex = user.sex,\n                                    age = user.age,\n                                    birth = user.birth,\n                                    addr = user.addr,\n                                    tdIsDelete = user.tdIsDelete,\n                                    Email = user.uLoginName + \"@email.com\",\n                                    EmailConfirmed=true,\n                                    RealName=user.uRealName,\n                                };\n\n                                //var result = userMgr.CreateAsync(userItem, \"BlogIdp123$\" + item.uLoginPWD).Result;\n\n                                // 因为导入的密码是 MD5密文，所以这里统一都用初始密码了,可以先登录，然后修改密码，超级管理员：blogadmin\n                                var result = userMgr.CreateAsync(userItem, \"BlogIdp123$InitPwd\").Result;\n                                if (!result.Succeeded)\n                                {\n                                    throw new Exception(result.Errors.First().Description);\n                                }\n\n                                var claims = new List<Claim>{\n                                    new Claim(JwtClaimTypes.Name, user.uRealName),\n                                    new Claim(JwtClaimTypes.Email, $\"{user.uLoginName}@email.com\"),\n                                    new Claim(\"rolename\", roleName),\n                                };\n\n                                claims.AddRange(rName.Select(s => new Claim(JwtClaimTypes.Role, s.ToString())));\n\n\n                                result = userMgr.AddClaimsAsync(userItem,claims ).Result;\n\n\n                                if (!result.Succeeded)\n                                {\n                                    throw new Exception(result.Errors.First().Description);\n                                }\n                                Console.WriteLine($\"{userItem?.UserName} created\");//AspNetUserClaims 表\n\n                            }\n                            else\n                            {\n                                Console.WriteLine($\"{user?.uLoginName} doesn't have a corresponding role.\");\n                            }\n                        }\n                        else\n                        {\n                            Console.WriteLine($\"{userItem?.UserName} already exists\");\n                        }\n\n                    }\n\n                    foreach (var role in BlogCore_Roles)\n                    {\n                        if (role == null || role.Name == null)\n                        {\n                            continue;\n                        }\n                        var roleItem = roleMgr.FindByNameAsync(role.Name).Result;\n\n                        if (roleItem != null)\n                        {\n                            role.Name = role.Name + Guid.NewGuid().ToString(\"N\");\n                        }\n\n                        roleItem = new ApplicationRole\n                        {\n                            CreateBy = role.CreateBy,\n                            Description = role.Description,\n                            IsDeleted = role.IsDeleted != null ? (bool)role.IsDeleted : true,\n                            CreateId = role.CreateId,\n                            CreateTime = role.CreateTime,\n                            Enabled = role.Enabled,\n                            Name = role.Name,\n                            OrderSort = role.OrderSort,\n                        };\n\n                        var result = roleMgr.CreateAsync(roleItem).Result;\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n                        Console.WriteLine($\"{roleItem?.Name} created\");//AspNetUserClaims 表\n\n                    }\n\n                }\n            }\n\n            Console.WriteLine(\"Done seeding database.\");\n            Console.WriteLine();\n        }\n\n        private static void EnsureSeedData(ConfigurationDbContext context)\n        {\n            if (!context.Clients.Any())\n            {\n                Console.WriteLine(\"Clients being populated\");\n                foreach (var client in Config.GetClients().ToList())\n                {\n                    context.Clients.Add(client.ToEntity());\n                }\n                context.SaveChanges();\n            }\n            else\n            {\n                Console.WriteLine(\"Clients already populated\");\n            }\n\n            if (!context.IdentityResources.Any())\n            {\n                Console.WriteLine(\"IdentityResources being populated\");\n                foreach (var resource in Config.GetIdentityResources().ToList())\n                {\n                    context.IdentityResources.Add(resource.ToEntity());\n                }\n                context.SaveChanges();\n            }\n            else\n            {\n                Console.WriteLine(\"IdentityResources already populated\");\n            }\n\n            if (!context.ApiResources.Any())\n            {\n                Console.WriteLine(\"ApiResources being populated\");\n                foreach (var resource in Config.GetApiResources().ToList())\n                {\n                    context.ApiResources.Add(resource.ToEntity());\n                }\n                context.SaveChanges();\n            }\n            else\n            {\n                Console.WriteLine(\"ApiResources already populated\");\n            }\n\n            if (!context.ApiScopes.Any())\n            {\n                Console.WriteLine(\"ApiScopes being populated\");\n                foreach (var resource in Config.GetApiScopes().ToList())\n                {\n                    context.ApiScopes.Add(resource.ToEntity());\n                }\n                context.SaveChanges();\n            }\n            else\n            {\n                Console.WriteLine(\"ApiScopes already populated\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Startup.cs",
    "content": "﻿using System;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Blog.IdentityServer.Data;\nusing Blog.IdentityServer.Models;\nusing System.Reflection;\nusing System.IO;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.AspNetCore.Http;\nusing Blog.IdentityServer.Extensions;\nusing Microsoft.AspNetCore.Authorization;\nusing Blog.IdentityServer.Authorization;\nusing Microsoft.AspNetCore.HttpOverrides;\nusing IdentityServer4.Extensions;\n\nnamespace Blog.IdentityServer\n{\n    public class Startup\n    {\n        public IConfiguration Configuration { get; }\n        public IWebHostEnvironment Environment { get; }\n\n        public Startup(IConfiguration configuration, IWebHostEnvironment environment)\n        {\n            Configuration = configuration;\n            Environment = environment;\n        }\n\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddSameSiteCookiePolicy();\n\n            string connectionStringFile = Configuration.GetConnectionString(\"DefaultConnection_file\");\n            var connectionString = File.Exists(connectionStringFile) ? File.ReadAllText(connectionStringFile).Trim() : Configuration.GetConnectionString(\"DefaultConnection\");\n            var isMysql = Configuration.GetConnectionString(\"IsMysql\").ObjToBool();\n\n\n            if (connectionString == \"\")\n            {\n                throw new Exception(\"数据库配置异常\");\n            }\n            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n\n            if (isMysql)\n            {\n                // mysql\n                services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(connectionString));\n            }\n            else\n            {\n                // sqlserver\n                services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));\n            };\n\n\n            services.Configure<IdentityOptions>(\n              options =>\n              {\n                  //options.Password.RequireDigit = false;\n                  //options.Password.RequireLowercase = false;\n                  //options.Password.RequireNonAlphanumeric = false;\n                  //options.Password.RequireUppercase = false;\n                  //options.SignIn.RequireConfirmedEmail = false;\n                  //options.SignIn.RequireConfirmedPhoneNumber = false;\n                  //options.User.AllowedUserNameCharacters = null;\n              });\n\n            services.AddIdentity<ApplicationUser, ApplicationRole>(options =>\n               {\n                   options.User = new UserOptions\n                   {\n                       RequireUniqueEmail = true, //要求Email唯一\n                       AllowedUserNameCharacters = null //允许的用户名字符\n                   };\n                   options.Password = new PasswordOptions\n                   {\n                       RequiredLength = 8, //要求密码最小长度，默认是 6 个字符\n                       RequireDigit = true, //要求有数字\n                       RequiredUniqueChars = 3, //要求至少要出现的字母数\n                       RequireLowercase = true, //要求小写字母\n                       RequireNonAlphanumeric = false, //要求特殊字符\n                       RequireUppercase = false //要求大写字母\n                   };\n\n                   //options.Lockout = new LockoutOptions\n                   //{\n                   //    AllowedForNewUsers = true, // 新用户锁定账户\n                   //    DefaultLockoutTimeSpan = TimeSpan.FromHours(1), //锁定时长，默认是 5 分钟\n                   //    MaxFailedAccessAttempts = 3 //登录错误最大尝试次数，默认 5 次\n                   //};\n                   //options.SignIn = new SignInOptions\n                   //{\n                   //    RequireConfirmedEmail = true, //要求激活邮箱\n                   //    RequireConfirmedPhoneNumber = true //要求激活手机号\n                   //};\n                   //options.ClaimsIdentity = new ClaimsIdentityOptions\n                   //{\n                   //    // 这里都是修改相应的Cliams声明的\n                   //    RoleClaimType = \"IdentityRole\",\n                   //    UserIdClaimType = \"IdentityId\",\n                   //    SecurityStampClaimType = \"SecurityStamp\",\n                   //    UserNameClaimType = \"IdentityName\"\n                   //};\n               })\n                .AddEntityFrameworkStores<ApplicationDbContext>()\n                .AddDefaultTokenProviders();\n\n            services.ConfigureApplicationCookie(options =>\n            {\n                options.LoginPath = new PathString(\"/oauth2/authorize\");\n            });\n\n\n            //配置session的有效时间,单位秒\n            services.AddSession(options =>\n            {\n                options.IdleTimeout = TimeSpan.FromSeconds(30);\n            });\n\n            services.AddMvc();\n\n            services.Configure<IISOptions>(iis =>\n            {\n                iis.AuthenticationDisplayName = \"Windows\";\n                iis.AutomaticAuthentication = false;\n            });\n\n            //services.Configure<ForwardedHeadersOptions>(options =>\n            //{\n            //    options.ForwardedHeaders =\n            //        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;\n            //    options.KnownNetworks.Clear();\n            //    options.KnownProxies.Clear();\n            //});\n\n            var builder = services.AddIdentityServer(options =>\n                {\n                    options.Events.RaiseErrorEvents = true;\n                    options.Events.RaiseInformationEvents = true;\n                    options.Events.RaiseFailureEvents = true;\n                    options.Events.RaiseSuccessEvents = true;\n                    // 查看发现文档\n                    if (Configuration[\"StartUp:IsOnline\"].ObjToBool())\n                    {\n                        options.IssuerUri = Configuration[\"StartUp:OnlinePath\"].ObjToString();\n                    }\n                    options.UserInteraction = new IdentityServer4.Configuration.UserInteractionOptions\n                    {\n                        LoginUrl = \"/oauth2/authorize\",//登录地址  \n                    };\n                })\n\n                // 自定义验证，可以不走Identity\n                //.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()\n                .AddExtensionGrantValidator<WeiXinOpenGrantValidator>()\n\n                // 数据库模式\n                .AddAspNetIdentity<ApplicationUser>()\n\n                // this adds the config data from DB (clients, resources)\n                .AddConfigurationStore(options =>\n                {\n                    if (isMysql)\n                    {\n                        options.ConfigureDbContext = b => b.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));\n                    }\n                    else\n                    {\n                        options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));\n                    }\n                })\n                // this adds the operational data from DB (codes, tokens, consents)\n                .AddOperationalStore(options =>\n                {\n                    if (isMysql)\n                    {\n                        options.ConfigureDbContext = b => b.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));\n                    }\n                    else\n                    {\n                        options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));\n                    }\n\n                    // this enables automatic token cleanup. this is optional.\n                    options.EnableTokenCleanup = true;\n                    // options.TokenCleanupInterval = 15; // frequency in seconds to cleanup stale grants. 15 is useful during debugging\n                });\n\n            builder.AddDeveloperSigningCredential();\n            if (Environment.IsDevelopment())\n            {\n                builder.AddDeveloperSigningCredential();\n            }\n\n\n            services.AddAuthorization(options =>\n            {\n                options.AddPolicy(\"Admin\", policy => policy.Requirements.Add(new ClaimRequirement(\"rolename\", \"Admin\")));\n                options.AddPolicy(\"SuperAdmin\", policy => policy.Requirements.Add(new ClaimRequirement(\"rolename\", \"SuperAdmin\")));\n            });\n\n            services.AddSingleton<IAuthorizationHandler, ClaimsRequirementHandler>();\n\n            services.AddIpPolicyRateLimitSetup(Configuration);\n\n\n        }\n\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            app.Use(async (ctx, next) =>\n            {\n                if (Configuration[\"StartUp:IsOnline\"].ObjToBool())\n                {\n                    ctx.SetIdentityServerOrigin(Configuration[\"StartUp:OnlinePath\"].ObjToString());\n                }\n                await next();\n            });\n\n            app.UseIpLimitMildd();\n         \n            //app.UseForwardedHeaders();\n            app.UseCookiePolicy();\n\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n                //app.UseDatabaseErrorPage();\n            }\n            else\n            {\n                app.UseExceptionHandler(\"/Home/Error\");\n            }\n\n            app.UseSession();\n            app.UseStaticFiles();\n            app.UseRouting();\n            app.UseIdentityServer();\n\n            app.UseAuthentication();\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n           {\n               endpoints.MapControllerRoute(\n                   name: \"default\",\n                   pattern: \"{controller=Home}/{action=Index}/{id?}\");\n           });\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Access denied\";\n}\n<br/>\n<header>\n    <div class=\"alert alert-danger\">\n        <h2 class=\"text-danger\">@ViewData[\"Title\"]</h2>\n    </div>\n    <p class=\"text-danger\">You do not have access to this resource.</p>\n    <p class=\"text-danger\">\n        @Html.Raw(ViewBag.ErrorMsg)\n    </p>\n</header>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/ConfirmEmail.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Confirm email\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n<div>\n    <p>\n        Thank you for confirming your email.\n    </p>\n</div>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Edit.cshtml",
    "content": "﻿@model EditViewModel\n@{\n    ViewData[\"Title\"] = \"Edit\";\n\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n\n<div class=\"row\">\n    <div class=\"col-md-6\">\n        <partial name=\"_ValidationSummary\" />\n        @{\n            foreach (var item in Model.Claims)\n            {\n                <p>@item</p>\n            }\n\n        }\n        <form asp-route-returnUrl=\"@ViewData[\"ReturnUrl\"]\" asp-action=\"Edit\" method=\"post\">\n            <h4>Create a new account.</h4>\n            <hr />\n            <input type=\"hidden\" asp-for=\"Id\" />\n            <div class=\"form-group\">\n                <label asp-for=\"UserName\"></label>\n                <input asp-for=\"UserName\" class=\"form-control\" />\n                <span asp-validation-for=\"UserName\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"LoginName\"></label>\n                <input asp-for=\"LoginName\" class=\"form-control\" />\n                <span asp-validation-for=\"LoginName\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Email\"></label>\n                <input asp-for=\"Email\" class=\"form-control\" />\n                <span asp-validation-for=\"Email\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"FirstQuestion\"></label>\n                <input disabled=\"disabled\" asp-for=\"FirstQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"FirstQuestion\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"SecondQuestion\"></label>\n                <input disabled=\"disabled\" asp-for=\"SecondQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"SecondQuestion\" class=\"text-danger\"></span>\n            </div>\n\n            <button type=\"submit\" class=\"btn btn-primary\">Update</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/ForgotPassword.cshtml",
    "content": "﻿@model ForgotPasswordViewModel\n@{\n    ViewData[\"Title\"] = \"Forgot your password?\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n<h4>Enter your email.</h4>\n<hr />\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <partial name=\"_ValidationSummary\" />\n        <form asp-action=\"ForgotPassword\" method=\"post\">\n            <div class=\"form-group\">\n                <label asp-for=\"Email\"></label>\n                <input asp-for=\"Email\" class=\"form-control\" />\n                <span asp-validation-for=\"Email\" class=\"text-danger\"></span>\n            </div>\n            <span class=\"pwd-qus-tip\">请填写注册时自定义的答案，两个都需要填写</span>\n            <br />\n            <span class=\"pwd-qus-tip\">如果注册时未填写，暂不支持找回密码，请留空并点击Submit，在下一页的link中，提交人工处理找回密码。</span>\n            <div class=\"form-group\">\n                <label asp-for=\"FirstQuestion\"></label>\n                <input asp-for=\"FirstQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"FirstQuestion\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"SecondQuestion\"></label>\n                <input asp-for=\"SecondQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"SecondQuestion\" class=\"text-danger\"></span>\n            </div>\n            <button type=\"submit\" class=\"btn btn-primary\">Submit</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/ForgotPasswordConfirmation.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Forgot password confirmation\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n<p>\n    @Html.Raw(ViewBag.ResetPassword)\n</p>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n    <div class=\"page-header logged-out\">\n        <h1>\n            Logout\n            <small>You are now logged out</small>\n        </h1>\n\n        @if (Model.PostLogoutRedirectUri != null)\n        {\n            <div>\n                Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n                <span>@Model.ClientName</span> application.\n            </div>\n        }\n        else\n        {\n\n            <div>\n                Click <a class=\"PostLogoutRedirectUri\" href=\"../\">here</a> to return to  home.\n            </div>\n        }\n\n        @if (Model.SignOutIframeUrl != null)\n        {\n            <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n        }\n    </div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Login.cshtml",
    "content": "﻿@model LoginViewModel\n\n<link href=\"~/css/login_styles.css\" rel=\"stylesheet\" />\n\n<script src=\"~/js/bootstrap-show-password.js\"></script>\n\n<div class=\"htmleaf-container\">\n    <div class=\"wrapper\">\n        <div class=\"containerLogin\">\n            <h1>BlogIdp</h1>\n\n\n            <partial name=\"_ValidationSummary\" />\n\n            @if (Model.EnableLocalLogin)\n            {\n                <form asp-route=\"authorize\" class=\"form login-container\">\n                    <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n                    <input class=\"login-name\" value=\"\" placeholder=\"登录名或邮箱\" asp-for=\"Username\">\n                    @*<input class=\"login-pass\" type=\"password\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">*@\n\n                    <p class=\"pass-with-show\">\n                        <input data-toggle=\"password\"\n                               data-placement=\"after\"\n                               class=\"login-pass form-control\"\n                               type=\"password\"\n                               value=\"\"\n                               asp-for=\"Password\"\n                               placeholder=\"密码\"\n                               data-eye-class=\"material-icons\"\n                               data-eye-open-class=\"visibility\"\n                               data-eye-close-class=\"visibility_off\"\n                               data-eye-class-position-inside=\"true\"\n                               data-message=\"点击隐藏或显示密码\">\n                    </p>\n\n\n                    @if (Model.AllowRememberLogin)\n                    {\n                        <div class=\"form-group login-remember\">\n                            <label asp-for=\"RememberLogin\">\n                                <input asp-for=\"RememberLogin\">\n                                <strong>Remember My Login</strong>\n                            </label>\n                        </div>\n                    }\n\n                    <div>\n                        <br />\n                        <p>   预览效果，请注册，默认角色AdminTest</p>\n                    </div>\n\n\n                    <button type=\"submit\" class=\"login\" name=\"button\" value=\"login\">Login</button>\n                    <button name=\"button\" value=\"cancel\">Cancel</button>\n\n\n                    <p class=\"to-register\"><a href=\"/account/register\" class=\"register\">没有账号? 去注册</a><a href=\"/account/forgot-password\" class=\"reset\">忘记密码？重置</a></p>\n                </form>\n\n            }\n            @if (Model.VisibleExternalProviders.Any())\n            {\n                <div class=\"col-md-6 col-sm-6 external-providers\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <h3 class=\"panel-title\">External Login</h3>\n                        </div>\n                        <div class=\"panel-body\">\n                            <ul class=\"list-inline\">\n                                @foreach (var provider in Model.VisibleExternalProviders)\n                                {\n                                    <li>\n                                        <a class=\"btn btn-default\"\n                                           asp-controller=\"External\"\n                                           asp-action=\"Challenge\"\n                                           asp-route-provider=\"@provider.AuthenticationScheme\"\n                                           asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                            @provider.DisplayName\n                                        </a>\n                                    </li>\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                </div>\n            }\n            @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n            {\n                <div class=\"alert alert-warning\">\n                    <strong>Invalid login request</strong>\n                    There are no login schemes configured for this client.\n                </div>\n            }\n\n        </div>\n\n        <ul class=\"bg-bubbles\">\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n            <li></li>\n        </ul>\n    </div>\n</div>\n\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"page-header\">\n        <h1>Logout</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <p>Would you like to logout of IdentityServer?</p>\n            <form asp-action=\"Logout\">\n                <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n                <fieldset>\n                    <div class=\"form-group\">\n                        <button class=\"btn btn-primary\">Yes</button>\n                    </div>\n                </fieldset>\n            </form>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/My.cshtml",
    "content": "﻿@model EditViewModel\n@{\n    ViewData[\"Title\"] = \"个人中心\";\n\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n\n<div class=\"row\">\n    <div class=\"col-md-6\">\n        <partial name=\"_ValidationSummary\" />\n        <form asp-route-returnUrl=\"@ViewData[\"ReturnUrl\"]\" asp-action=\"My\" method=\"post\">\n            <h4>Create a new account.</h4>\n            <hr />\n            <input type=\"hidden\" asp-for=\"Id\" />\n            <div class=\"form-group\">\n                <label asp-for=\"UserName\"></label>\n                <input asp-for=\"UserName\" class=\"form-control\" />\n                <span asp-validation-for=\"UserName\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"LoginName\"></label>\n                <input asp-for=\"LoginName\" class=\"form-control\" />\n                <span asp-validation-for=\"LoginName\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Email\"></label>\n                <input asp-for=\"Email\" class=\"form-control\" />\n                <span asp-validation-for=\"Email\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"FirstQuestion\"></label>\n                <input asp-for=\"FirstQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"FirstQuestion\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"SecondQuestion\"></label>\n                <input asp-for=\"SecondQuestion\" class=\"form-control\" />\n                <span asp-validation-for=\"SecondQuestion\" class=\"text-danger\"></span>\n            </div>\n\n            <button type=\"submit\" class=\"btn btn-primary\">Update</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Register.cshtml",
    "content": "﻿@model RegisterViewModel\n@{\n    ViewData[\"Title\"] = \"Register\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <partial name=\"_ValidationSummary\" />\n        <form asp-route-returnUrl=\"@ViewData[\"ReturnUrl\"]\" method=\"post\">\n            <h4>Create a new account.</h4>\n            <hr />\n            <div class=\"form-group\">\n                <label asp-for=\"RealName\"></label>\n                <input asp-for=\"RealName\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"RealName\" class=\"text-danger\"></span>\n            </div>\n            <span class=\"pwd-qus-tip\">支持登录名和邮箱两种方式登录。</span>\n            <div class=\"form-group\">\n                <label asp-for=\"LoginName\"></label>\n                <input asp-for=\"LoginName\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"LoginName\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Email\"></label>\n                <input asp-for=\"Email\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"Email\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Password\"></label>\n                <input asp-for=\"Password\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"Password\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"ConfirmPassword\"></label>\n                <input asp-for=\"ConfirmPassword\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"ConfirmPassword\" class=\"text-danger\"></span>\n            </div>\n\n            <span class=\"pwd-qus-tip\">请务必认真填写密保答案，此为后期找回账户名和密码的唯一依据，不再提供人工找回密码！请牢记自己的内容。</span>\n            <br />\n            <span class=\"pwd-qus-tip\">密保问题两个必须都填写。</span>\n            <div class=\"form-group\">\n                <label asp-for=\"FirstQuestion\"></label>\n                <input asp-for=\"FirstQuestion\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"FirstQuestion\" class=\"text-danger\"></span>\n            </div>\n\n            <div class=\"form-group\">\n                <label asp-for=\"SecondQuestion\"></label>\n                <input asp-for=\"SecondQuestion\" class=\"form-control create-item\" />\n                <span asp-validation-for=\"SecondQuestion\" class=\"text-danger\"></span>\n            </div>\n\n            <button type=\"submit\" class=\"btn btn-primary\">Register</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/ResetPassword.cshtml",
    "content": "﻿@model ResetPasswordViewModel\n@{\n    ViewData[\"Title\"] = \"Reset password\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n<h4>Reset your password.</h4>\n<hr />\n<div class=\"row\">\n    <div class=\"col-md-4\">\n        <partial name=\"_ValidationSummary\" />\n        <form method=\"post\">\n            <input asp-for=\"Code\" type=\"hidden\" />\n            <div class=\"form-group\">\n                <label asp-for=\"userId\"></label>\n                <input asp-for=\"userId\" class=\"form-control\" />\n                <span asp-validation-for=\"userId\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Email\"></label>\n                <input asp-for=\"Email\" class=\"form-control\" />\n                <span asp-validation-for=\"Email\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"AccessCode\">随机校验码</label>\n                <input asp-for=\"AccessCode\" class=\"form-control\" />\n                <span asp-validation-for=\"AccessCode\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"Password\"></label>\n                <input asp-for=\"Password\" class=\"form-control\" />\n                <span asp-validation-for=\"Password\" class=\"text-danger\"></span>\n            </div>\n            <div class=\"form-group\">\n                <label asp-for=\"ConfirmPassword\"></label>\n                <input asp-for=\"ConfirmPassword\" class=\"form-control\" />\n                <span asp-validation-for=\"ConfirmPassword\" class=\"text-danger\"></span>\n            </div>\n            <button type=\"submit\" class=\"btn btn-primary\">Reset</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/ResetPasswordConfirmation.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Reset password confirmation\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n<p>\n    Your password has been reset. Please <a asp-action=\"Login\">click here to log in</a>.\n</p>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/RoleEdit.cshtml",
    "content": "﻿@model RoleEditViewModel\n@{\n    ViewData[\"Title\"] = \"Edit\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n\n<div class=\"row\">\n    <div class=\"col-md-6\">\n        <partial name=\"_ValidationSummary\" />\n        <form asp-route-returnUrl=\"@ViewData[\"ReturnUrl\"]\" asp-action=\"Edit\" method=\"post\">\n            <h4>Create a new account.</h4>\n            <hr />\n            <input type=\"hidden\" asp-for=\"Id\" />\n            <div class=\"form-group\">\n                <label asp-for=\"RoleName\"></label>\n                <input asp-for=\"RoleName\" class=\"form-control\" />\n                <span asp-validation-for=\"RoleName\" class=\"text-danger\"></span>\n            </div>\n            \n\n            <button type=\"submit\" class=\"btn btn-default\">Update</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/RoleRegister.cshtml",
    "content": "﻿@model RoleRegisterViewModel\n@{\n    ViewData[\"Title\"] = \"Register\";\n}\n\n<h2>@ViewData[\"Title\"]</h2>\n\n<div class=\"row\">\n    <div class=\"col-md-6\">\n        <partial name=\"_ValidationSummary\" />\n        <form asp-route-returnUrl=\"@ViewData[\"ReturnUrl\"]\" method=\"post\">\n            <h4>Create a new account.</h4>\n            <hr />\n            <div class=\"form-group\">\n                <label asp-for=\"RoleName\"></label>\n                <input asp-for=\"RoleName\" class=\"form-control\" />\n                <span asp-validation-for=\"RoleName\" class=\"text-danger\"></span>\n            </div>\n           \n            <button type=\"submit\" class=\"btn btn-default\">Register</button>\n        </form>\n    </div>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Roles.cshtml",
    "content": "﻿@model List<Blog.IdentityServer.Models.ApplicationRole>\n@{\n    ViewData[\"Title\"] = \"Roles\";\n}\n<link href=\"~/css/showtip.css\" rel=\"stylesheet\" />\n<div>\n    <h2>@ViewData[\"Title\"]</h2>\n</div>\n<hr />\n\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <div>\n            <div class=\"pull-left\">\n                <a asp-action=\"RoleRegister\" asp-route-returnUrl=\"/account/Roles\" class=\"btn btn-primary\">\n                    <span title=\"Register New\" class=\"glyphicon glyphicon-plus-sign\"></span> Register New\n                </a>\n            </div>\n        </div>\n    </div>\n</div>\n<br />\n<div class=\"panel panel-default\">\n    <table class=\"table table-striped\">\n        <thead>\n            <tr>\n                <th>\n                    Name\n                </th>\n                <th>Operate</th>\n            </tr>\n        </thead>\n        <tbody>\n            @foreach (var item in Model)\n            {\n            <tr>\n                <td>\n                    @Html.DisplayFor(modelItem => item.Name)\n                </td>\n              \n                <td>\n                    <a asp-action=\"Edit\" asp-route-id=\"@item.Id\" asp-route-returnUrl=\"/account/Roles\" title=\"Edit\" class=\"btn btn-warning\">\n                        <span class=\"glyphicon glyphicon-pencil\">Edit</span>\n                    </a>\n\n\n                    <button type=\"button\" class=\"btn btn-danger viewbtn\" title=\"History\" data-id=\"@item.Id\" data-toggle=\"modal\" data-target=\"#DeleteRole\">\n                        <span class=\"glyphicon glyphicon-trash\">Delete</span>\n                    </button>\n\n                </td>\n            </tr>\n            }\n        </tbody>\n    </table>\n</div>\n\n<div class=\"modal fade\" id=\"DeleteRole\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n    <div class=\"modal-dialog\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">警告</h4>\n            </div>\n            <div class=\"modal-body\">确定要删除当前这条记录么？</div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">取消</button>\n                <button type=\"button\" class=\"btn btn-primary deletebutton\">删除</button>\n            </div>\n        </div><!-- /.modal-content -->\n    </div><!-- /.modal-dialog -->\n</div>\n\n\n\n\n\n<script src=\"~/js/Role.js\"></script>"
  },
  {
    "path": "Blog.IdentityServer/Views/Account/Users.cshtml",
    "content": "﻿@model List<Blog.IdentityServer.Models.ApplicationUser>\n@{\n    ViewData[\"Title\"] = \"Users\";\n    int index = 0;\n}\n<link href=\"~/css/showtip.css\" rel=\"stylesheet\" />\n<div>\n    <h2>@ViewData[\"Title\"]</h2>\n</div>\n<hr />\n\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <div>\n            <div class=\"pull-left\">\n                <a asp-action=\"Register\" asp-route-returnUrl=\"/account/users\" class=\"btn btn-primary\">\n                    <span title=\"Register New\" class=\"glyphicon glyphicon-plus-sign\"></span> Register New\n                </a>\n            </div>\n        </div>\n    </div>\n</div>\n<br />\n<div class=\"panel panel-default\">\n    <table class=\"table table-striped\">\n        <thead>\n            <tr>\n                <th>\n                    #\n                </th>\n                <th>\n                    Id\n                </th>\n                <th>\n                    UserName\n                </th>\n                <th>\n                    LoginName\n                </th>\n                <th>\n                    CreateTime\n                </th>\n                <th>AccessFailedCount</th>\n                <th>Operate</th>\n            </tr>\n        </thead>\n        <tbody>\n            @foreach (var item in Model)\n            {\n            <tr>\n                <td>\n                    @(Model.Count-index)\n                </td>\n                <td>\n                    @Html.DisplayFor(modelItem => item.Id)\n                </td>\n                <td>\n                    @Html.DisplayFor(modelItem => item.LoginName)\n                </td>\n                <td>\n                    @Html.DisplayFor(modelItem => item.UserName)\n                </td>\n                <td>\n                    @Html.DisplayFor(modelItem => item.birth)\n                </td>\n                <td>\n                    @Html.DisplayFor(modelItem => item.AccessFailedCount)\n                </td>\n                <td>\n                    <a asp-action=\"Edit\" asp-route-id=\"@item.Id\" asp-route-returnUrl=\"/account/users\" title=\"Edit\" class=\"btn btn-warning\">\n                        <span class=\"glyphicon glyphicon-pencil\">Edit</span>\n                    </a>\n\n\n                    <button type=\"button\" class=\"btn btn-danger viewbtn\" title=\"History\" data-id=\"@item.Id\" data-toggle=\"modal\" data-target=\"#DeleteUser\">\n                        <span class=\"glyphicon glyphicon-trash\">Delete</span>\n                    </button>\n\n                </td>\n            </tr>\n\n                index++;\n            }\n        </tbody>\n    </table>\n</div>\n\n<div class=\"modal fade\" id=\"DeleteUser\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n    <div class=\"modal-dialog\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">警告</h4>\n            </div>\n            <div class=\"modal-body\">确定要删除当前这条记录么？</div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">取消</button>\n                <button type=\"button\" class=\"btn btn-primary deletebutton\">删除</button>\n            </div>\n        </div><!-- /.modal-content -->\n    </div><!-- /.modal-dialog -->\n</div>\n\n\n\n\n\n<script src=\"~/js/User.js\"></script>"
  },
  {
    "path": "Blog.IdentityServer/Views/ApiResourcesManager/CreateOrEdit.cshtml",
    "content": "﻿\n@{\n    ViewData[\"Title\"] = \"Create\";\n}\n<style>\n    section.todoapp {\n        width: 600px;\n    }\n\n    input.Client-input {\n        float: right;\n        width: 470px;\n        height: 28px;\n        margin: 5px;\n        border: 0;\n        border-bottom: 1px dashed;\n    }\n\n    section.main {\n        height: 38px;\n        text-align: end;\n        text-align: -webkit-right;\n        line-height: 38px;\n    }\n\n    footer.info {\n        margin-top: 20px;\n    }\n</style>\n<script src=\"~/js/axios.min.js\"></script>\n<script src=\"~/js/vue.min.js\"></script>\n<section class=\"todoapp\">\n    <h3>{{ title }}</h3>\n\n    <section class=\"main\" v-cloak>\n        Api资源名称：\n        <input class=\"Client-input\" type=\"text\" v-model=\"clientDto.name\">\n    </section>\n    <section class=\"main\" v-cloak>\n        显示名称：\n        <input class=\"Client-input\" type=\"text\" v-model=\"clientDto.displayName\">\n    </section>\n    <section class=\"main\" v-cloak>\n        描述：\n        <input class=\"Client-input\" type=\"text\" v-model=\"clientDto.description\">\n    </section>\n    <section class=\"main\" v-cloak>\n        允许的声明：\n        <input class=\"Client-input\" type=\"text\" v-model=\"clientDto.userClaims\">\n    </section>\n    <section class=\"main\" v-cloak>\n        作用域：\n        <input class=\"Client-input\" type=\"text\" v-model=\"clientDto.scopes\">\n    </section>\n\n    <footer class=\"info\">\n        <input type=\"button\" onclick=\"{ window.location.href='/ApiResourcesManager/index' }\" class=\"btn btn-default\" value=\"< Back\">\n        <input type=\"button\" class=\"btn btn-primary\" @@click=\"saveClients\" value=\"Submit\">\n\n    </footer>\n    <script>\n    // app Vue instance\n    var app = new Vue({\n        // app initial state\n        data: {\n            clientDto: {\n                name:'',\n                displayName:'',\n                description:'',\n                userClaims:'',\n                scopes:'',\n            },\n            id: @(ViewBag.ApiResourceId),\n            title: '添加',\n            editedTodo: null,\n            visibility: 'all'\n        },\n        created: function () {\n            let _this = this;\n            if (_this.id > 0) {\n                    _this.title = '编辑';\n            }\n            axios.get('/ApiResourcesManager/GetDataById?id='+_this.id)\n                .then(function (response) {\n                    _this.clientDto = (response.data.response);\n                })\n                .catch(function (error) {\n                    console.log(error);\n                });\n        },\n\n        // methods that implement data logic.\n        // note there's no DOM manipulation here at all.\n        methods: {\n            saveClients: function () {\n                let _this = this;\n                _this.clientDto.id = _this.id;\n                console.log(_this.clientDto);\n                if (!_this.clientDto.name) {\n                    alert('数据不能为空');\n                    return;\n                }\n                axios.post('/ApiResourcesManager/SaveData', _this.clientDto )\n                    .then(function (response) {\n                        console.log(response);\n                        if (response.data.success) {\n                            alert(\"提交成功\");\n                            window.location.href='/ApiResourcesManager/index'\n                        }\n                    })\n                    .catch(function (error) {\n                        console.log(error);\n                    });\n\n            },\n\n\n        },\n\n    })\n\n\n    // mount\n    app.$mount('.todoapp')\n\n\n    </script>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/ApiResourcesManager/Index.cshtml",
    "content": "﻿@model List<IdentityServer4.EntityFramework.Entities.ApiResource>\n@using IdentityServer4.EntityFramework.Mappers\n\n@{\n    ViewData[\"Title\"] = \"APIs\";\n}\n<link href=\"~/css/showtip.css\" rel=\"stylesheet\" />\n<style>\n    table {\n        table-layout: fixed;\n        word-break: break-all;\n    }\n\n    hr {\n        margin-top: 0.5rem;\n        margin-bottom: 0.5rem;\n    }\n</style>\n<div>\n    <h2>@ViewData[\"Title\"]</h2>\n</div>\n<hr />\n\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <div>\n            <div class=\"pull-left\">\n                <a asp-action=\"CreateOrEdit\" asp-route-id=\"0\" class=\"btn btn-primary\">\n                    <span title=\"Create New\" class=\"glyphicon glyphicon-plus-sign\"></span> Add New\n                </a>\n            </div>\n        </div>\n    </div>\n</div>\n<br />\n<div class=\"\">\n    <table class=\"table table-striped\">\n        <thead>\n            <tr>\n                <th>资源名称</th>\n                <th>显示名称</th>\n                <th>声明</th>\n                <th>作用域</th>\n                <th>描述</th>\n                <th style=\"width:100px;\">Operate</th>\n            </tr>\n        </thead>\n        <tbody>\n            @foreach (var item in Model)\n            {\n                var apiResourceModel = item.ToModel();\n                <tr>\n                    <td>\n                        @Html.DisplayFor(modelItem => item.Name)\n                    </td>\n                    <td>\n                        @Html.DisplayFor(modelItem => item.DisplayName)\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<hr>\", apiResourceModel.UserClaims))\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<hr>\", apiResourceModel.Scopes))\n                    </td>\n                    <td>\n                        @Html.DisplayFor(modelItem => item.Description)\n                    </td>\n\n                    <td>\n                        <a asp-action=\"CreateOrEdit\" asp-route-id=\"@item.Id\" title=\"Edit\" class=\"btn btn-warning\">\n                            <span class=\"glyphicon glyphicon-pencil\">Edit</span>\n                        </a>\n\n                    </td>\n                </tr>\n            }\n        </tbody>\n    </table>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/ClientsManager/CreateOrEdit.cshtml",
    "content": "﻿\n@{\n    ViewData[\"Title\"] = \"Create\";\n}\n<style>\n    section.todoapp {\n    }\n\n    input.Client-input {\n        /*float: right;*/\n        width: 100%;\n        height: 28px;\n        margin: 5px;\n        border: 0;\n        border-bottom: 1px dashed;\n    }\n\n    .Client-select {\n        width: 100%;\n        height: 28px;\n        margin: 5px;\n        border: 0;\n        border-bottom: 1px dashed;\n    }\n\n    section.main {\n        height: 38px;\n        text-align: left;\n        line-height: 38px;\n    }\n\n    footer.info {\n        margin-top: 20px;\n    }\n\n    .todoapp .title {\n        float: left;\n        width: 130px;\n    }\n\n    .todoapp .contents {\n        float: left;\n        width: calc(100% - 200px);\n    }\n\n    .h-50 {\n        height: 50px !important;\n    }\n\n    .l-h-20 {\n        line-height: 20px;\n    }\n</style>\n<script src=\"~/js/axios.min.js\"></script>\n<script src=\"~/js/vue.min.js\"></script>\n<section class=\"todoapp\">\n    <h3>{{ title }}</h3>\n\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">客户端Id：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.clientId\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">客户端名称：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.clientName\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">客户端密钥：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.clientSecrets\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">描述：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.description\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">允许的授权类型：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.allowedGrantTypes\"></div>\n    </section>\n    <section class=\"main h-50\" v-cloak>\n        <div class=\"title l-h-20\">允许将token通过浏览器传递：</div>\n        <div class=\"contents\">\n            @*<input class=\"Client-input\" type=\"text\" v-model=\"clientDto.allowAccessTokensViaBrowser\">*@\n            <select class=\"Client-select\" v-model=\"clientDto.allowAccessTokensViaBrowser\">\n                <option value=\"True\">True</option>\n                <option value=\"False\">False</option>\n            </select>\n        </div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">作用域：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.allowedScopes\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">允许的跨域域名：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.allowedCorsOrigins\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">回调地址：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.redirectUris\"></div>\n    </section>\n    <section class=\"main\" v-cloak>\n        <div class=\"title\">退出的回调：</div>\n        <div class=\"contents\"><input class=\"Client-input\" type=\"text\" v-model=\"clientDto.postLogoutRedirectUris\"></div>\n    </section>\n    <footer class=\"info\">\n        <input type=\"button\" onclick=\"{ window.location.href='/clientsManager/index' }\" class=\"btn btn-default\" value=\"< Back\">\n        <input type=\"button\" class=\"btn btn-primary\" @@click=\"saveClients\" value=\"Submit\">\n\n    </footer>\n    <script>\n    // app Vue instance\n    var app = new Vue({\n        // app initial state\n        data: {\n            clientDto: {\n                clientId:'',\n                clientName:'',\n                clientSecrets:'',\n                description:'',\n                allowAccessTokensViaBrowser:'',\n                allowedGrantTypes:'',\n                allowedScopes:'',\n                allowedCorsOrigins:'',\n                redirectUris:'',\n                postLogoutRedirectUris:'',\n            },\n            id: @(ViewBag.ClientId),\n            title: '添加',\n            editedTodo: null,\n            visibility: 'all'\n        },\n        created: function () {\n            let _this = this;\n            if (_this.id > 0) {\n                    _this.title = '编辑';\n            }\n            axios.get('/ClientsManager/GetDataById?id='+_this.id)\n                .then(function (response) {\n                    _this.clientDto = (response.data.response);\n                })\n                .catch(function (error) {\n                    console.log(error);\n                });\n        },\n\n        // methods that implement data logic.\n        // note there's no DOM manipulation here at all.\n        methods: {\n            saveClients: function () {\n                let _this = this;\n                _this.clientDto.id = _this.id;\n                console.log(_this.clientDto);\n                if (!_this.clientDto.clientId) {\n                    alert('数据不能为空');\n                    return;\n                }\n                axios.post('/ClientsManager/SaveData', _this.clientDto )\n                    .then(function (response) {\n                        console.log(response);\n                        if (response.data.success) {\n                            alert(\"提交成功\");\n                            window.location.href='/clientsManager/index'\n                        }\n                    })\n                    .catch(function (error) {\n                        console.log(error);\n                    });\n\n            },\n\n\n        },\n\n    })\n\n\n    // mount\n    app.$mount('.todoapp')\n\n\n    </script>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/ClientsManager/Index.cshtml",
    "content": "﻿@model List<IdentityServer4.EntityFramework.Entities.Client>\n@using IdentityServer4.EntityFramework.Mappers\n\n@{\n    ViewData[\"Title\"] = \"Clients\";\n}\n<link href=\"~/css/showtip.css\" rel=\"stylesheet\" />\n<style>\n    table {\n        table-layout: fixed;\n        word-break: break-all;\n    }\n\n    hr {\n        margin: 6px;\n    }\n\n    .alert-auth {\n        margin: 15px 0 -10px 0;\n        color: #ff5567;\n        font-size: 14px;\n    }\n</style>\n<div>\n    <h2>@ViewData[\"Title\"]</h2>\n</div>\n<hr />\n\n<div class=\"row\">\n    <div class=\"col-md-12\">\n        <div>\n            <div class=\"pull-left\">\n                <a asp-action=\"CreateOrEdit\" asp-route-id=\"0\" class=\"btn btn-primary\">\n                    <span title=\"Create New\" class=\"glyphicon glyphicon-plus-sign\"></span> Add New\n                </a>\n                <p class=\"alert-auth\">如果你需要一个客户端，用来学习三端联调，但是又不想自己搭认证中心，可以使用本平台，请联系老张的哲学。</p>\n            </div>\n        </div>\n    </div>\n</div>\n<br />\n<div class=\"\">\n    <table class=\"table table-striped\">\n        <thead>\n            <tr>\n                <th style=\"width:150px;\">客户端Id</th>\n                <th style=\"width:230px;\">客户端名</th>\n                <th style=\"width:180px;\">授权类型</th>\n                <th style=\"width:210px;\">作用域</th>\n                <th>允许跨域</th>\n                <th>回调地址</th>\n                <th>退出回调</th>\n                <th style=\"width:100px;\">Operate</th>\n            </tr>\n        </thead>\n        <tbody>\n            @foreach (var item in Model)\n            {\n                var clientModel = item.ToModel();\n                <tr>\n                    <td>\n                        @(!string.IsNullOrEmpty(item.ClientId) && item.ClientId.Contains(\"xyz000!\") ? \"VIP用户专属\" : item.ClientId)\n                    </td>\n                    <td>\n                        @Html.DisplayFor(modelItem => item.ClientName)\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<br>\", clientModel.AllowedGrantTypes))\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<br>\", clientModel.AllowedScopes))\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<hr>\", clientModel.AllowedCorsOrigins))\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<hr>\", clientModel.RedirectUris))\n                    </td>\n                    <td>\n                        @Html.Raw(string.Join(\"<hr>\", clientModel.PostLogoutRedirectUris))\n                    </td>\n                    <td>\n                        <a asp-action=\"CreateOrEdit\" asp-route-id=\"@item.Id\" title=\"Edit\" class=\"btn btn-warning\">\n                            <span class=\"glyphicon glyphicon-pencil\">Edit</span>\n                        </a>\n\n                    </td>\n                </tr>\n            }\n        </tbody>\n    </table>\n</div>\n\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Device/Success.cshtml",
    "content": "<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<h1>Authentication cookie</h1>\n\n<h3>Claims</h3>\n<dl>\n    @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h3>Properties</h3>\n<dl>\n    @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>\n\n@if (Model.Clients.Any())\n{\n    <h3>Clients</h3>\n    <ul>\n        @foreach (var client in Model.Clients)\n        {\n            <li>@client</li>\n        }\n    </ul>\n}"
  },
  {
    "path": "Blog.IdentityServer/Views/Grants/Config.cshtml",
    "content": "﻿\n@{\n    ViewData[\"Title\"] = \"Config\";\n}\n\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>All Grants Type Config</h1>\n        <p>Below is the list of configs,you can configure it according to the type of authorization you need.</p>\n    </div>\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>1、client_credentials</strong></h3>\n                </div>\n                <div class=\"grey888\">\n                    <div>适用于和用户无关，机器与机器之间直接交互访问资源的场景。</div>\n                    <div>这种模式一般只用在服务端与服务端之间的认证,在c#中请求令牌，认证服务器不提供像用户数据这样的重要资源，仅仅是有限的只读资源或者一些开放的API。</div>\n                </div>\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\"> Ids4:</h5>\n            <pre>\n                 // 控制台客户端 客户端凭证模式\n                new Client\n                {\n                    ClientId = \"credentials_client\",\n                    ClientName = \"Client Credentials Client\",\n\n                    AllowedGrantTypes = GrantTypes.ClientCredentials,\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedScopes = { \"blog.core.api\" }\n                },\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client Console:</h5>\n            <pre>\n                 using var client = new HttpClient();\n                 var discoResponse = await client.GetDiscoveryDocumentAsync(\"http://localhost:5004\");\n                 if (discoResponse.IsError)\n                 {\n                     Console.WriteLine(discoResponse.Error);\n                     return;\n                 }\n\n                 var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n                 {\n                     Address = discoResponse.TokenEndpoint,\n                     ClientId = \"Console\",// 客户端id\n                     Scope = \"blog.core.api\",// 对应的受保护资源服务器id\n                     ClientSecret = \"secret\",\n                 });\n\n                 if (tokenResponse.IsError)\n                 {\n                     Console.WriteLine(tokenResponse.Error);\n                     return;\n                 }\n\n                 Console.WriteLine(tokenResponse.Json);\n                 client.SetBearerToken(tokenResponse.AccessToken);\n                 // 获取access_token后，向资源服务器发起请求\n                 var response = await client.GetAsync(\"http://localhost:8081/api/blog/1\");\n     \n            </pre>\n\n        </div>\n\n\n    </div>\n\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>2、password</strong></h3>\n                </div>\n                <div class=\"grey888\">\n                    <div>这种模式适用于鉴权服务器与资源服务器是高度相互信任的，例如两个服务都是同个团队或者同一公司开发的。该应用Client就使用你的密码，申请令牌，这种方式称为\"密码式\"（password）。</div>\n                    <div>如果你对接的是第三方的客户端，请不要使用这个方案，因为第三方可能会记录你的认证平台的用户安全信息比如用户名和密码）</div>\n                    <div>这种模式比客户端凭证模式的好处是多了用户信息，同时也可以自定义Claim声明。</div>\n                </div>\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\"> Ids4:</h5>\n            <pre>\n            \n               // 自定义claim\n                public static IEnumerable<ApiScope> ApiScopes =>\n                new ApiScope[]\n                {\n                    new ApiScope(\"password_scope1\")\n                };\n                \n                public static IEnumerable<ApiResource> ApiResources =>\n                 new ApiResource[]\n                 {\n\n                     new ApiResource(\"blog.core.api\",\"api1\")\n                     {\n                         Scopes={ \"blog.core.api\" },\n                         UserClaims={JwtClaimTypes.Role},  //添加Cliam 角色类型，同时，用户的claim也许配置！\n                         ApiSecrets={new Secret(\"apisecret\".Sha256())}\n                     }\n                 };\n                \n                        \n                 // 控制台客户端 密码模式\n                 new Client\n                 {\n                     ClientId = \"password_client\",\n                     ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                     AllowedGrantTypes = new List<string>()\n                     {\n                         GrantTypes.ResourceOwnerPassword.FirstOrDefault(),\n                     },\n\n                     AllowedScopes = new List<string>\n                     {\n                         \"blog.core.api\"\n                     }\n                 }\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client Console:</h5>\n            <pre>\n                 using var client = new HttpClient();\n                 var discoResponse = await client.GetDiscoveryDocumentAsync(\"http://localhost:5004\");\n                 if (discoResponse.IsError)\n                 {\n                     Console.WriteLine(discoResponse.Error);\n                     return;\n                 }\n\n                 var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest\n                 {\n                     Address = discoResponse.TokenEndpoint,\n                     ClientId = \"password_client\",// 客户端id\n                     Scope = \"blog.core.api\",// 对应的受保护资源服务器id\n                     ClientSecret = \"secret\",\n                     UserName = \"laozhang\",// 这里的用户名密码，是我SeedData的时候导入的\n                     Password = \"BlogIdp123$InitPwd\"\n                 });\n\n                 if (tokenResponse.IsError)\n                 {\n                     Console.WriteLine(tokenResponse.Error);\n                     return;\n                 }\n\n                 Console.WriteLine(tokenResponse.Json);\n                 client.SetBearerToken(tokenResponse.AccessToken);\n                 // 获取access_token后，向资源服务器发起请求\n                 var response = await client.GetAsync(\"http://localhost:8081/api/blog/1\");\n     \n            </pre>\n\n        </div>\n\n\n    </div>\n\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>3、implicit（MVC模式）</strong></h3>\n                </div>\n                <div class=\"grey888\">\n                    <div>让用户自己在IdentityServer服务器进行登录验证，客户端不需要知道用户的密码，从而实现用户密码的安全性。</div>\n                    <div>有些 Web 应用是纯前端应用，没有后端，必须将令牌储存在前端。这种方式没有授权码这个中间步骤，所以称为（授权码）\"简化\"（implicit）。</div>\n                    <div>简化模式（implicit grant type）不通过第三方应用程序的服务器，直接在浏览器中向认证服务器申请令牌，跳过了\"授权码\"这个步骤</div>\n                    <div>这种模式基于安全性考虑，建议把token时效设置短一些, 不支持refresh token</div>\n                    <div>这种模式由于token携带在url中，安全性方面不能保证。不过，令牌的位置是 URL 锚点（fragment），而不是查询字符串（querystring），这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议，因此存在\"中间人攻击\"的风险，而浏览器跳转时，锚点不会发到服务器，就减少了泄漏令牌的风险。</div>\n                </div>\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Ids4:</h5>\n            <pre>\n                new Client\n                {\n                    ClientId = \"Implicit_client\",\n                    ClientName=\"Demo MVC Client\",\n\n                    AllowedGrantTypes = GrantTypes.Implicit,\n                 \n                    RedirectUris = { \"http://localhost:1003/signin-oidc\" },\n                    PostLogoutRedirectUris = { \"http://localhost:1003/signout-callback-oidc\" },\n                    \n                    RequireConsent=true,\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                        \"blog.core.api\"\n                    }\n                }\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client MVC:</h5>\n            <pre>\n\n            services.AddAuthentication(options =>\n            {\n                options.DefaultScheme = \"Cookies\";\n                options.DefaultChallengeScheme = \"oidc\";\n            })\n               .AddCookie(\"Cookies\")\n              .AddOpenIdConnect(\"oidc\", options =>\n              {\n                  options.Authority = \"http://localhost:5004\";\n                  options.RequireHttpsMetadata = false;\n                  options.ClientId = \"Implicit_client\";\n                  options.SaveTokens = true;\n                  options.GetClaimsFromUserInfoEndpoint = true;\n              });\n            </pre>\n\n        </div>\n\n\n    </div>\n\n\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>4、implicit（VUE模式）</strong></h3>\n                </div>\n\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\"> Ids4:</h5>\n            <pre>\n                new Client {\n                    ClientId = \"blogvuejs\",\n                    ClientName = \"Blog.Vue JavaScript Client\",\n                    AllowedGrantTypes = GrantTypes.Implicit,\n                    AllowAccessTokensViaBrowser = true,\n\n                    RedirectUris =           {\n                        \"http://vueblog.neters.club/callback\",\n                        \"http://apk.neters.club/oauth2-redirect.html\",\n                        \"http://localhost:6688/callback\",\n                        \"http://localhost:8081/oauth2-redirect.html\",\n                    },\n                    PostLogoutRedirectUris = { \"http://vueblog.neters.club\",\"http://localhost:6688\" },\n                    AllowedCorsOrigins =     { \"http://vueblog.neters.club\",\"http://localhost:6688\" },\n\n                    AccessTokenLifetime=3600,\n\n                    AllowedScopes = {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"roles\",\n                        \"blog.core.api.BlogModule\"\n                    }\n                },\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client Vue.js:</h5>\n            <pre>\n                 \n            import { UserManager } from 'oidc-client'\n\n            class ApplicationUserManager extends UserManager {\n              constructor () {\n                super({\n                  authority: 'https://ids.neters.club',\n                  client_id: 'blogadminjs',\n                  redirect_uri: 'http://vueadmin.neters.club/callback',\n                  response_type: 'id_token token',\n                  scope: 'openid profile roles blog.core.api',\n                  post_logout_redirect_uri: 'http://vueadmin.neters.club'\n                })\n              }\n\n              async login () {\n                await this.signinRedirect()\n                return this.getUser()\n              }\n\n              async logout () {\n                return this.signoutRedirect()\n              }\n            }\n\n            </pre>\n\n        </div>\n\n\n    </div>\n\n\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>5、authorization_code</strong></h3>\n                </div>\n                <div class=\"grey888\">\n                    <div>这种模式不同于简化模式，在于授权码模式不直接返回token，而是先返回一个授权码，然后再根据这个授权码去请求token。这显得更为安全。</div>\n                    <div>通过多种授权模式中的授权码模式进行说明，主要针对介绍IdentityServer保护API的资源，授权码访问API资源。</div>\n                </div>\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\"> Ids4:</h5>\n            <pre>\n                new Client\n                {\n                    ClientId = \"blazorserver\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    RequireConsent = false,\n                    RequirePkce = true,\n                    AlwaysIncludeUserClaimsInIdToken=true,//将用户所有的claims包含在IdToken内\n                    AllowAccessTokensViaBrowser = true,\n                \n                    // where to redirect to after login\n                    RedirectUris = { \"https://mvp.neters.club/signin-oidc\" },\n\n                    AllowedCorsOrigins =     { \"https://mvp.neters.club\" },\n                   \n                    // where to redirect to after logout\n                    PostLogoutRedirectUris = { \"https://mvp.neters.club/signout-callback-oidc\" },\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                        \"blog.core.api\"\n                    }\n                },\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client MVC:</h5>\n            <pre>\n                 \n            // 第一部分:认证方案的配置\n            // add cookie-based session management with OpenID Connect authentication\n            services.AddAuthentication(options =>\n            {\n                options.DefaultScheme = \"Cookies\";\n                options.DefaultChallengeScheme = \"oidc\";\n            })\n            .AddCookie(\"Cookies\", options =>\n            {\n                //options.Cookie.Name = \"blazorclient\";\n\n                //options.ExpireTimeSpan = TimeSpan.FromHours(1);\n                //options.SlidingExpiration = false;\n            })\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.Authority = \"https://ids.neters.club/\";\n                options.RequireHttpsMetadata = false;//必须https协议\n                options.ClientId = \"blazorserver\"; // 75 seconds\n                options.ClientSecret = \"secret\";\n                options.ResponseType = \"code\";\n                options.SaveTokens = true;\n\n                // 为api在使用refresh_token的时候,配置offline_access作用域\n                options.GetClaimsFromUserInfoEndpoint = true;\n                // 作用域获取\n                options.Scope.Clear();\n                options.Scope.Add(\"roles\");//\"roles\"\n                options.Scope.Add(\"rolename\");//\"rolename\"\n                options.Scope.Add(\"blog.core.api\");\n                options.Scope.Add(\"profile\");\n                options.Scope.Add(\"openid\");\n\n                options.Events = new OpenIdConnectEvents\n                {\n                    // called if user clicks Cancel during login\n                    OnAccessDenied = context =>\n                    {\n                        context.HandleResponse();\n                        context.Response.Redirect(\"/\");\n                        return Task.CompletedTask;\n                    }\n                };\n            });\n\n            </pre>\n\n        </div>\n\n\n    </div>\n\n\n    <div class=\"card\">\n        <div class=\"card-header\">\n            <div class=\"row\">\n                <div class=\"col-sm-8 card-title\">\n                    <h3><strong>6、hybrid</strong></h3>\n                </div>\n\n                <div class=\"grey888\">\n                    <div>客户端根据ResponseType的不同，authorization endpoint返回可以分为三种情况：\"code id_token\"、\"code token\"、\"code id_token token\"</div>\n                    <div>适用于服务器端 Web 应用程序和原生桌面/移动应用程序，混合模式是简化模式和授权码模式的组合。</div>\n                    <div>每当考虑使用授权码模式的时候，一般都是使用混合模式。</div>\n                </div>\n            </div>\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Ids4:</h5>\n            <pre>\n                new Client\n                {\n                    ClientId = \"hybridclent\",\n                    ClientName=\"Demo MVC Client\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Hybrid,\n                    \n                    AllowAccessTokensViaBrowser = true,//返回类型包含token时候，配置\n                 \n                    RequirePkce = false,//v4.x需要配置这个\n\n                    RedirectUris = { \"http://localhost:1003/signin-oidc\" },\n                    PostLogoutRedirectUris = { \"http://localhost:1003/signout-callback-oidc\" },\n\n                    AllowOfflineAccess=true,\n                    AlwaysIncludeUserClaimsInIdToken=true,\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        IdentityServerConstants.StandardScopes.Email,\n                        \"roles\",\n                        \"rolename\",\n                        \"blog.core.api\"\n                    }\n                }\n            </pre>\n\n        </div>\n\n        <div>\n            <h5 class=\"Grant-Config\">Client MVC:</h5>\n            <pre>\n\n            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n\n            // 认证方案的配置\n            services.AddAuthentication(options =>\n            {\n                options.DefaultScheme = \"Cookies\";\n                options.DefaultChallengeScheme = \"oidc\";\n            })\n            .AddCookie(\"Cookies\", options =>\n            {\n                options.AccessDeniedPath = \"/Authorization/NoPermission\";\n            })\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.SignInScheme = \"Cookies\";\n\n                options.Authority = \"https://ids.neters.club\";\n                options.RequireHttpsMetadata = false;\n                options.ClientId = \"hybridclent\";\n                options.ClientSecret = \"secret\";\n\n                options.ResponseType = \"code id_token\";\n\n                options.GetClaimsFromUserInfoEndpoint = true;\n                options.SaveTokens = true;\n\n\n                // 为api在使用refresh_token的时候,配置offline_access作用域\n                //options.GetClaimsFromUserInfoEndpoint = true;\n\n                // 作用域获取\n                options.Scope.Clear();\n                options.Scope.Add(\"roles\");\n                options.Scope.Add(\"rolename\");\n                options.Scope.Add(\"blog.core.api\");\n                options.Scope.Add(\"profile\");\n                options.Scope.Add(\"openid\");\n\n                //options.ClaimActions.MapJsonKey(\"website\", \"website\");\n\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    //映射 User.Name\n                    //NameClaimType = JwtClaimTypes.Name,\n                    //RoleClaimType = JwtClaimTypes.Role\n                };\n            });\n            </pre>\n\n        </div>\n\n\n    </div>\n\n\n</div>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n\n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>\n\n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "Blog.IdentityServer/Views/Home/Index.cshtml",
    "content": "﻿@using IdentityServer4.Extensions\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n\n<div class=\"container\">\n    <div class=\"welcome-block px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center\">\n        <h1 class=\"display-4\">\n            <img class=\"icon\" alt=\"Logo\" src=\"/logofull.png\">\n            <br />\n        </h1>\n        <p class=\"lead\">欢迎来到 Blog.IdentityServer</p>\n    </div>\n\n    <div class=\"card-deck mb-3 text-center\">\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <div class=\"card mb-4 box-shadow\">\n                <div class=\"card-header\">\n                    <h4 class=\"my-0 font-weight-normal\">持久授权</h4>\n                </div>\n                <div class=\"card-body\">\n                    <h1 class=\"card-title\">\n                        <span class=\"oi oi-lock-locked\" title=\"查看\" aria-hidden=\"true\"></span>\n                    </h1>\n                    <a class=\"btn btn-lg btn-block btn-primary\" href=\"/Grants\">查看</a>\n                </div>\n            </div>\n\n\n        }\n        else\n        {\n            <div class=\"card mb-4 box-shadow\">\n                <div class=\"card-header\">\n                    <h4 class=\"my-0 font-weight-normal\">登录</h4>\n                </div>\n                <div class=\"card-body\">\n                    <h1 class=\"card-title\">\n                        <span class=\"oi oi-lock-locked\" title=\"登录\" aria-hidden=\"true\"></span>\n                    </h1>\n                    <a class=\"btn btn-lg btn-block btn-primary\" href=\"/oauth2/authorize\">登录</a>\n                </div>\n            </div>\n        }\n\n\n        <div class=\"card mb-4 box-shadow\">\n            <div class=\"card-header\">\n                <h4 class=\"my-0 font-weight-normal\">发现文档</h4>\n            </div>\n            <div class=\"card-body\">\n                <h1 class=\"card-title\">\n                    <span class=\"oi oi-monitor\" title=\"发现文档\" aria-hidden=\"true\"></span>\n                </h1>\n                <a href=\"/.well-known/openid-configuration\" class=\"btn btn-lg btn-block btn-outline-primary\">发现文档</a>\n            </div>\n        </div>\n\n        <div class=\"card mb-4 box-shadow\">\n            <div class=\"card-header\">\n                <h4 class=\"my-0 font-weight-normal\">各模式配置</h4>\n            </div>\n            <div class=\"card-body\">\n                <h1 class=\"card-title\">\n                    <span class=\"oi oi-musical-note\" title=\"模式配置\" aria-hidden=\"true\"></span>\n                </h1>\n                <a href=\"/Grants/Config\" class=\"btn btn-lg btn-block btn-outline-primary\">各模式配置</a>\n            </div>\n        </div>\n\n    </div>\n\n    <footer class=\"pt-4 my-md-5 pt-md-5 border-top\">\n        <div class=\"row\">\n            <div class=\"col-6 col-md\">\n                Blog.IdentityServer\n                <small class=\"d-block mb-3 text-muted\">© 2018-2020 老张的哲学 The style design idea comes from <a href=\"https://github.com/skoruba/IdentityServer4.Admin\" target=\"_blank\">Skoruba.IdentityServer4.Admin</a> </small>\n            </div>\n            <div class=\"col-md-6 text-right\">\n\n            </div>\n        </div>\n    </footer>\n</div>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"page-header\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n\n<h1>You are now being returned to the application.</h1>\n<p>Once complete, you may close this tab</p>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script src=\"~/js/signin-redirect.js\"></script>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "﻿@using IdentityServer4.Extensions\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>IdentityServer4</title>\n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    @*<link rel=\"stylesheet\" href=\"~/lib/bootstrap/css/bootstrap.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.css\" />*@\n\n\n    <link href=\"~/css/bundle.min.css\" rel=\"stylesheet\" />\n    <link href=\"~/css/web.css\" rel=\"stylesheet\" />\n\n    <script src=\"~/lib/jquery/jquery.min.js\"></script>\n    @*<script src=\"~/lib/bootstrap/js/bootstrap.min.js\"></script>*@\n    <script src=\"~/js/bundle.min.js\"></script>\n    <script src=\"~/js/showTip.js\"></script>\n\n</head>\n<body>\n    @if (!string.IsNullOrWhiteSpace(name))\n    {\n        <div class=\"navbar navbar-inverse navbar-fixed-top\">\n            <div class=\"container-fluid\">\n                @*<div class=\"navbar-header\">\n                        <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#bs-example-navbar-collapse-1\" aria-expanded=\"false\">\n                            <span class=\"sr-only\">Toggle navigation</span>\n                            <span class=\"icon-bar\"></span>\n                            <span class=\"icon-bar\"></span>\n                            <span class=\"icon-bar\"></span>\n                        </button>\n                        <a href=\"~/\">\n                            <span class=\"navbar-brand\">\n                                <img src=\"~/icon.png\" class=\"icon-banner\">\n                                Blog.Idp\n                            </span>\n                        </a>\n                    </div>*@\n\n\n                <div class=\"width100p menu width100% d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom box-shadow\">\n                    <!--Site name -->\n                    <h3 class=\"menu-logo my-0 mr-md-auto font-weight-normal\"><a class=\"logo\" href=\"/\">Blog.Idp</a></h3>\n                    <!--Menu item -->\n                    <!--Menu item -->\n                    <!--Menu item -->\n                    <div class=\"menu-item my-2 my-md-0 mr-md-3 dropdown\">\n                        <button type=\"button\" class=\"btn btn-primary dropdown-toggle\" data-toggle=\"dropdown\">\n                            设置 - @name\n                        </button>\n                        <div class=\"dropdown-menu\">\n                            <a class=\"dropdown-item\" href=\"/Account/users\">用户</a>\n                            <a class=\"dropdown-item\" href=\"/ClientsManager/index\">客户端</a>\n                            <a class=\"dropdown-item\" href=\"/ApiResourcesManager/index\">资源api</a>\n                            <a class=\"dropdown-item\" href=\"/Account/forgot-password\">更改密码</a>\n                            <a class=\"dropdown-item\" href=\"/Grants\">授权</a>\n                            <a class=\"dropdown-item\" href=\"/Account/My\">个人中心</a>\n                        </div>\n                    </div>\n                    <a class=\"menu-item my-2 btn btn-outline-primary\" href=\"/Account/Logout\">注销</a>\n\n                    <!--Menu button - show in < MD -->\n                    <a class=\"my-2 btn btn-outline-primary menu-button\" href=\"#\">\n                        <span class=\"oi oi-menu\" title=\"menu\" aria-hidden=\"true\"></span> 菜单\n                    </a>\n                </div>\n\n\n                @*<li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                        <ul class=\"dropdown-menu\">\n                            <li><a asp-action=\"forgot-password\" asp-controller=\"Account\">修改密码</a></li>\n                            <li><a asp-action=\"Logout\" asp-controller=\"Account\">退出登录</a></li>\n                        </ul>\n                    </li>\n\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">用户管理 <b class=\"caret\"></b></a>\n                        <ul class=\"dropdown-menu\">\n                            <li><a asp-action=\"users\" asp-controller=\"Account\">用户</a></li>\n                            <li><a asp-action=\"roles\" asp-controller=\"Account\">角色</a></li>\n                        </ul>\n                    </li>\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">资源管理 <b class=\"caret\"></b></a>\n                        <ul class=\"dropdown-menu\">\n                            <li><a asp-action=\"index\" asp-controller=\"ClientsManager\">客户端</a></li>\n                            <li><a asp-action=\"index\" asp-controller=\"ApiResourcesManager\">资源api</a></li>\n                        </ul>\n                    </li>*@\n\n\n\n\n            </div>\n        </div>\n    }\n    <div class=\"content-bd\">\n        @RenderBody()\n    </div>\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "Blog.IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "Blog.IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "Blog.IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServer4.Quickstart.UI\n@using IdentityServer4.Quickstart.UI.Device\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "Blog.IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "Blog.IdentityServer/appsettings.Development.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/appsettings.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"Debug\": {\n      \"LogLevel\": {\n        \"Default\": \"Warning\"\n      }\n    },\n    \"Console\": {\n      \"LogLevel\": {\n        \"Default\": \"Warning\",\n        \"Microsoft.Hosting.Lifetime\": \"Debug\"\n      }\n    }\n  },\n  \"ConnectionStrings\": {\n    \"IsMysql\": true,//默认开启mysql\n    \"DefaultConnection\": \"Data Source=(localdb)\\\\MSSQLLocalDB;Initial Catalog=BlogIdpPro;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False\",\n    \"DefaultConnection_file\": \"c:\\\\my-file\\\\dbCountPsw1_ldpxx.txt\"\n  },\n  \"Certificates\": {\n    \"Path\": \"Certificates\\\\IS4.pfx\",\n    \"Password\": \"anson7\"\n  },\n  \"StartUp\": {\n    \"IsOnline\": false,\n    \"OnlinePath\": \"https://ids.neters.club\"\n  },\n  \"IpRateLimiting\": {\n    \"EnableEndpointRateLimiting\": true, //False: globally executed, true: executed for each\n    \"StackBlockedRequests\": false, //False: Number of rejections should be recorded on another counter\n    \"RealIpHeader\": \"X-Real-IP\",\n    \"ClientIdHeader\": \"X-ClientId\",\n    \"IpWhitelist\": [], //白名单\n    \"EndpointWhitelist\": [ \"get:/api/xxx\", \"*:/api/yyy\" ],\n    \"ClientWhitelist\": [ \"dev-client-1\", \"dev-client-2\" ],\n    \"QuotaExceededResponse\": {\n      \"Content\": \"{{\\\"status\\\":429,\\\"msg\\\":\\\"访问过于频繁，请一分钟后重试\\\",\\\"success\\\":false}}\",\n      \"ContentType\": \"application/json\",\n      \"StatusCode\": 429\n    },\n    \"HttpStatusCode\": 429, //返回状态码\n    \"GeneralRules\": [ //api规则,结尾一定要带*\n      {\n        \"Endpoint\": \"*:/account/register*\",\n        \"Period\": \"1m\",\n        \"Limit\": 8\n      },\n      {\n        \"Endpoint\": \"*:/oauth2/authorize*\",\n        \"Period\": \"1m\",\n        \"Limit\": 10\n      },\n      {\n        \"Endpoint\": \"*/api/*\",\n        \"Period\": \"1s\",\n        \"Limit\": 1\n      }\n    ]\n\n  }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/tempkey.jwk",
    "content": "{\"alg\":\"RS256\",\"d\":\"HwqpgH1B1efVFfOh8siXQln2Hc3a5jwNv8iO34ApQ2kIMpirKhvuYbgZfIlroPDEPObOLCXgZWbrQgRi-OkoAPgPbn9vkemT0_au9ZVw6aocDR9rt6AguTrSE68cBz5Qx2oarJ8_TAAqNtByAQOUdll2S0OuBRR2hBfdQKI-eemtoMGi95PV27AeJ4U-35iGvrIC665_ypvbRRymjXOup3hWv0Zh1o5gta9isO2mhBG4K1khGqF_XaYDYQ7t1C02Fj9WrEyGdKta9MgtAnagauD51eQsw2m7yknbfAZEd6a2Ck_knLLTzpyDqkF53qXpi53Z689tuBsTyHML_px3cQ\",\"dp\":\"mzRXEgwfQ0usqs6UJFKKZPdckFdxsWq38iMrpauELgRON2RZlDEa2Ie_BejGC98TwgOnxP3Lh794BFxS11g0-JDQAyhdTvvj-XGJixeeWTdc-azdDumVS3lh-GTv0KoCJ9IuRytrAbjkeIezQ1z5z2sMq0YZlpiWwErsM_jdUo8\",\"dq\":\"UyQcmL9XkA3Wt3uLQLb4ZMCgTIYk92wfwudU1XvKsBaJubRkdlph9-he4stqWU6sNoFChcrmtWW4fTlARiIbBDYPCKGrCxq0DwXNe3NzF4R7T8s5Ft_hxxGTfWJQ6Ba9G1KaRyKnw98Hu7RqYWyYrm-RyfqEYNu_nA7QxtvBokk\",\"e\":\"AQAB\",\"kid\":\"039695D7F0DC6503E128F4FAAB3585B9\",\"kty\":\"RSA\",\"n\":\"sSYWLw2EIKwo97ky4R2PW5ouXKT5wqEgGMA3G1pX_7HKlJKKoNaMTB1_KsarQRnihdGzj2HrB5BggAlieEo1MPRT9rOKVDMhvVvRjLcd2edWvi6-FXxlgL9tYA9UlVGWu1Dr6K5SG0X066PRqlhl31GDcvsf2Yjzy-PaYeUNM0gDBfwX6Sg-NViNUQaw4xjuOM65lFnoijEdDEl8MuCJdXB_XICUeXKpfdJbbEW2ytW6jmUkKS4oOHteViFeIsp-TFZY2K8aRlasNiI8rKOdwiFIV-h92TocZ3-KD0nlCmJzXDMnRl8mYqfmq6BCELUdutxTGlNgO-d8_4mip4JsiQ\",\"p\":\"xNqUonYhPcV88q8I2R25ooTLyKtGSuw-WceZCAv6oxKBhFw3bsoL6Juvgjxk6jYH9lN4lsLM88rT9ZPcXbuj8116W_dDQMj3T8TMriTRiV6vV5kt9gjtzDg_8NBxiyJaYz0fiqXlEEFFQUkIOYMa1ITwAPcIJMC2w1x3g9jyHCM\",\"q\":\"5l_Z3e02rKFNQGc-WMcUbpXETzZDmX2WnF6jiCrzLvzb8DhvpIy13IYc9HcdiN1hgwZgGnfjQXdA1_izDyKw-CzjXkJ0FKucLoSz8fuRdUeu028leO6PNOYYJaR1AfHE4dIU-StplEU5OLeiX8GXm0zDcqWgcUJ2Rz7fX8XneWM\",\"qi\":\"rw8bjm_5cp7-ezVUE01Lobi_1h1U8xzMJ8QDt3FycdH8mitCf0pTjChfI_FGzcbWXOjq5jFsHv7DyazkURtKD7n3dsKGiq95-ktNpGMwQFIDyVQD2cuKn0tj6Hgss0YfZA_VnG4Fp5a6u1gfLf0mrnPYQf9OUo4mmUO0ONUYRoY\"}"
  },
  {
    "path": "Blog.IdentityServer/tempkey.rsa",
    "content": "{\"KeyId\":\"rNruJfc3LCx8qbpod8foCA\",\"Parameters\":{\"D\":\"V+uOk1wEljBVqO+h+GfgR214tedtVf7rkLArWvAKTdQkBpTxn9xlEqFsCv//FZoVIXyXK3vXgPt/pXZJ6A42muod2cEYblgNSi/noiKLaQGA/PCA29TM5qqKdfU3pey0qKZr6elPzRuDc2MkbGsLkfXahqK9f4QrDHBZETXjx/7H7N6e0N2T3wJ77EAPYAYRr2IYXOuzfhreU9RzHRfQOketB7kIvacBIaiiheQtPBS60aZm5DruC3LTMpWISNNOCKevFWoS6lQixpCfg/K/Y8QDNnxhafasNpY6ZRNUxnqi8BJ5Dlqo68otOo+JSnURO4x/GhNb1MTMRoay7c2D3Q==\",\"DP\":\"1SnnkdSmvtG9vE+rsCB54uQTuQpNJvopvVNuB+JUFjGiRHHoe8eMh9AEqDI0BsMoTFGz7bePTapFUOFpRTAQfgZPrTFhvuPCOOONK2ceaUC23yYqa3jdWuwIVDzpanifvz5iTHF1PA65NxXfsF2cOK55G+2833jEHP3TF88dQDk=\",\"DQ\":\"PriWuA/zvGvRyjWCCwDtNXhXiMyauCQscvy28eZVqB4tyfmN2BynOrWP9+YTmM54cwFvJ4TJBjcOx0AL/mzQGiK40+kcAGSh00AZ/rP8JWUlA1IKGSXuCcArYt/F3CAWwZqNw1EzMGvJ2in6uYPlq1HQDoL9Dp0v7uCS5fXLBrs=\",\"Exponent\":\"AQAB\",\"InverseQ\":\"8h9ojX//gM7Y1jbWrF+xOFJfsJDE27A9lpDwC0Vb21CosX1Q0F28iihyLapehKCuoh8+ho8EQhgEQIH+tYiZ1eUCisR3Jn6ZDR6+OQsgJB5hTSskhV7sND0M4yp9+zpEiIwSgG4ES4YVrjbgoxCEfIw1sSW3ZcXHkd3L0wHArOs=\",\"Modulus\":\"7NtqboAxsXFdo5kc4wccRMxyp7i6cg3YEg4facNgvTwDRRMUtTCuFkXBZBD8R/MQZrmzaYx29sK1XlHNJ7SjoMA0kq77sKjU7kKBWkf5eIhnHKDmIHNCPQzcXOVsr53IIreYXsO66JQW7d/m6Glmr7DT8bOflp3FZEUh/v/1M7F7rcwoTvur1ry/viWPsLx5lekYClfYID1jtjmrC5Xt76CY9ZvcNZ981v8qPkVGhNaEyZBi7Pgm7zUt4iRSQSma5Bc/en+8/C0MxE67kwxxnD3HoCAM9GxlTtbG8XxtlHl3XuSO4sFVW4XTAAdUGcbb3BuUWecNdlKcFO8AmxGJoQ==\",\"P\":\"8sods2xmYT3BdIA9gM96eK+AR+NpPDzLn4gIPJSLtBIeYzcZ/Xka9WVVlVwCCHeogs/Tk+uy7fq1v/+wcblx8Pl+fncfskpJaaWWCTzRbb75CoEjFXWMYFr9PiZ3FxdFCASQDlMv/FDj0ZVJr8w7rmXo4B8lqZIR//kYbH8EW28=\",\"Q\":\"+b6qUwFpidC4QDH2dTqASz4HU/ok77Ks+e/CwjmC1H5TlqjRcTlONcwfgO0YIz73PC0D40FxewQrFryn5SK1by0DGuQ8L3rk21araldNFy3/ui4Hu7AqTSZrhitoEaMgXNhv1G7oDoreWzxowzW5xyiJ/5SsDMn9ezWkPaqAI+8=\"}}"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/css/login_styles.css",
    "content": "\n* {\n    box-sizing: border-box;\n    margin: 0;\n    padding: 0;\n    font-weight: 300;\n}\n\nbody {\n    font-family: 'Source Sans Pro', sans-serif;\n    color: white;\n    font-weight: 300;\n    margin: 0;\n}\n\n    body ::-webkit-input-placeholder {\n        /* WebKit browsers */\n        font-family: 'Source Sans Pro', sans-serif;\n        color: white;\n        font-weight: 300;\n    }\n\n    body :-moz-placeholder {\n        /* Mozilla Firefox 4 to 18 */\n        font-family: 'Source Sans Pro', sans-serif;\n        color: white;\n        opacity: 1;\n        font-weight: 300;\n    }\n\n    body ::-moz-placeholder {\n        /* Mozilla Firefox 19+ */\n        font-family: 'Source Sans Pro', sans-serif;\n        color: white;\n        opacity: 1;\n        font-weight: 300;\n    }\n\n    body :-ms-input-placeholder {\n        /* Internet Explorer 10+ */\n        font-family: 'Source Sans Pro', sans-serif;\n        color: white;\n        font-weight: 300;\n    }\n\n.wrapper {\n    background: #50a3a2;\n    /*background: -webkit-linear-gradient(top left, #50a3a2 0%, #53e3a6 100%);*/\n    background: linear-gradient(to bottom right,#127c7b 0,#50a3a2);\n    opacity: 0.8;\n    position: absolute;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    overflow: hidden;\n}\n\n    .wrapper.form-success .containerLogin h1 {\n        -webkit-transform: translateY(85px);\n        -ms-transform: translateY(85px);\n        transform: translateY(85px);\n    }\n\n.containerLogin {\n    max-width: 600px;\n    margin: 0 auto;\n    padding: 80px 0;\n    height: 400px;\n    text-align: center;\n}\n\n    .containerLogin h1 {\n        font-size: 40px;\n        -webkit-transition-duration: 1s;\n        transition-duration: 1s;\n        -webkit-transition-timing-function: ease-in-put;\n        transition-timing-function: ease-in-put;\n        font-weight: 200;\n    }\n\nform {\n    padding: 20px 0;\n    position: relative;\n    z-index: 2;\n}\n\n.login-container {\n    border-radius: 5px;\n    background-clip: padding-box;\n    margin: auto;\n    padding: 35px 35px 15px 35px;\n    border: 1px solid #eaeaea;\n    -webkit-box-shadow: 0 0 25px #cac6c6;\n    box-shadow: 0 0 25px #cac6c6;\n}\n\nform input.login-name, form input.login-pass {\n    -webkit-appearance: none;\n    -moz-appearance: none;\n    appearance: none;\n    outline: 0;\n    border: 1px solid rgba(255, 255, 255, 0.4);\n    background-color: rgba(255, 255, 255, 0.2);\n    width: 250px;\n    max-width: 250px;\n    border-radius: 3px;\n    padding: 10px 15px;\n    margin: 0 auto 10px auto;\n    display: block;\n    text-align: center;\n    font-size: 18px;\n    color: white;\n    -webkit-transition-duration: 0.25s;\n    transition-duration: 0.25s;\n    font-weight: 300;\n}\n\n    form input.login-name:hover, form input.login-pass:hover {\n        background-color: rgba(255, 255, 255, 0.4);\n    }\n\n    form input.login-name:focus, form input.login-pass:focus {\n        background-color: white;\n        width: 300px;\n        color: #53e3a6;\n    }\n\nform button {\n    -webkit-appearance: none;\n    -moz-appearance: none;\n    appearance: none;\n    outline: 0;\n    background-color: rgba(255, 255, 255, 0.2);\n    border: 0;\n    padding: 10px 15px;\n    color: #fff;\n    border-radius: 3px;\n    width: 250px;\n    cursor: pointer;\n    font-size: 18px;\n    -webkit-transition-duration: 0.25s;\n    transition-duration: 0.25s;\n}\n\n\n    form button.login {\n        -webkit-appearance: none;\n        -moz-appearance: none;\n        appearance: none;\n        outline: 0;\n        background-color: white;\n        border: 0;\n        padding: 10px 15px;\n        color: #000;\n        font-weight: bold;\n        border-radius: 3px;\n        width: 250px;\n        cursor: pointer;\n        font-size: 18px;\n        -webkit-transition-duration: 0.25s;\n        transition-duration: 0.25s;\n    }\n\n    form button:hover {\n        background-color: #f5f7f9;\n        color: #53e3a6;\n    }\n\n.to-register {\n    margin: 20px 0;\n}\n\n    .to-register a.register {\n        color: #fff !important;\n        margin-right: 20px;\n    }\n\n.bg-bubbles {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 1;\n}\n\n    .bg-bubbles li {\n        position: absolute;\n        list-style: none;\n        display: block;\n        width: 40px;\n        height: 40px;\n        background-color: rgba(255, 255, 255, 0.15);\n        bottom: -160px;\n        -webkit-animation: square 25s infinite;\n        animation: square 25s infinite;\n        -webkit-transition-timing-function: linear;\n        transition-timing-function: linear;\n    }\n\n        .bg-bubbles li:nth-child(1) {\n            left: 10%;\n        }\n\n        .bg-bubbles li:nth-child(2) {\n            left: 20%;\n            width: 80px;\n            height: 80px;\n            -webkit-animation-delay: 2s;\n            animation-delay: 2s;\n            -webkit-animation-duration: 17s;\n            animation-duration: 17s;\n        }\n\n        .bg-bubbles li:nth-child(3) {\n            left: 25%;\n            -webkit-animation-delay: 4s;\n            animation-delay: 4s;\n        }\n\n        .bg-bubbles li:nth-child(4) {\n            left: 40%;\n            width: 60px;\n            height: 60px;\n            -webkit-animation-duration: 22s;\n            animation-duration: 22s;\n            background-color: rgba(255, 255, 255, 0.25);\n        }\n\n        .bg-bubbles li:nth-child(5) {\n            left: 70%;\n        }\n\n        .bg-bubbles li:nth-child(6) {\n            left: 80%;\n            width: 120px;\n            height: 120px;\n            -webkit-animation-delay: 3s;\n            animation-delay: 3s;\n            background-color: rgba(255, 255, 255, 0.2);\n        }\n\n        .bg-bubbles li:nth-child(7) {\n            left: 32%;\n            width: 160px;\n            height: 160px;\n            -webkit-animation-delay: 7s;\n            animation-delay: 7s;\n        }\n\n        .bg-bubbles li:nth-child(8) {\n            left: 55%;\n            width: 20px;\n            height: 20px;\n            -webkit-animation-delay: 15s;\n            animation-delay: 15s;\n            -webkit-animation-duration: 40s;\n            animation-duration: 40s;\n        }\n\n        .bg-bubbles li:nth-child(9) {\n            left: 25%;\n            width: 10px;\n            height: 10px;\n            -webkit-animation-delay: 2s;\n            animation-delay: 2s;\n            -webkit-animation-duration: 40s;\n            animation-duration: 40s;\n            background-color: rgba(255, 255, 255, 0.3);\n        }\n\n        .bg-bubbles li:nth-child(10) {\n            left: 90%;\n            width: 160px;\n            height: 160px;\n            -webkit-animation-delay: 11s;\n            animation-delay: 11s;\n        }\n\n@-webkit-keyframes square {\n    0% {\n        -webkit-transform: translateY(0);\n        transform: translateY(0);\n    }\n\n    100% {\n        -webkit-transform: translateY(-700px) rotate(600deg);\n        transform: translateY(-700px) rotate(600deg);\n    }\n}\n\n@keyframes square {\n    0% {\n        -webkit-transform: translateY(0);\n        transform: translateY(0);\n    }\n\n    100% {\n        -webkit-transform: translateY(-700px) rotate(600deg);\n        transform: translateY(-700px) rotate(600deg);\n    }\n}\n\n\n.home-from {\n    margin: 60px;\n}\n\n    .home-from a {\n        color: #f9ac4b;\n    }\n\n.pass-with-show div {\n    width: 250px !important;\n    margin: 0 auto !important;\n}\n\n/* fallback */\n@font-face {\n    font-family: 'Material Icons';\n    font-style: normal;\n    font-weight: 400;\n    src: url('fluhrq6tzzclqej-vdg-iuiadsnc.woff2') format('woff2');\n}\n\n.material-icons {\n    font-family: 'Material Icons';\n    font-weight: normal;\n    font-style: normal;\n    font-size: 18px;\n    line-height: 1;\n    letter-spacing: normal;\n    text-transform: none;\n    display: inline-block;\n    white-space: nowrap;\n    word-wrap: normal;\n    direction: ltr;\n    -webkit-font-feature-settings: 'liga';\n    -webkit-font-smoothing: antialiased;\n}\n\n.add-on.input-group-addon {\n    position: absolute;\n    right: 5px;\n    top: 10px;\n}\n\n.pass-with-show input {\n    width: 250px;\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/css/showtip.css",
    "content": ".alert {\n    position: fixed !important;\n    top: 200px !important;\n    left: 50% !important;\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/css/site.css",
    "content": "﻿body {\n  margin-top: 65px;\n}\n.navbar-header {\n  position: relative;\n  top: -4px;\n}\n.navbar-brand > .icon-banner {\n  position: relative;\n  top: -2px;\n  display: inline;\n}\n.icon {\n  position: relative;\n  top: -3px;\n}\n.logged-out iframe {\n  display: none;\n  width: 0;\n  height: 0;\n}\n.page-consent .client-logo {\n  float: left;\n}\n.page-consent .client-logo img {\n  width: 80px;\n  height: 80px;\n}\n.page-consent .consent-buttons {\n  margin-top: 25px;\n}\n.page-consent .consent-form .consent-scopecheck {\n  display: inline-block;\n  margin-right: 5px;\n}\n.page-consent .consent-form .consent-description {\n  margin-left: 25px;\n}\n.page-consent .consent-form .consent-description label {\n  font-weight: normal;\n}\n.page-consent .consent-form .consent-remember {\n  padding-left: 16px;\n}\n.grants .page-header {\n  margin-bottom: 10px;\n}\n.grants .grant {\n  margin-top: 20px;\n  padding-bottom: 20px;\n  border-bottom: 1px solid lightgray;\n}\n.grants .grant img {\n  width: 100px;\n  height: 100px;\n}\n.grants .grant .clientname {\n  font-size: 140%;\n  font-weight: bold;\n}\n.grants .grant .granttype {\n  font-size: 120%;\n  font-weight: bold;\n}\n.grants .grant .created {\n  font-size: 120%;\n  font-weight: bold;\n}\n.grants .grant .expires {\n  font-size: 120%;\n  font-weight: bold;\n}\n.grants .grant li {\n  list-style-type: none;\n  display: inline;\n}\n.grants .grant li:after {\n  content: ', ';\n}\n.grants .grant li:last-child:after {\n  content: '';\n}"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/css/site.less",
    "content": "﻿body {\n    margin-top: 65px;\n}\n\n.navbar-header {\n    position: relative;\n    top: -4px;\n}\n\n.navbar-brand > .icon-banner {\n    position: relative;\n    top: -2px;\n    display: inline;\n}\n\n.icon {\n    position: relative;\n    top: -10px;\n}\n\n.logged-out iframe {\n    display: none;\n    width: 0;\n    height: 0;\n}\n\n.page-consent {\n    .client-logo {\n        float: left;\n\n        img {\n            width: 80px;\n            height: 80px;\n        }\n    }\n\n    .consent-buttons {\n        margin-top: 25px;\n    }\n\n    .consent-form {\n        .consent-scopecheck {\n            display: inline-block;\n            margin-right: 5px;\n        }\n\n        .consent-scopecheck[disabled] {\n            //visibility:hidden;\n        }\n\n        .consent-description {\n            margin-left: 25px;\n\n            label {\n                font-weight: normal;\n            }\n        }\n\n        .consent-remember {\n            padding-left: 16px;\n        }\n    }\n}\n\n.grants {\n    .page-header {\n        margin-bottom: 10px;\n    }\n\n    .grant {\n        margin-top: 20px;\n        padding-bottom: 20px;\n        border-bottom: 1px solid lightgray;\n\n        img {\n            width: 100px;\n            height: 100px;\n        }\n\n        .clientname {\n            font-size: 140%;\n            font-weight: bold;\n        }\n\n        .granttype {\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        .created {\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        .expires {\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        li {\n            list-style-type: none;\n            display: inline;\n\n            &:after {\n                content: ', ';\n            }\n\n            &:last-child:after {\n                content: '';\n            }\n\n            .displayname {\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/css/web.css",
    "content": "/*Common*/\n@media (max-width: 767px) {\n    .menu {\n        text-align: center;\n    }\n\n    .menu-logo {\n        font-size: 1.2em;\n    }\n\n    .menu-item {\n        display: none;\n    }\n\n    .menu-button {\n        display: block;\n    }\n\n    .welcome-block h1 {\n        font-size: 2em;\n    }\n}\n\n@media (min-width: 768px) {\n    .menu-item {\n        display: block;\n    }\n\n    .menu-button {\n        display: none;\n    }\n}\n\n.gravatar-image {\n    max-width: none;\n}\n\n.border-top {\n    border-top: 1px solid #e5e5e5;\n}\n\n.border-bottom {\n    border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.05);\n}\n\n.welcome-block {\n    max-width: 700px;\n}\n\n.logo, .logo:hover {\n    color: black;\n    text-decoration: none;\n}\n\n.col-m-5 {\n    margin: 5px;\n}\n\n.col-m-10 {\n    margin: 10px;\n}\n\n.col-m-15 {\n    margin: 15px;\n}\n\n.col-m-20 {\n    margin: 20px;\n}\n\n.col-m-25 {\n    margin: 25px;\n}\n\n.col-m-30 {\n    margin: 30px;\n}\n\n.col-m-35 {\n    margin: 35px;\n}\n\n.col-m-40 {\n    margin: 40px;\n}\n\n.col-m-45 {\n    margin: 45px;\n}\n\n.col-m-50 {\n    margin: 50px;\n}\n\n.col-m-b-5 {\n    margin-bottom: 5px;\n}\n\n.col-m-b-10 {\n    margin-bottom: 10px;\n}\n\n.col-m-b-15 {\n    margin-bottom: 15px;\n}\n\n.col-m-b-20 {\n    margin-bottom: 20px;\n}\n\n.col-m-b-25 {\n    margin-bottom: 25px;\n}\n\n.col-m-b-30 {\n    margin-bottom: 30px;\n}\n\n.col-m-b-35 {\n    margin-bottom: 35px;\n}\n\n.col-m-b-40 {\n    margin-bottom: 40px;\n}\n\n.col-m-b-45 {\n    margin-bottom: 45px;\n}\n\n.col-m-b-50 {\n    margin-bottom: 50px;\n}\n\n.col-m-t-5 {\n    margin-top: 5px;\n}\n\n.col-m-t-10 {\n    margin-top: 10px;\n}\n\n.col-m-t-15 {\n    margin-top: 15px;\n}\n\n.col-m-t-20 {\n    margin-top: 20px;\n}\n\n.col-m-t-25 {\n    margin-top: 25px;\n}\n\n.col-m-t-30 {\n    margin-top: 30px;\n}\n\n.col-m-t-35 {\n    margin-top: 35px;\n}\n\n.col-m-t-40 {\n    margin-top: 40px;\n}\n\n.col-m-t-45 {\n    margin-top: 45px;\n}\n\n.col-m-t-50 {\n    margin-top: 50px;\n}\n\n.col-m-l-5 {\n    margin-left: 5px;\n}\n\n.col-m-l-10 {\n    margin-left: 10px;\n}\n\n.col-m-l-15 {\n    margin-left: 15px;\n}\n\n.col-m-l-20 {\n    margin-left: 20px;\n}\n\n.col-m-l-25 {\n    margin-left: 25px;\n}\n\n.col-m-l-30 {\n    margin-left: 30px;\n}\n\n.col-m-l-35 {\n    margin-left: 35px;\n}\n\n.col-m-l-40 {\n    margin-left: 40px;\n}\n\n.col-m-l-45 {\n    margin-left: 45px;\n}\n\n.col-m-l-50 {\n    margin-left: 50px;\n}\n\n.col-m-r-5 {\n    margin-right: 5px;\n}\n\n.col-m-r-10 {\n    margin-right: 10px;\n}\n\n.col-m-r-15 {\n    margin-right: 15px;\n}\n\n.col-m-r-20 {\n    margin-right: 20px;\n}\n\n.col-m-r-25 {\n    margin-right: 25px;\n}\n\n.col-m-r-30 {\n    margin-right: 30px;\n}\n\n.col-m-r-35 {\n    margin-right: 35px;\n}\n\n.col-m-r-40 {\n    margin-right: 40px;\n}\n\n.col-m-r-45 {\n    margin-right: 45px;\n}\n\n.col-m-r-50 {\n    margin-right: 50px;\n}\n\n.col-p-5 {\n    padding: 5px;\n}\n\n.col-p-10 {\n    padding: 10px;\n}\n\n.col-p-15 {\n    padding: 15px;\n}\n\n.col-p-20 {\n    padding: 20px;\n}\n\n.col-p-25 {\n    padding: 25px;\n}\n\n.col-p-30 {\n    padding: 30px;\n}\n\n.col-p-35 {\n    padding: 35px;\n}\n\n.col-p-40 {\n    padding: 40px;\n}\n\n.col-p-45 {\n    padding: 45px;\n}\n\n.col-p-50 {\n    padding: 50px;\n}\n\n.col-p-b-5 {\n    padding-bottom: 5px;\n}\n\n.col-p-b-10 {\n    padding-bottom: 10px;\n}\n\n.col-p-b-15 {\n    padding-bottom: 15px;\n}\n\n.col-p-b-20 {\n    padding-bottom: 20px;\n}\n\n.col-p-b-25 {\n    padding-bottom: 25px;\n}\n\n.col-p-b-30 {\n    padding-bottom: 30px;\n}\n\n.col-p-b-35 {\n    padding-bottom: 35px;\n}\n\n.col-p-b-40 {\n    padding-bottom: 40px;\n}\n\n.col-p-b-45 {\n    padding-bottom: 45px;\n}\n\n.col-p-b-50 {\n    padding-bottom: 50px;\n}\n\n.col-p-t-5 {\n    padding-top: 5px;\n}\n\n.col-p-t-10 {\n    padding-top: 10px;\n}\n\n.col-p-t-15 {\n    padding-top: 15px;\n}\n\n.col-p-t-20 {\n    padding-top: 20px;\n}\n\n.col-p-t-25 {\n    padding-top: 25px;\n}\n\n.col-p-t-30 {\n    padding-top: 30px;\n}\n\n.col-p-t-35 {\n    padding-top: 35px;\n}\n\n.col-p-t-40 {\n    padding-top: 40px;\n}\n\n.col-p-t-45 {\n    padding-top: 45px;\n}\n\n.col-p-t-50 {\n    padding-top: 50px;\n}\n\n.col-p-l-5 {\n    padding-left: 5px;\n}\n\n.col-p-l-10 {\n    padding-left: 10px;\n}\n\n.col-p-l-15 {\n    padding-left: 15px;\n}\n\n.col-p-l-20 {\n    padding-left: 20px;\n}\n\n.col-p-l-25 {\n    padding-left: 25px;\n}\n\n.col-p-l-30 {\n    padding-left: 30px;\n}\n\n.col-p-l-35 {\n    padding-left: 35px;\n}\n\n.col-p-l-40 {\n    padding-left: 40px;\n}\n\n.col-p-l-45 {\n    padding-left: 45px;\n}\n\n.col-p-l-50 {\n    padding-left: 50px;\n}\n\n.col-p-r-5 {\n    padding-right: 5px;\n}\n\n.col-p-r-10 {\n    padding-right: 10px;\n}\n\n.col-p-r-15 {\n    padding-right: 15px;\n}\n\n.col-p-r-20 {\n    padding-right: 20px;\n}\n\n.col-p-r-25 {\n    padding-right: 25px;\n}\n\n.col-p-r-30 {\n    padding-right: 30px;\n}\n\n.col-p-r-35 {\n    padding-right: 35px;\n}\n\n.col-p-r-40 {\n    padding-right: 40px;\n}\n\n.col-p-r-45 {\n    padding-right: 45px;\n}\n\n.col-p-r-50 {\n    padding-right: 50px;\n}\n\n.col-form-label {\n    text-align: right;\n    font-weight: bold;\n}\n\n@media (max-width: 575px) {\n    .col-form-label {\n        text-align: left;\n    }\n}\n\n/*Controls*/\n.navbar-brand > img {\n    max-height: 31px;\n}\n\n.navbar-brand.logo {\n    padding: 10px 10px;\n}\n\n.navbar-brand-image-mobile {\n    display: none;\n}\n\n@media (max-width: 767px) {\n    .navbar-brand-image {\n        display: none;\n    }\n\n    .navbar-brand-image-mobile {\n        display: block;\n        padding-left: 0;\n        padding-right: 0;\n    }\n}\n\n.validation-summary-errors {\n    color: #ff3834;\n    border: 1px solid #ffd3d3;\n    background: none;\n    padding-top: 9px;\n    -ms-border-radius: 4px;\n    border-radius: 4px;\n    margin-bottom: 15px;\n    margin-top: 20px;\n}\n\n.switch {\n    display: inline-block;\n    height: 28px;\n    position: relative;\n    width: 60px;\n    margin-top: 5px;\n}\n\n    .switch input {\n        display: none;\n    }\n\n.slider {\n    background-color: #ccc;\n    bottom: 0;\n    cursor: pointer;\n    left: 0;\n    position: absolute;\n    right: 0;\n    top: 0;\n    transition: .4s;\n}\n\n    .slider:before {\n        background-color: #fff;\n        bottom: 4px;\n        content: \"\";\n        height: 20px;\n        left: 7px;\n        position: absolute;\n        transition: .4s;\n        width: 20px;\n    }\n\ninput:checked + .slider {\n    background-color: #007bff;\n}\n\n    input:checked + .slider:before {\n        transform: translateX(26px);\n    }\n\n.slider.round {\n    border-radius: 34px;\n}\n\n    .slider.round:before {\n        border-radius: 50%;\n    }\n\n.picker hr {\n    margin-bottom: 5px;\n}\n\n.picker .button__text {\n    display: inline-block;\n    text-align: center;\n    vertical-align: middle;\n    margin: 3px;\n    border: 1px solid transparent;\n    padding: .375rem .75rem;\n    font-size: 1rem;\n    line-height: 1.5;\n    border-radius: .25rem;\n    border-color: #007bff;\n    color: #007bff;\n}\n\n.picker .button__add {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    margin-right: 5px;\n    white-space: normal;\n    text-transform: none;\n}\n\n.picker .button__delete, .picker .button__update {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    margin-right: 5px;\n    white-space: normal;\n    text-transform: none;\n}\n\n.picker .button__show-all {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    margin-right: 5px;\n    white-space: normal;\n    text-transform: none;\n}\n\n.picker .block__buttons__add {\n    margin-top: 4px;\n}\n\n.picker .search-title {\n    color: gray;\n    font-size: 12px;\n}\n\n#toast-container > div {\n    opacity: 1;\n    -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n    filter: alpha(opacity=100);\n}\n\nlabel.radio-img > input {\n    visibility: hidden;\n    position: absolute;\n}\n\n    label.radio-img > input + img {\n        cursor: pointer;\n        border: 2px solid transparent;\n    }\n\n    label.radio-img > input:checked + img {\n        background-color: #ffe7ac;\n        -ms-border-radius: 15px;\n        border-radius: 15px;\n    }\n\n    label.radio-img > input:checked ~ h3, label.radio-img > input:checked ~ h4 {\n        color: #007bff;\n        text-decoration: underline;\n    }\n\nlabel.radio-img > h3, label > h4 {\n    cursor: pointer;\n}\n\n/*Pages*/\n.client .action-butons {\n    margin: 20px 0 20px 0;\n}\n\n.audit-log-container .modal-dialog {\n    overflow-y: initial !important;\n}\n\n.audit-log-container .modal-body {\n    max-height: calc(100vh - 200px);\n    overflow-y: auto;\n}\n\n.width100p {\n    width: 100% !important;\n}\n\n.content-bd {\n    margin: 0 20px;\n}\n\n.row.grant {\n    border-top: 1px dashed gray;\n    padding-top: 10px;\n}\n\nh5.Grant-Config {\n    font-size: 1.25rem;\n    background: beige;\n    padding: 10px 20px;\n}\n\n.grey888 {\n    color: #888;\n    font-size: 14px;\n}\n\n    .grey888 div {\n        margin: 3px;\n    }\n\n.pwd-qus-tip {\n    font-size: 12px;\n    color: red;\n}\n\n.create-item {\n    width: 300px;\n}\n\na.reset {\n    color: greenyellow !important;\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/Role.js",
    "content": "﻿var Roleid = '';\n\n$(\".viewbtn\").on(\"click\", function () {\n    Roleid = $(this).data('id');\n\n});\n$(\".deletebutton\").on(\"click\", function () {\n    if (Roleid) {\n        $.post(\"/account/roledelete/\" + Roleid, null, function () {\n            history.go(0);\n            ShowSuccess(\"删除成功！\");\n        })\n            .error(function () {\n                $('#DeleteRole').modal('hide');\n                ShowFailure(\"删除失败，无权限！\");\n            });\n\n\n\n    }\n});"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/User.js",
    "content": "﻿var userid = '';\n\n$(\".viewbtn\").on(\"click\", function () {\n    userid = $(this).data('id');\n\n});\n$(\".deletebutton\").on(\"click\", function () {\n    if (userid) {\n        $.post(\"/account/delete/\" + userid, null, function () {\n            history.go(0);\n            ShowSuccess(\"删除成功！\");\n        })\n            .error(function () {\n                $('#DeleteUser').modal('hide');\n                ShowFailure(\"删除失败，无权限！\");\n            });\n\n\n\n    }\n});"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/bootstrap-show-password.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * https://github.com/wenzhixin/bootstrap-show-password\n * version: 1.1.2\n */\n\n!function ($) {\n\n    'use strict';\n\n    // TOOLS DEFINITION\n    // ======================\n\n    // it only does '%s', and return '' when arguments are undefined\n    var sprintf = function(str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        if (flag) {\n            return str;\n        }\n        return '';\n    };\n\n    // PASSWORD CLASS DEFINITION\n    // ======================\n\n    var Password = function(element, options) {\n        this.options   = options;\n        this.$element  = $(element);\n        this.isShown = false;\n\n        this.init();\n    };\n\n    Password.DEFAULTS = {\n        placement: 'after', // 'before' or 'after'\n        white: false, // v2\n        message: 'Click here to show/hide password',\n        eyeClass: 'glyphicon',\n        eyeOpenClass: 'glyphicon-eye-open',\n        eyeCloseClass: 'glyphicon-eye-close',\n        eyeClassPositionInside: false\n    };\n\n    Password.prototype.init = function() {\n        var placementFuc,\n            inputClass; // v2 class\n\n        if (this.options.placement === 'before') {\n            placementFuc = 'insertBefore';\n            inputClass = 'input-prepend';\n        } else {\n            this.options.placement = 'after'; // default to after\n            placementFuc = 'insertAfter';\n            inputClass = 'input-append';\n        }\n\n        // Create the text, icon and assign\n        this.$element.wrap(sprintf('<div class=\"%s input-group\" />', inputClass));\n\n        this.$text = $('<input type=\"text\" />')\n            [placementFuc](this.$element)\n            .attr('class', this.$element.attr('class'))\n            .attr('style', this.$element.attr('style'))\n            .attr('placeholder', this.$element.attr('placeholder'))\n            .css('display', this.$element.css('display'))\n            .val(this.$element.val()).hide();\n\n        // Copy readonly attribute if it's set\n        if (this.$element.prop('readonly'))\n            this.$text.prop('readonly', true);\n        this.$icon = $([\n            '<span tabindex=\"100\" title=\"' + this.options.message + '\" class=\"add-on input-group-addon\">',\n            '<i class=\"icon-eye-open' + (this.options.white ? ' icon-white' : '') +\n                ' ' + this.options.eyeClass + ' ' + (this.options.eyeClassPositionInside ? '' : this.options.eyeOpenClass) + '\">' +\n                (this.options.eyeClassPositionInside ? this.options.eyeOpenClass : '') + '</i>',\n            '</span>'\n        ].join(''))[placementFuc](this.$text).css('cursor', 'pointer');\n\n        // events\n        this.$text.off('keyup').on('keyup', $.proxy(function() {\n            if (!this.isShown) return;\n            this.$element.val(this.$text.val()).trigger('change');\n        }, this));\n\n        this.$icon.off('click').on('click', $.proxy(function() {\n            this.$text.val(this.$element.val()).trigger('change');\n            this.toggle();\n        }, this));\n    };\n\n    Password.prototype.toggle = function(_relatedTarget) {\n        this[!this.isShown ? 'show' : 'hide'](_relatedTarget);\n    };\n\n    Password.prototype.show = function(_relatedTarget) {\n        var e = $.Event('show.bs.password', {relatedTarget: _relatedTarget});\n        this.$element.trigger(e);\n\n        this.isShown = true;\n        this.$element.hide();\n        this.$text.show();\n        if (this.options.eyeClassPositionInside) {\n            this.$icon.find('i')\n                .removeClass('icon-eye-open')\n                .addClass('icon-eye-close')\n                .html(this.options.eyeCloseClass);\n        } else {\n            this.$icon.find('i')\n                .removeClass('icon-eye-open ' + this.options.eyeOpenClass)\n                .addClass('icon-eye-close ' + this.options.eyeCloseClass);\n        }\n\n        // v3 input-group\n        this.$text[this.options.placement](this.$element);\n    };\n\n    Password.prototype.hide = function(_relatedTarget) {\n        var e = $.Event('hide.bs.password', {relatedTarget: _relatedTarget});\n        this.$element.trigger(e);\n\n        this.isShown = false;\n        this.$element.show();\n        this.$text.hide();\n        if (this.options.eyeClassPositionInside) {\n            this.$icon.find('i')\n                .removeClass('icon-eye-close')\n                .addClass('icon-eye-open')\n                .html(this.options.eyeOpenClass);\n        } else {\n            this.$icon.find('i')\n                .removeClass('icon-eye-close ' + this.options.eyeCloseClass)\n                .addClass('icon-eye-open ' + this.options.eyeOpenClass);\n        }\n\n        // v3 input-group\n        this.$element[this.options.placement](this.$text);\n    };\n\n    Password.prototype.val = function (value) {\n        if (typeof value === 'undefined') {\n            return this.$element.val();\n        } else {\n            this.$element.val(value).trigger('change');\n            this.$text.val(value);\n        }\n    };\n\n    Password.prototype.focus = function () {\n        this.$element.focus();\n    };\n\n\n    // PASSWORD PLUGIN DEFINITION\n    // =======================\n\n    var old = $.fn.password;\n\n    $.fn.password = function() {\n        var option = arguments[0],\n            args = arguments,\n\n            value,\n            allowedMethods = [\n                'show', 'hide', 'toggle', 'val', 'focus'\n            ]; // public function\n\n        this.each(function() {\n            var $this = $(this),\n                data = $this.data('bs.password'),\n                options = $.extend({}, Password.DEFAULTS, $this.data(), typeof option === 'object' && option);\n\n            if (typeof option === 'string') {\n                if ($.inArray(option, allowedMethods) < 0) {\n                    throw \"Unknown method: \" + option;\n                }\n                value = data[option](args[1]);\n            } else {\n                if (!data) {\n                    data = new Password($this, options);\n                    $this.data('bs.password', data);\n                } else {\n                    data.init(options);\n                }\n            }\n        });\n\n        return value ? value : this;\n    };\n\n    $.fn.password.Constructor = Password;\n\n\n    // PASSWORD NO CONFLICT\n    // =================\n\n    $.fn.password.noConflict = function() {\n        $.fn.password = old;\n        return this;\n    };\n\n    $(function () {\n        $('[data-toggle=\"password\"]').password();\n    });\n\n}(window.jQuery);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/showTip.js",
    "content": "﻿//tip是提示信息，type:'success'是成功信息，'danger'是失败信息,'info'是普通信息\nfunction ShowTip(tip, type) {\n    var $tip = $('#tip');\n    if ($tip.length == 0) {\n        $tip = $('<span id=\"tip\" style=\"font-weight:bold;position:absolute;top:50px;left: 50%;z-index:9999\"></span>');\n        $('body').append($tip);\n    }\n    $tip.stop(true).attr('class', 'alert alert-' + type).text(tip).css('margin-left', -$tip.outerWidth() / 2).fadeIn(500).delay(2000).fadeOut(500);\n}\n\nfunction ShowMsg(msg) {\n    ShowTip(msg, 'info');\n}\n\nfunction ShowSuccess(msg) {\n    ShowTip(msg, 'success');\n}\n\nfunction ShowFailure(msg) {\n    ShowTip(msg, 'danger');\n}\n\nfunction ShowWarn(msg, $focus, clear) {\n    ShowTip(msg, 'warning');\n    if ($focus) $focus.focus();\n    if (clear) $focus.val('');\n    return false;\n}"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/bootstrap/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  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');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\2a\";\n}\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n    .container {\n        width: 100%;\n        max-width: 1440px;\n    }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.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 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.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 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .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 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .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 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .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 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 14.333333px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 3;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 2;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  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);\n  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);\n  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);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  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);\n  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);\n  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);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  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);\n  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);\n  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);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  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);\n  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);\n  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);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  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);\n  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);\n  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);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  min-height: 16.42857143px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -15px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -15px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/bootstrap/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.5\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.5\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.5'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.5\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.5'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target)\n      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"]') || $(e.target).is('input[type=\"checkbox\"]'))) e.preventDefault()\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.5\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.5'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.5\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.5'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.5\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.5'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown', relatedTarget)\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.5\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.5'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.5\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.5'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      that.$element\n        .removeAttr('aria-describedby')\n        .trigger('hidden.bs.' + that.type)\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.5\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.5'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.5\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.5'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.5\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.5'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.5\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.5'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/.bower.json",
    "content": "{\n  \"name\": \"jquery-validation\",\n  \"homepage\": \"http://jqueryvalidation.org/\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/jzaefferer/jquery-validation.git\"\n  },\n  \"authors\": [\n    \"Jörn Zaefferer <joern.zaefferer@gmail.com>\"\n  ],\n  \"description\": \"Form validation made easy\",\n  \"main\": \"dist/jquery.validate.js\",\n  \"keywords\": [\n    \"forms\",\n    \"validation\",\n    \"validate\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"demo\",\n    \"lib\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">= 1.7.2\"\n  },\n  \"version\": \"1.14.0\",\n  \"_release\": \"1.14.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"1.14.0\",\n    \"commit\": \"c1343fb9823392aa9acbe1c3ffd337b8c92fed48\"\n  },\n  \"_source\": \"https://github.com/jzaefferer/jquery-validation.git\",\n  \"_target\": \"1.14.0\",\n  \"_originalSource\": \"jquery-validation\"\n}"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/CONTRIBUTING.md",
    "content": "# Contributing to the jQuery Validation Plugin\n\n## Reporting an Issue\n\n1. Make sure the problem you're addressing is reproducible.\n2. Use http://jsbin.com or http://jsfiddle.net to provide a test page.\n3. Indicate what browsers the issue can be reproduced in. **Note: IE Compatibilty mode issues will not be addressed. Make sure you test in a real browser!**\n4. What version of the plug-in is the issue reproducible in. Is it reproducible after updating to the latest version.\n\nDocumentation issues are also tracked at the [jQuery Validation](https://github.com/jzaefferer/jquery-validation/issues) issue tracker.\nPull Requests to improve the docs are welcome at the [jQuery Validation docs](https://github.com/jzaefferer/validation-content) repository, though.\n\n**IMPORTANT NOTE ABOUT EMAIL VALIDATION**. As of version 1.12.0 this plugin is using the same regular expression that the [HTML5 specification suggests for browsers to use](https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address). We will follow their lead and use the same check. If you think the specification is wrong, please report the issue to them. If you have different requirements, consider [using a custom method](http://jqueryvalidation.org/jQuery.validator.addMethod/).\n\n## Contributing code\n\nThanks for contributing! Here's a few guidelines to help your contribution get landed.\n\n1. Make sure the problem you're addressing is reproducible. Use jsbin.com or jsfiddle.net to provide a test page.\n2. Follow the [jQuery style guide](http://contribute.jquery.com/style-guides/js)\n3. Add or update unit tests along with your patch. Run the unit tests in at least one browser (see below).\n4. Run `grunt` (see below) to check for linting and a few other issues.\n5. Describe the change in your commit message and reference the ticket, like this: \"Demos: Fixed delegate bug for dynamic-totals demo. Fixes #51\". If you're adding a new localization file, use something like this: \"Localization: Added croatian (HR) localization\"\n\n## Build setup\n\n1. Install [NodeJS](http://nodejs.org).\n2. Install the Grunt CLI To install by running `npm install -g grunt-cli`. More details are available on their website http://gruntjs.com/getting-started.\n3. Install the NPM dependencies by running `npm install`.\n4. The build can now be called by running `grunt`.\n\n## Creating a new Additional Method\n\nIf you've wrote custom methods that you'd like to contribute to additional-methods.js:\n\n1. Create a branch\n2. Add the method as a new file in `src/additional`\n3. (Optional) Add translations to `src/localization`\n4. Send a pull request to the master branch.\n\n## Unit Tests\n\nTo run unit tests, just open `test/index.html` within your browser. Make sure you ran `npm install` before so all required dependencies are available.\nStart with one browser while developing the fix, then run against others before committing. Usually latest Chrome, Firefox, Safari and Opera and a few IEs.\n\n## Documentation\n\nPlease report documentation issues at the [jQuery Validation](https://github.com/jzaefferer/jquery-validation/issues) issue tracker.\nIn case your pull request implements or changes public API it would be a plus you would provide a pull request against the [jQuery Validation docs](https://github.com/jzaefferer/validation-content) repository.\n\n## Linting\n\nTo run JSHint and other tools, use `grunt`.\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/Gruntfile.js",
    "content": "/*jshint node:true*/\nmodule.exports = function(grunt) {\n\n\"use strict\";\n\nvar banner,\n\tumdStart,\n\tumdMiddle,\n\tumdEnd,\n\tumdStandardDefine,\n\tumdAdditionalDefine,\n\tumdLocalizationDefine;\n\nbanner = \"/*!\\n\" +\n\t\" * jQuery Validation Plugin v<%= pkg.version %>\\n\" +\n\t\" *\\n\" +\n\t\" * <%= pkg.homepage %>\\n\" +\n\t\" *\\n\" +\n\t\" * Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>\\n\" +\n\t\" * Released under the <%= _.pluck(pkg.licenses, 'type').join(', ') %> license\\n\" +\n\t\" */\\n\";\n\n// define UMD wrapper variables\n\numdStart = \"(function( factory ) {\\n\" +\n\t\"\\tif ( typeof define === \\\"function\\\" && define.amd ) {\\n\";\n\numdMiddle = \"\\t} else {\\n\" +\n\t\"\\t\\tfactory( jQuery );\\n\" +\n\t\"\\t}\\n\" +\n\t\"}(function( $ ) {\\n\\n\";\n\numdEnd = \"\\n}));\";\n\numdStandardDefine = \"\\t\\tdefine( [\\\"jquery\\\"], factory );\\n\";\numdAdditionalDefine = \"\\t\\tdefine( [\\\"jquery\\\", \\\"./jquery.validate\\\"], factory );\\n\";\numdLocalizationDefine = \"\\t\\tdefine( [\\\"jquery\\\", \\\"../jquery.validate\\\"], factory );\\n\";\n\ngrunt.initConfig({\n\tpkg: grunt.file.readJSON(\"package.json\"),\n\tconcat: {\n\t\t// used to copy to dist folder\n\t\tdist: {\n\t\t\toptions: {\n\t\t\t\tbanner: banner +\n\t\t\t\t\tumdStart +\n\t\t\t\t\tumdStandardDefine +\n\t\t\t\t\tumdMiddle,\n\t\t\t\tfooter: umdEnd\n\t\t\t},\n\t\t\tfiles: {\n\t\t\t\t\"dist/jquery.validate.js\": [ \"src/core.js\", \"src/*.js\" ]\n\t\t\t}\n\t\t},\n\t\textra: {\n\t\t\toptions: {\n\t\t\t\tbanner: banner +\n\t\t\t\t\tumdStart +\n\t\t\t\t\tumdAdditionalDefine +\n\t\t\t\t\tumdMiddle,\n\t\t\t\tfooter: umdEnd\n\t\t\t},\n\t\t\tfiles: {\n\t\t\t\t\"dist/additional-methods.js\": [ \"src/additional/additional.js\", \"src/additional/*.js\" ]\n\t\t\t}\n\t\t}\n\t},\n\tuglify: {\n\t\toptions: {\n\t\t\tpreserveComments: false,\n\t\t\tbanner: \"/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - \" +\n\t\t\t\t\"<%= grunt.template.today('m/d/yyyy') %>\\n\" +\n\t\t\t\t\" * <%= pkg.homepage %>\\n\" +\n\t\t\t\t\" * Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;\" +\n\t\t\t\t\" Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */\\n\"\n\t\t},\n\t\tdist: {\n\t\t\tfiles: {\n\t\t\t\t\"dist/additional-methods.min.js\": \"dist/additional-methods.js\",\n\t\t\t\t\"dist/jquery.validate.min.js\": \"dist/jquery.validate.js\"\n\t\t\t}\n\t\t},\n\t\tall: {\n\t\t\texpand: true,\n\t\t\tcwd: \"dist/localization\",\n\t\t\tsrc: \"**/*.js\",\n\t\t\tdest: \"dist/localization\",\n\t\t\text: \".min.js\"\n\t\t}\n\t},\n\tcompress: {\n\t\tdist: {\n\t\t\toptions: {\n\t\t\t\tmode: \"zip\",\n\t\t\t\tlevel: 1,\n\t\t\t\tarchive: \"dist/<%= pkg.name %>-<%= pkg.version %>.zip\",\n\t\t\t\tpretty: true\n\t\t\t},\n\t\t\tsrc: [\n\t\t\t\t\"changelog.txt\",\n\t\t\t\t\"demo/**/*.*\",\n\t\t\t\t\"dist/**/*.js\",\n\t\t\t\t\"Gruntfile.js\",\n\t\t\t\t\"lib/**/*.*\",\n\t\t\t\t\"package.json\",\n\t\t\t\t\"README.md\",\n\t\t\t\t\"src/**/*.*\",\n\t\t\t\t\"test/**/*.*\"\n\t\t\t]\n\t\t}\n\t},\n\tqunit: {\n\t\tfiles: \"test/index.html\"\n\t},\n\tjshint: {\n\t\toptions: {\n\t\t\tjshintrc: true\n\t\t},\n\t\tcore: {\n\t\t\tsrc: \"src/**/*.js\"\n\t\t},\n\t\ttest: {\n\t\t\tsrc: \"test/*.js\"\n\t\t},\n\t\tgrunt: {\n\t\t\tsrc: \"Gruntfile.js\"\n\t\t}\n\t},\n\twatch: {\n\t\toptions: {\n\t\t\tatBegin: true\n\t\t},\n\t\tsrc: {\n\t\t\tfiles: \"<%= jshint.core.src %>\",\n\t\t\ttasks: [\n\t\t\t\t\"concat\"\n\t\t\t]\n\t\t}\n\t},\n\tjscs: {\n\t\tall: [ \"<%= jshint.core.src %>\", \"<%= jshint.test.src %>\", \"<%= jshint.grunt.src %>\" ]\n\t},\n\tcopy: {\n\t\tdist: {\n\t\t\toptions: {\n\t\t\t\t// append UMD wrapper\n\t\t\t\tprocess: function( content ) {\n\t\t\t\t\treturn umdStart + umdLocalizationDefine + umdMiddle + content + umdEnd;\n\t\t\t\t}\n\t\t\t},\n\t\t\tsrc: \"src/localization/*\",\n\t\t\tdest: \"dist/localization\",\n\t\t\texpand: true,\n\t\t\tflatten: true,\n\t\t\tfilter: \"isFile\"\n\t\t}\n\t},\n\treplace: {\n\t\tdist: {\n\t\t\tsrc: \"dist/**/*.min.js\",\n\t\t\toverwrite: true,\n\t\t\treplacements: [\n\t\t\t\t{\n\t\t\t\t\tfrom: \"./jquery.validate\",\n\t\t\t\t\tto: \"./jquery.validate.min\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n});\n\ngrunt.loadNpmTasks(\"grunt-contrib-jshint\");\ngrunt.loadNpmTasks(\"grunt-contrib-qunit\");\ngrunt.loadNpmTasks(\"grunt-contrib-uglify\");\ngrunt.loadNpmTasks(\"grunt-contrib-concat\");\ngrunt.loadNpmTasks(\"grunt-contrib-compress\");\ngrunt.loadNpmTasks(\"grunt-contrib-watch\");\ngrunt.loadNpmTasks(\"grunt-jscs\");\ngrunt.loadNpmTasks(\"grunt-contrib-copy\");\ngrunt.loadNpmTasks(\"grunt-text-replace\");\n\ngrunt.registerTask(\"default\", [ \"concat\", \"copy\", \"jscs\", \"jshint\", \"qunit\" ]);\ngrunt.registerTask(\"release\", [ \"default\", \"uglify\", \"replace\", \"compress\" ]);\ngrunt.registerTask(\"start\", [ \"concat\", \"watch\" ]);\n\n};\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/LICENSE.md",
    "content": "The MIT License (MIT)\n=====================\n\nCopyright Jörn Zaefferer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/README.md",
    "content": "[jQuery Validation Plugin](http://jqueryvalidation.org/) - Form validation made easy\n================================\n\n[![Build Status](https://secure.travis-ci.org/jzaefferer/jquery-validation.png)](http://travis-ci.org/jzaefferer/jquery-validation)\n[![devDependency Status](https://david-dm.org/jzaefferer/jquery-validation/dev-status.png?theme=shields.io)](https://david-dm.org/jzaefferer/jquery-validation#info=devDependencies)\n\nThe jQuery Validation Plugin provides drop-in validation for your existing forms, while making all kinds of customizations to fit your application really easy.\n\n## [Help the project](http://pledgie.com/campaigns/18159)\n\n[![Help the project](http://www.pledgie.com/campaigns/18159.png?skin_name=chrome)](http://pledgie.com/campaigns/18159)\n\nThis project is looking for help! [You can donate to the ongoing pledgie campaign](http://pledgie.com/campaigns/18159)\nand help spread the word. If you've used the plugin, or plan to use, consider a donation - any amount will help.\n\nYou can find the plan for how to spend the money on the [pledgie page](http://pledgie.com/campaigns/18159).\n\n## Getting Started\n\n### Downloading the prebuilt files\n\nPrebuilt files can be downloaded from http://jqueryvalidation.org/\n\n### Downloading the latest changes\n\nThe unreleased development files can be obtained by:\n\n 1. [Downloading](https://github.com/jzaefferer/jquery-validation/archive/master.zip) or Forking this repository\n 2. [Setup the build](CONTRIBUTING.md#build-setup)\n 3. Run `grunt` to create the built files in the \"dist\" directory\n\n### Including it on your page\n\nInclude jQuery and the plugin on a page. Then select a form to validate and call the `validate` method.\n\n```html\n<form>\n\t<input required>\n</form>\n<script src=\"jquery.js\"></script>\n<script src=\"jquery.validate.js\"></script>\n<script>\n$(\"form\").validate();\n</script>\n```\n\nAlternatively include jQuery and the plugin via requirejs in your module.\n\n```js\ndefine([\"jquery\", \"jquery.validate\"], function( $ ) {\n\t$(\"form\").validate();\n});\n```\n\nFor more information on how to setup a rules and customizations, [check the documentation](http://jqueryvalidation.org/documentation/).\n\n## Reporting issues and contributing code\n\nSee the [Contributing Guidelines](CONTRIBUTING.md) for details.\n\n**IMPORTANT NOTE ABOUT EMAIL VALIDATION**. As of version 1.12.0 this plugin is using the same regular expression that the [HTML5 specification suggests for browsers to use](https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address). We will follow their lead and use the same check. If you think the specification is wrong, please report the issue to them. If you have different requirements, consider [using a custom method](http://jqueryvalidation.org/jQuery.validator.addMethod/).\n\n## License\nCopyright &copy; Jörn Zaefferer<br>\nLicensed under the MIT license.\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/bower.json",
    "content": "{\n\t\"name\": \"jquery-validation\",\n\t\"homepage\": \"http://jqueryvalidation.org/\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"git://github.com/jzaefferer/jquery-validation.git\"\n\t},\n\t\"authors\": [\n\t\t\"Jörn Zaefferer <joern.zaefferer@gmail.com>\"\n\t],\n\t\"description\": \"Form validation made easy\",\n\t\"main\": \"dist/jquery.validate.js\",\n\t\"keywords\": [\n\t\t\"forms\",\n\t\t\"validation\",\n\t\t\"validate\"\n\t],\n\t\"license\": \"MIT\",\n\t\"ignore\": [\n\t\t\"**/.*\",\n\t\t\"node_modules\",\n\t\t\"bower_components\",\n\t\t\"test\",\n\t\t\"demo\",\n\t\t\"lib\"\n\t],\n\t\"dependencies\": {\n\t\t\"jquery\": \">= 1.7.2\"\n\t},\n\t\"version\": \"1.14.0\"\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/changelog.md",
    "content": "1.14.0 / 2015-06-30\n==================\n\n## Core\n  * Remove unused removeAttrs method\n  * Replace regex for url method\n  * Remove bad url param in $.ajax, overwritten by $.extend\n  * Properly handle nested cancel submit button\n  * Fix indent\n  * Refactor attributeRules and dataRules to share noramlizer\n  * dataRules method to convert value to number for number inputs\n  * Update url method to allow for protocol-relative URLs\n  * Remove deprecated $.format placeholder\n  * Use jQuery 1.7+ on/off, add destroy method\n  * IE8 compatibility changed .indexOf to $.inArray\n  * Cast NaN value attributes to undefined for Opera Mini\n  * Stop trimming value inside required method\n  * Use :disabled selector to match disabled elements\n  * Exclude some keyboard keys to prevent revalidating the field\n  * Do not search the whole DOM for radio/checkbox elements\n  * Throw better errors for bad rule methods\n  * Fixed number validation error\n  * Fix reference to whatwg spec\n  * Focus invalid element when validating a custom set of inputs\n  * Reset element styles when using custom highlight methods\n  * Escape dollar sign in error id\n  * Revert \"Ignore readonly as well as disabled fields.\"\n  * Update link in comment for Luhn algorithm\n\n## Additionals\n  * Update dateITA to address timezone issue\n  * Fix extension method to only method period\n  * Fix accept method to match period only\n  * Update time method to allow single digit hour\n  * Drop bad test for notEqualTo method\n  * Add notEqualTo method\n  * Use correct jQuery reference via `$`\n  * Remove useless regex check in iban method\n  * Brazilian CPF number\n\n## Localization\n  * Update messages_tr.js\n  * Update messages_sr_lat.js\n  * Adding Perú Spanish (ES PE)\n  * Adding Georgian (ქართული, ge)\n  * Fixed typo in catalan translation\n  * Improve Finnish (fi) translation\n  * Add armenian (hy_AM) locale\n  * Extend italian (it) translation with currency method\n  * Add bn_BD locale\n  * Update zh locale\n  * Remove full stop at the end of italian messages\n\n1.13.1 / 2014-10-14\n==================\n\n## Core\n  * Allow 0 as value for autoCreateRanges\n  * Apply ignore setting to all validationTargetFor elements\n  * Don't trim value in min/max/rangelength methods\n  * Escape id/name before using it as a selector in errorsFor\n  * Explicit default for focusCleanup option\n  * Fix incorrect regexp for describedby matcher\n  * Ignore readonly as well as disabled fields\n  * Improve id escaping, store escaped id in describedby\n  * Use return value of submitHandler to allow or prevent form submit\n\n## Additionals\n  * Add postalcodeBR method\n  * Fix pattern method when parameter is a string\n\n\n1.13.0 / 2014-07-01\n==================\n\n## All\n* Add plugin UMD wrapper\n\n## Core\n* Respect non-error aria-describedby and empty hidden errors\n* Improve dateISO RegExp\n* Added radio/checkbox to delegate click-event\n* Use aria-describedby for non-label elements\n* Register focusin, focusout and keyup also on radio/checkbox\n* Fix normalization for rangelength attribute value\n* Update elementValue method to deal with type=\"number\" fields\n* Use charAt instead of array notation on strings, to support IE8(?)\n\n## Localization\n* Fix sk translation of rangelength method\n* Add Finnish methods\n* Fixed GL number validation message\n* Fixed ES number method validation message\n* Added galician (GL)\n* Fixed French messages for min and max methods\n\n## Additionals\n* Add statesUS method\n* Fix dateITA method to deal with DST bug\n* Add persian date method\n* Add postalCodeCA method\n* Add postalcodeIT method\n\n1.12.0 / 2014-04-01\n==================\n\n* Add ARIA testing ([3d5658e](https://github.com/jzaefferer/jquery-validation/commit/3d5658e9e4825fab27198c256beed86f0bd12577))\n* Add es-AR localization messages. ([7b30beb](https://github.com/jzaefferer/jquery-validation/commit/7b30beb8ebd218c38a55d26a63d529e16035c7a2))\n* Add missing dots to 'es' and 'es_AR' messages. ([a2a653c](https://github.com/jzaefferer/jquery-validation/commit/a2a653cb68926ca034b4b09d742d275db934d040))\n* Added Indonesian (ID) localization ([1d348bd](https://github.com/jzaefferer/jquery-validation/commit/1d348bdcb65807c71da8d0bfc13a97663631cd3a))\n* Added NIF, NIE and CIF Spanish documents numbers validation ([#830](https://github.com/jzaefferer/jquery-validation/issues/830), [317c20f](https://github.com/jzaefferer/jquery-validation/commit/317c20fa9bb772770bb9b70d46c7081d7cfc6545))\n* Added the current form to the context of the remote ajax request ([0a18ae6](https://github.com/jzaefferer/jquery-validation/commit/0a18ae65b9b6d877e3d15650a5c2617a9d2b11d5))\n* Additionals: Update IBAN method, trim trailing whitespaces ([#970](https://github.com/jzaefferer/jquery-validation/issues/970), [347b04a](https://github.com/jzaefferer/jquery-validation/commit/347b04a7d4e798227405246a5de3fc57451d52e1))\n* BIC method: Improve RegEx, {1} is always redundant. Closes gh-744 ([5cad6b4](https://github.com/jzaefferer/jquery-validation/commit/5cad6b493575e8a9a82470d17e0900c881130873))\n* Bower: Add Bower.json for package registration ([e86ccb0](https://github.com/jzaefferer/jquery-validation/commit/e86ccb06e301613172d472cf15dd4011ff71b398))\n* Changes dollar references to 'jQuery', for compability with jQuery.noConflict. Closes gh-754 ([2049afe](https://github.com/jzaefferer/jquery-validation/commit/2049afe46c1be7b3b89b1d9f0690f5bebf4fbf68))\n* Core: Add \"method\" field to error list entry ([89a15c7](https://github.com/jzaefferer/jquery-validation/commit/89a15c7a4b17fa2caaf4ff817f09b04c094c3884))\n* Core: Added support for generic messages via data-msg attribute ([5bebaa5](https://github.com/jzaefferer/jquery-validation/commit/5bebaa5c55c73f457c0e0181ec4e3b0c409e2a9d))\n* Core: Allow attributes to have a value of zero (eg min='0') ([#854](https://github.com/jzaefferer/jquery-validation/issues/854), [9dc0d1d](https://github.com/jzaefferer/jquery-validation/commit/9dc0d1dd946b2c6178991fb16df0223c76162579))\n* Core: Disable deprecated $.format ([#755](https://github.com/jzaefferer/jquery-validation/issues/755), [bf3b350](https://github.com/jzaefferer/jquery-validation/commit/bf3b3509140ea8ab5d83d3ec58fd9f1d7822efc5))\n* Core: Fix support for multiple error classes ([c1f0baf](https://github.com/jzaefferer/jquery-validation/commit/c1f0baf36c21ca175bbc05fb9345e5b44b094821))\n* Core: Ignore events on ignored elements ([#700](https://github.com/jzaefferer/jquery-validation/issues/700), [a864211](https://github.com/jzaefferer/jquery-validation/commit/a86421131ea69786ee9e0d23a68a54a7658ccdbf))\n* Core: Improve elementValue method ([6c041ed](https://github.com/jzaefferer/jquery-validation/commit/6c041edd21af1425d12d06cdd1e6e32a78263e82))\n* Core: Make element() handle ignored elements properly. ([3f464a8](https://github.com/jzaefferer/jquery-validation/commit/3f464a8da49dbb0e4881ada04165668e4a63cecb))\n* Core: Switch dataRules parsing to W3C HTML5 spec style ([460fd22](https://github.com/jzaefferer/jquery-validation/commit/460fd22b6c84a74c825ce1fa860c0a9da20b56bb))\n* Core: Trigger success on optional but have other successful validators ([#851](https://github.com/jzaefferer/jquery-validation/issues/851), [f93e1de](https://github.com/jzaefferer/jquery-validation/commit/f93e1deb48ec8b3a8a54e946a37db2de42d3aa2a))\n* Core: Use plain element instead of un-wrapping the element again ([03cd4c9](https://github.com/jzaefferer/jquery-validation/commit/03cd4c93069674db5415a0bf174a5870da47e5d2))\n* Core: make sure remote is executed last ([#711](https://github.com/jzaefferer/jquery-validation/issues/711), [ad91b6f](https://github.com/jzaefferer/jquery-validation/commit/ad91b6f388b7fdfb03b74e78554cbab9fd8fca6f))\n* Demo: Use correct option in multipart demo. ([#1025](https://github.com/jzaefferer/jquery-validation/issues/1025), [070edc7](https://github.com/jzaefferer/jquery-validation/commit/070edc7be4de564cb74cfa9ee4e3f40b6b70b76f))\n* Fix $/jQuery usage in additional methods. Fixes #839 ([#839](https://github.com/jzaefferer/jquery-validation/issues/839), [59bc899](https://github.com/jzaefferer/jquery-validation/commit/59bc899e4586255a4251903712e813c21d25b3e1))\n* Improve Chinese translations ([1a0bfe3](https://github.com/jzaefferer/jquery-validation/commit/1a0bfe32b16f8912ddb57388882aa880fab04ffe))\n* Initial ARIA-Required implementation ([bf3cfb2](https://github.com/jzaefferer/jquery-validation/commit/bf3cfb234ede2891d3f7e19df02894797dd7ba5e))\n* Localization: change accept values to extension. Fixes #771, closes gh-793. ([#771](https://github.com/jzaefferer/jquery-validation/issues/771), [12edec6](https://github.com/jzaefferer/jquery-validation/commit/12edec66eb30dc7e86756222d455d49b34016f65))\n* Messages: Add icelandic localization ([dc88575](https://github.com/jzaefferer/jquery-validation/commit/dc885753c8872044b0eaa1713cecd94c19d4c73d))\n* Messages: Add missing dots to 'bg', 'fr' and 'sr' messages. ([adbc636](https://github.com/jzaefferer/jquery-validation/commit/adbc6361c377bf6b74c35df9782479b1115fbad7))\n* Messages: Create messages_sr_lat.js ([f2f9007](https://github.com/jzaefferer/jquery-validation/commit/f2f90076518014d98495c2a9afb9a35d45d184e6))\n* Messages: Create messages_tj.js ([de830b3](https://github.com/jzaefferer/jquery-validation/commit/de830b3fd8689a7384656c17565ee92c2878d8a5))\n* Messages: Fix sr_lat translation, add missing space ([880ba1c](https://github.com/jzaefferer/jquery-validation/commit/880ba1ca545903a41d8c5332fc4038a7e9a580bd))\n* Messages: Update messages_sr.js, fix missing space ([10313f4](https://github.com/jzaefferer/jquery-validation/commit/10313f418c18ea75f385248468c2d3600f136cfb))\n* Methods: Add additional method for currency ([1a981b4](https://github.com/jzaefferer/jquery-validation/commit/1a981b440346620964c87ebdd0fa03246348390e))\n* Methods: Adding Smart Quotes to stripHTML's punctuation removal ([aa0d624](https://github.com/jzaefferer/jquery-validation/commit/aa0d6241c3ea04663edc1e45ed6e6134630bdd2f))\n* Methods: Fix dateITA method, avoiding summertime errors ([279b932](https://github.com/jzaefferer/jquery-validation/commit/279b932c1267b7238e6652880b7846ba3bbd2084))\n* Methods: Localized methods for chilean culture (es-CL) ([cf36b93](https://github.com/jzaefferer/jquery-validation/commit/cf36b933499e435196d951401221d533a4811810))\n* Methods: Update email to use HTML5 regex, remove email2 method ([#828](https://github.com/jzaefferer/jquery-validation/issues/828), [dd162ae](https://github.com/jzaefferer/jquery-validation/commit/dd162ae360639f73edd2dcf7a256710b2f5a4e64))\n* Pattern method: Remove delimiters, since HTML5 implementations don't include those either. ([37992c1](https://github.com/jzaefferer/jquery-validation/commit/37992c1c9e2e0be8b315ccccc2acb74863439d3e))\n* Restricting credit card validator to include length check. Closes gh-772 ([f5f47c5](https://github.com/jzaefferer/jquery-validation/commit/f5f47c5c661da5b0c0c6d59d169e82230928a804))\n* Update messages_ko.js - closes gh-715 ([5da3085](https://github.com/jzaefferer/jquery-validation/commit/5da3085ff02e0e6ecc955a8bfc3bb9a8d220581b))\n* Update messages_pt_BR.js. Closes gh-782 ([4bf813b](https://github.com/jzaefferer/jquery-validation/commit/4bf813b751ce34fac3c04eaa2e80f75da3461124))\n* Update phonesUK and mobileUK to accept new prefixes. Closes gh-750 ([d447b41](https://github.com/jzaefferer/jquery-validation/commit/d447b41b830dee984be21d8281ec7b87a852001d))\n* Verify nine-digit zip codes. Closes gh-726 ([165005d](https://github.com/jzaefferer/jquery-validation/commit/165005d4b5780e22d13d13189d107940c622a76f))\n* phoneUS: Add N11 exclusions. Closes gh-861 ([519bbc6](https://github.com/jzaefferer/jquery-validation/commit/519bbc656bcb26e8aae5166d7b2e000014e0d12a))\n* resetForm should clear any aria-invalid values ([4f8a631](https://github.com/jzaefferer/jquery-validation/commit/4f8a631cbe84f496ec66260ada52db2aa0bb3733))\n* valid(): Check all elements. Fixes #791 - valid() validates only the first (invalid) element ([#791](https://github.com/jzaefferer/jquery-validation/issues/791), [6f26803](https://github.com/jzaefferer/jquery-validation/commit/6f268031afaf4e155424ee74dd11f6c47fbb8553))\n\n1.11.1 / 2013-03-22\n==================\n\n  * Revert to also converting parameters of range method to numbers. Closes gh-702\n  * Replace most usage of PHP with mockjax handlers. Do some demo cleanup as well, update to newer masked-input plugin. Keep captcha demo in PHP. Fixes #662\n  * Remove inline code highlighting from milk demo. View source works fine.\n  * Fix dynamic-totals demo by trimming whitespace from template content before passing to jQuery constructor\n  * Fix min/max validation. Closes gh-666. Fixes #648\n  * Fixed 'messages' coming up as a rule and causing an exception after being updated through rules(\"add\"). Closes gh-670, fixes #624\n  * Add Korean (ko) localization. Closes gh-671\n  * Improved the UK postcode method to filter out more invalid postcodes. Closes #682\n  * Update messages_sv.js. Closes #683\n  * Change grunt link to the project website. Closes #684\n  * Move remote method down the list to run last, after all other methods applied to a field. Fixes #679\n  * Update plugin.json description, should include the word 'validate'\n  * Fix typos\n  * Fix jQuery loader to use path of itself. Fixes nested demos.\n  * Update grunt-contrib-qunit to make use of PhantomJS 1.8, when installed through node module 'phantomjs'\n  * Make valid() return a boolean instead of 0 or 1. Fixes #109 - valid() does not return boolean value\n\n1.11.0 / 2013-02-04\n==================\n\n  * Remove clearing as numbers of `min`, `max` and `range` rules. Fixes #455. Closes gh-528.\n  * Update pre-existing labels - fixes #430 closes gh-436\n  * Fix $.validator.format to avoid group interpolation, where at least IE8/9 replaces -bash with the match. Fixes #614\n  * Fix mimetype regex\n  * Add plugin manifest and update headers to just MIT license, drop unnecessary dual-licensing (like jQuery).\n  * Hebrew messages: Removed dots at end of sentences - Fixes gh-568\n  * French translation for require_from_group validation. Fixes gh-573.\n  * Allow groups to be an array or a string - Fixes #479\n  * Removed spaces with multiple MIME types\n  * Fix some date validations, JS syntax errors.\n  * Remove support for metadata plugin, replace with data-rule- and data-msg- (added in 907467e8) properties.\n  * Added sftp as a valid url-pattern\n  * Add Malay (my) localization\n  * Update localization/messages_hu.js\n  * Remove focusin/focusout polyfill. Fixes #542 - Inclusion of jquery.validate interfers with focusin and focusout events in IE9\n  * Localization: Fixed typo in finnish translation\n  * Fix RTM demo to show invalid icon when going from valid back to invalid\n  * Fixed premature return in remote function which prevented ajax call from being made in case an input was entered too quickly. Ensures remote validation always validates the newest value.\n  * Undo fix for #244. Fixes #521 - E-mail validation fires immediately when text is in the field.\n\n1.10.0 / 2012-09-07\n===================\n\n  * Corrected French strings for nowhitespace, phoneUS, phoneUK and mobileUK based upon community feedback.\n  * rename files for language_REGION according to the standard ISO_3166-1 (http://en.wikipedia.org/wiki/ISO_3166-1), for Taiwan tha language is Chinese (zh) and the region is Taiwan (TW)\n  * Optimise RegEx patterns, especially for UK phone numbers.\n  * Add Language Name for each file, rename the language code according to the standard ISO 639 for Estonian, Georgian, Ukrainian and Chinese (http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)\n  * Added croatian (HR) localization\n  * Existing French translations were edited and French translations for the additional methods were added.\n  * Merged in changes for specifying custom error messages in data attributes\n  * Updated UK Mobile phone number regex for new numbers. Fixes #154\n  * Add element to success call with test. Fixes #60\n  * Fixed regex for time additional method. Fixes #131\n  * resetForm now clears old previousValue on form elements. Fixes #312\n  * Added checkbox test to require_from_group and changed require_from_group to use elementValue. Fixes #359\n  * Fixed dataFilter response issues in jQuery 1.5.2+. Fixes #405\n  * Added jQuery Mobile demo. Fixes #249\n  * Deoptimize findByName for correctness. Fixes #82 - $.validator.prototype.findByName breaks in IE7\n  * Added US zip code support and test. Fixes #90\n  * Changed lastElement to lastActive in keyup, skip validation on tab or empty element. Fixes #244\n  * Removed number stripping from stripHtml. Fixes #2\n  * Fixed invalid count on invalid to valid remote validation. Fixes #286\n  * Add link to file_input to demo index\n  * Moved old accept method to extension additional-method, added new accept method to handle standard browser mimetype filtering. Fixes #287 and supersedes #369\n  * Disables blur event when onfocusout is set to false. Test added.\n  * Fixed value issue for radio buttons and checkboxes. Fixes #363\n  * Added test for rangeWords and fixed regex and bounds in method. Fixes #308\n  * Fixed TinyMCE Demo and added link on demo page. Fixes #382\n  * Changed localization message for min/max. Fixes #273\n  * Added pseudo selector for text input types to fix issue with default empty type attribute. Added tests and some test markup. Fixes #217\n  * Fixed delegate bug for dynamic-totals demo. Fixes #51\n  * Fix incorrect message for alphanumeric validator\n  * Removed incorrect false check on required attribute\n  * required attribute fix for non-html5 browsers. Fixes #301\n  * Added methods \"require_from_group\" and \"skip_or_fill_minimum\"\n  * Use correct iso code for swedish\n  * Updated demo HTML files to use HTML5 doctype\n  * Fixed regex issue for decimals without leading zeroes. Added new methods test. Fixes #41\n  * Introduce a elementValue method that normalizes only string values (don't touch array value of multi-select). Fixes #116\n  * Support for dynamically added submit buttons, and updated test case. Uses validateDelegate. Code from PR #9\n  * Fix bad double quote in test fixtures\n  * Fix maxWords method to include the upper bound, not exclude it. Fixes #284\n  * Fixed grammar error in german range validator message. Fixes #315\n  * Fixed handling of multiple class names for errorClass option. Test by Max Lynch. Fixes #280\n  * Fix jQuery.format usage, should be $.validator.format. Fixes #329\n  * Methods for 'all' UK phone numbers + UK postcodes\n  * Pattern method: Convert string param to RegExp. Fixes issue #223\n  * grammar error in german localization file\n  * Added Estonian localization for messages\n  * Improve tooltip handling on themerollered demo\n  * Add type=\"text\" to input fields without type attribute to please qSA\n  * Update themerollered demo to use tooltip to show errors as overlay.\n  * Update themerollered demo to use latest jQuery UI (along with newer jQuery version). Move code around to speed up page load.\n  * Fixed min error message broken in Japanese.\n  * Update form plugin to latest version. Enhance the ajaxSubmit demo.\n  * Drop dateDE and numberDE methods from classRuleSettings, leftover from moving those to localized methods\n  * Passing submit event to submitHandler callback\n  * Fixed #219 - Fix valid() on elements with dependency-callback or dependency-expression.\n  * Improve build to remove dist dir to ensure only the current release gets zipped up\n\n1.9.0\n---\n* Added Basque (EU) localization\n* Added Slovenian (SL) localization\n* Fixed issue #127 - Finnish translations has one : instead of ;\n* Fixed Russian localization, minor syntax issue\n* Added in support for HTML5 input types, fixes #97\n* Improved HTML5 support by setting novalidate attribute on the form, and reading the type attribute.\n* Fixed showLabel() removing all classes from error element. Remove only settings.validClass. Fixes #151.\n* Added 'pattern' to additional-methods to validate against arbitrary regular expressions.\n* Improved email method to not allow the dot at the end (valid by RFC, but unwanted here). Fixes #143\n* Fixed swedish and norwegian translations, min/max messages got switched. Fixes #181\n* Fixed #184 - resetForm: should unset lastElement\n* Fixed #71 - improve existing time method and add time12h method for 12h am/pm time format\n* Fixed #177 - Fix validation of a single radio or checkbox input\n* Fixed #189 - :hidden elements are now ignored by default\n* Fixed #194 - Required as attribute fails if jQuery>=1.6 - Use .prop instead of .attr\n* Fixed #47, #39, #32 - Allowed credit card numbers to contain spaces as well as dashes (spaces are commonly input by users).\n\n1.8.1\n---\n* Added Thai (TH) localization, fixes #85\n* Added Vietnamese (VI) localization, thanks Ngoc\n* Fixed issue #78. Error/Valid styling applies to all radio buttons of same group for required validation.\n* Don't use form.elements as that isn't supported in jQuery 1.6 anymore. Its buggy as hell anyway (IE6-8: form.elements === form).\n\n1.8.0\n---\n* Improved NL localization (http://plugins.jquery.com/node/14120)\n* Added Georgian (GE) localization, thanks Avtandil Kikabidze\n* Added Serbian (SR) localization, thanks Aleksandar Milovac\n* Added ipv4 and ipv6 to additional methods, thanks Natal Ngétal\n* Added Japanese (JA) localization, thanks Bryan Meyerovich\n* Added Catalan (CA) localization, thanks Xavier de Pedro\n* Fixed missing var statements within for-in loops\n* Fix for remote validation, where a formatted message got messed up (https://github.com/jzaefferer/jquery-validation/issues/11)\n* Bugfixes for compatibility with jQuery 1.5.1, while maintaining backwards-compatibility\n\n1.7\n---\n* Added Lithuanian (LT) localization\n* Added Greek (EL) localization (http://plugins.jquery.com/node/12319)\n* Added Latvian (LV) localization (http://plugins.jquery.com/node/12349)\n* Added Hebrew (HE) localization (http://plugins.jquery.com/node/12039)\n* Fixed Spanish (ES) localization (http://plugins.jquery.com/node/12696)\n* Added jQuery UI themerolled demo\n* Removed cmxform.js\n* Fixed four missing semicolons (http://plugins.jquery.com/node/12639)\n* Renamed phone-method in additional-methods.js to phoneUS\n* Added phoneUK and mobileUK methods to additional-methods.js (http://plugins.jquery.com/node/12359)\n* Deep extend options to avoid modifying multiple forms when using the rules-method on a single element (http://plugins.jquery.com/node/12411)\n* Bugfixes for compatibility with jQuery 1.4.2, while maintaining backwards-compatibility\n\n1.6\n---\n* Added Arabic (AR), Portuguese (PTPT), Persian (FA), Finnish (FI) and Bulgarian (BR) localization\n* Updated Swedish (SE) localization (some missing html iso characters)\n* Fixed $.validator.addMethod to properly handle empty string vs. undefined for the message argument\n* Fixed two accidental global variables\n* Enhanced min/max/rangeWords (in additional-methods.js) to strip html before counting; good when counting words in a richtext editor\n* Added localized methods for DE, NL and PT, removing the dateDE and numberDE methods (use messages_de.js and methods_de.js with date and number methods instead)\n* Fixed remote form submit synchronization, kudos to Matas Petrikas\n* Improved interactive select validation, now validating also on click (via option or select, inconsistent across browsers); doesn't work in Safari, which doesn't trigger a click event at all on select elements; fixes http://plugins.jquery.com/node/11520\n* Updated to latest form plugin (2.36), fixing http://plugins.jquery.com/node/11487\n* Bind to blur event for equalTo target to revalidate when that target changes, fixes http://plugins.jquery.com/node/11450\n* Simplified select validation, delegating to jQuery's val() method to get the select value; should fix http://plugins.jquery.com/node/11239\n* Fixed default message for digits (http://plugins.jquery.com/node/9853)\n* Fixed issue with cached remote message (http://plugins.jquery.com/node/11029 and http://plugins.jquery.com/node/9351)\n* Fixed a missing semicolon in additional-methods.js (http://plugins.jquery.com/node/9233)\n* Added automatic detection of substitution parameters in messages, removing the need to provide format functions (http://plugins.jquery.com/node/11195)\n* Fixed an issue with :filled/:blank somewhat caused by Sizzle (http://plugins.jquery.com/node/11144)\n* Added an integer method to additional-methods.js (http://plugins.jquery.com/node/9612)\n* Fixed errorsFor method where the for-attribute contains characters that need escaping to be valid inside a selector (http://plugins.jquery.com/node/9611)\n\n1.5.5\n---\n* Fix for http://plugins.jquery.com/node/8659\n* Fixed trailing comma in messages_cs.js\n\n1.5.4\n---\n* Fixed remote method bug (http://plugins.jquery.com/node/8658)\n\n1.5.3\n---\n* Fixed a bug related to the wrapper-option, where all ancestor-elements that matched the wrapper-option where selected (http://plugins.jquery.com/node/7624)\n* Updated multipart demo to use latest jQuery UI accordion\n* Added dateNL and time methods to additionalMethods.js\n* Added Traditional Chinese (Taiwan, tw) and Kazakhstan (KK) localization\n* Moved jQuery.format (formerly String.format) to jQuery.validator.format, jQuery.format is deprecated and will be removed in 1.6 (see http://code.google.com/p/jquery-utils/issues/detail?id=15 for details)\n* Cleaned up messages_pl.js and messages_ptbr.js (still defined messages for max/min/rangeValue, which were removed in 1.4)\n* Fixed flawed boolean logic in valid-plugin-method for multiple elements; now all elements need to be valid for a boolean-true result (http://plugins.jquery.com/node/8481)\n* Enhancement $.validator.addMethod: An undefined third message-argument won't overwrite an existing message (http://plugins.jquery.com/node/8443)\n* Enhancement to submitHandler option: When used, click events on submit buttons are captured and the submitting button is inserted into the form before calling submitHandler, and removed afterwards; keeps submit buttons intact (http://plugins.jquery.com/node/7183#comment-3585)\n* Added option validClass, default \"valid\", which adds that class to all valid elements, after validation (http://dev.jquery.com/ticket/2205)\n* Added creditcardtypes method to additionalMethods.js, including tests (via http://dev.jquery.com/ticket/3635)\n* Improved remote method to allow serverside message as a string, or true for valid, or false for invalid using the clientside defined message (http://dev.jquery.com/ticket/3807)\n* Improved accept method to also accept a Drupal-style comma-separated list of values (http://plugins.jquery.com/node/8580)\n\n1.5.2\n---\n* Fixed messages in additional-methods.js for maxWords, minWords, and rangeWords to include call to $.format\n* Fixed value passed to methods to exclude carriage return (\\r), same as jQuery's val() does\n* Added slovak (sk) localization\n* Added demo for integration with jQuery UI tabs\n* Added selects-grouping example to tabs demo (see second tab, birthdate field)\n\n1.5.1\n---\n* Updated marketo demo to use invalidHandler option instead of binding invalid-form event\n* Added TinyMCE integration example\n* Added ukrainian (ua) localization\n* Fixed length validation to work with trimmed value (regression from 1.5 where general trimming before validation was removed)\n* Various small fixes for compatibility with both 1.2.6 and 1.3\n\n1.5\n---\n* Improved basic demo, validating confirm-password field after password changed\n* Fixed basic validation to pass the untrimmed input value as the first parameter to validation methods, changed required accordingly; breaks existing custom method that rely on the trimming\n* Added norwegian (no), italian (it), hungarian (hu) and romanian (ro) localization\n* Fixed #3195: Two flaws in swedish localization\n* Fixed #3503: Extended rules(\"add\") to accept messages property: use to specify add custom messages to an element via rules(\"add\", { messages: { required: \"Required! \" } });\n* Fixed #3356: Regression from #2908 when using meta-option\n* Fixed #3370: Added ignoreTitle option, set to skip reading messages from the title attribute, helps to avoid issues with Google Toolbar; default is false for compatibility\n* Fixed #3516: Trigger invalid-form event even when remote validation is involved\n* Added invalidHandler option as a shortcut to bind(\"invalid-form\", function() {})\n* Fixed Safari issue for loading indicator in ajaxSubmit-integration-demo (append to body first, then hide)\n* Added test for creditcard validation and improved default message\n* Enhanced remote validation, accepting options to passthrough to $.ajax as parameter (either url string or options, including url property plus everything else that $.ajax supports)\n\n1.4\n---\n* Fixed #2931, validate elements in document order and ignore type=image inputs\n* Fixed usage of $ and jQuery variables, now fully compatible with all variations of noConflict usage\n* Implemented #2908, enabling custom messages via metadata ala class=\"{required:true,messages:{required:'required field'}}\", added demo/custom-messages-metadata-demo.html\n* Removed deprecated methods minValue (min), maxValue (max), rangeValue (rangevalue), minLength (minlength), maxLength (maxlength), rangeLength (rangelength)\n* Fixed #2215 regression: Call unhighlight only for current elements, not everything\n* Implemented #2989, enabling image button to cancel validation\n* Fixed issue where IE incorrectly validates against maxlength=0\n* Added czech (cs) localization\n* Reset validator.submitted on validator.resetForm(), enabling a full reset when necessary\n* Fixed #3035, skipping all falsy attributes when reading rules (0, undefined, empty string), removed part of the maxlength workaround (for 0)\n* Added dutch (nl) localization (#3201)\n\n1.3\n---\n* Fixed invalid-form event, now only triggered when form is invalid\n* Added spanish (es), russian (ru), portuguese brazilian (ptbr), turkish (tr), and polish (pl) localization\n* Added removeAttrs plugin to facilitate adding and removing multiple attributes\n* Added groups option to display a single message for multiple elements, via groups: { arbitraryGroupName: \"fieldName1 fieldName2[, fieldNameN\" }\n* Enhanced rules() for adding and removing (static) rules: rules(\"add\", \"method1[, methodN]\"/{method1:param[, method_n:param]}) and rules(\"remove\"[, \"method1[, method_n]\")\n* Enhanced rules-option, accepts space-separated string-list of methods, eg. {birthdate: \"required date\"}\n* Fixed checkbox group validation with inline rules: As long as the rules are specified on the first element, the group is now properly validated on click\n* Fixed #2473, ignoring all rules with an explicit parameter of boolean-false, eg. required:false is the same as not specifying required at all (it was handled as required:true so far)\n* Fixed #2424, with a modified patch from #2473: Methods returning a dependency-mismatch don't stop other rules from being evaluated anymore; still, success isn't applied for optional fields\n* Fixed url and email validation to not use trimmed values\n* Fixed creditcard validation to accept only digits and dashes (\"asdf\" is not a valid creditcard number)\n* Allow both button and input elements for cancel buttons (via class=\"cancel\")\n* Fixed #2215: Fixed message display to call unhighlight as part of showing and hiding messages, no more visual side-effects while checking an element and extracted validator.checkForm to validate a form without UI sideeffects\n* Rewrote custom selectors (:blank, :filled, :unchecked) with functions for compatibility with AIR\n\n1.2.1\n-----\n\n* Bundled delegate plugin with validate plugin - its always required anyway\n* Improved remote validation to include parts from the ajaxQueue plugin for proper synchronization (no additional plugin necessary)\n* Fixed stopRequest to prevent pendingRequest < 0\n* Added jQuery.validator.autoCreateRanges property, defaults to false, enable to convert min/max to range and minlength/maxlength to rangelength; this basically fixes the issue introduced by automatically creating ranges in 1.2\n* Fixed optional-methods to not highlight anything at all if the field is blank, that is, don't trigger success\n* Allow false/null for highlight/unhighlight options instead of forcing a do-nothing-callback even when nothing needs to be highlighted\n* Fixed validate() call with no elements selected, returning undefined instead of throwing an error\n* Improved demo, replacing metadata with classes/attributes for specifying rules\n* Fixed error when no custom message is used for remote validation\n* Modified email and url validation to require domain label and top label\n* Fixed url and email validation to require TLD (actually to require domain label); 1.2 version (TLD is optional) is moved to additions as url2 and email2\n* Fixed dynamic-totals demo in IE6/7 and improved templating, using textarea to store multiline template and string interpolation\n* Added login form example with \"Email password\" link that makes the password field optional\n* Enhanced dynamic-totals demo with an example of a single message for two fields\n\n1.2\n---\n\n* Added AJAX-captcha validation example (based on http://psyrens.com/captcha/)\n* Added remember-the-milk-demo (thanks RTM team for the permission!)\n* Added marketo-demo (thanks Glen Lipka!)\n* Added support for ajax-validation, see method \"remote\"; serverside returns JSON, true for valid elements, false or a String for invalid, String is used as message\n* Added highlight and unhighlight options, by default toggles errorClass on element, allows custom highlighting\n* Added valid() plugin method for easy programmatic checking of forms and fields without the need to use the validator API\n* Added rules() plugin method to read and write rules for an element (currently read only)\n* Replaced regex for email method, thanks to the contribution by Scott Gonzalez, see http://projects.scottsplayground.com/email_address_validation/\n* Restructured event architecture to rely solely on delegation, both improving performance, and ease-of-use for the developer (requires jquery.delegate.js)\n* Moved documentation from inline to http://docs.jquery.com/Plugins/Validation - including interactive examples for all methods\n* Removed validator.refresh(), validation is now completely dynamic\n* Renamed minValue to min, maxValue to max and rangeValue to range, deprecating the previous names (to be removed in 1.3)\n* Renamed minLength to minlength, maxLength to maxlength and rangeLength to rangelength, deprecating the previous names (to be removed in 1.3)\n* Added feature to merge min + max into and range and minlength + maxlength into rangelength\n* Added support for dynamic rule parameters, allowing to specify a function as a parameter eg. for minlength, called when validating the element\n* Allow to specify null or an empty string as a message to display nothing (see marketo demo)\n* Rules overhaul: Now supports combination of rules-option, metadata, classes (new) and attributes (new), see rules() for details\n\n1.1.2\n---\n\n* Replaced regex for URL method, thanks to the contribution by Scott Gonzalez, see http://projects.scottsplayground.com/iri/\n* Improved email method to better handle unicode characters\n* Fixed error container to hide when all elements are valid, not only on form submit\n* Fixed String.format to jQuery.format (moving into jQuery namespace)\n* Fixed accept method to accept both upper and lowercase extensions\n* Fixed validate() plugin method to create only one validator instance for a given form and always return that one instance (avoids binding events multiple times)\n* Changed debug-mode console log from \"error\" to \"warn\" level\n\n1.1.1\n-----\n\n* Fixed invalid XHTML, preventing error label creation in IE since jQuery 1.1.4\n* Fixed and improved String.format: Global search & replace, better handling of array arguments\n* Fixed cancel-button handling to use validator-object for storing state instead of form element\n* Fixed name selectors to handle \"complex\" names, eg. containing brackets (\"list[]\")\n* Added button and disabled elements to exclude from validation\n* Moved element event handlers to refresh to be able to add handlers to new elements\n* Fixed email validation to allow long top level domains (eg. \".travel\")\n* Moved showErrors() from valid() to form()\n* Added validator.size(): returns the number of current errors\n* Call submitHandler with validator as scope for easier access of it's methods, eg. to find error labels using errorsFor(Element)\n* Compatible with jQuery 1.1.x and 1.2.x\n\n1.1\n---\n\n* Added validation on blur, keyup and click (for checkboxes and radiobutton). Replaces event-option.\n* Fixed resetForm\n* Fixed custom-methods-demo\n\n1.0\n---\n\n* Improved number and numberDE methods to check for correct decimal numbers with delimiters\n* Only elements that have rules are checked (otherwise success-option is applied to all elements)\n* Added creditcard number method (thanks to Brian Klug)\n* Added ignore-option, eg. ignore: \"[@type=hidden]\", using that expression to exclude elements to validate. Default: none, though submit and reset buttons are always ignored\n* Heavily enhanced Functions-as-messages by providing a flexible String.format helper\n* Accept Functions as messages, providing runtime-custom-messages\n* Fixed exclusion of elements without rules from successList\n* Fixed custom-method-demo, replaced the alert with message displaying the number of errors\n* Fixed form-submit-prevention when using submitHandler\n* Completely removed dependency on element IDs, though they are still used (when present) to link error labels to inputs. Achieved by using\n  an array with {name, message, element} instead of an object with id:message pairs for the internal errorList.\n* Added support for specifying simple rules as simple strings, eg. \"required\" is equivalent to {required: true}\n* Added feature: Add errorClass to invalid field�s parent element, making it easy to style the label/field container or the label for the field.\n* Added feature: focusCleanup - If enabled, removes the errorClass from the invalid elements and hides all errors messages whenever the element is focused.\n* Added success option to show the a field was validated successfully\n* Fixed Opera select-issue (avoiding a attribute-collision)\n* Fixed problems with focussing hidden elements in IE\n* Added feature to skip validation for submit buttons with class \"cancel\"\n* Fixed potential issues with Google Toolbar by preferring plugin option messages over title attribute\n* submitHandler is only called when an actual submit event was handled, validator.form() returns false only for invalid forms\n* Invalid elements are now focused only on submit or via validator.focusInvalid(), avoiding all trouble with focus-on-blur\n* IE6 error container layout issue is solved\n* Customize error element via errorElement option\n* Added validator.refresh() to find new inputs in the form\n* Added accept validation method, checks file extensions\n* Improved dependency feature by adding two custom expressions: \":blank\" to select elements with an empty value and �:filled� to select elements with a value, both excluding whitespace\n* Added a resetForm() method to the validator: Resets each form element (using the form plugin, if available), removes classes on invalid elements and hides all error messages\n* Fixed docs for validator.showErrors()\n* Fixed error label creation to always use html() instead of text(), allowing arbitrary HTML passed in as messages\n* Fixed error label creation to use specified error class\n* Added dependency feature: The requires method accepts both String (jQuery expressions) and Functions as the argument\n* Heavily improved customizing of error message display: Use normal messages and show/hide an additional container; Completely replace message display with own mechanism (while being able to delegate to the default handler; Customize placing of generated labels (instead of default below-element)\n* Fixed two major bugs in IE (error containers) and Opera (metadata)\n* Modified validation methods to accept empty fields as valid (exception: of course �required� and also �equalTo� methods)\n* Renamed \"min\" to \"minLength\", \"max\" to \"maxLength\", \"length\" to \"rangeLength\"\n* Added \"minValue\", \"maxValue\" and \"rangeValue\"\n* Streamlined API for support of different events. The default, submit, can be disabled. If any event is specified, that is applied to each element (instead of the entire form). Combining keyup-validation with submit-validation is now extremely easy to setup\n* Added support for one-message-per-rule when defining messages via plugin settings\n* Added support to wrap metadata in some parent element. Useful when metadata is used for other plugins, too.\n* Refactored tests and demos: Less files, better demos\n* Improved documentation: More examples for methods, more reference texts explaining some basics\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/dist/additional-methods.js",
    "content": "/*!\n * jQuery Validation Plugin v1.14.0\n *\n * http://jqueryvalidation.org/\n *\n * Copyright (c) 2015 Jörn Zaefferer\n * Released under the MIT license\n */\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( [\"jquery\", \"./jquery.validate\"], factory );\n\t} else {\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n\n(function() {\n\n\tfunction stripHtml(value) {\n\t\t// remove html tags and space chars\n\t\treturn value.replace(/<.[^<>]*?>/g, \" \").replace(/&nbsp;|&#160;/gi, \" \")\n\t\t// remove punctuation\n\t\t.replace(/[.(),;:!?%#$'\\\"_+=\\/\\-“”’]*/g, \"\");\n\t}\n\n\t$.validator.addMethod(\"maxWords\", function(value, element, params) {\n\t\treturn this.optional(element) || stripHtml(value).match(/\\b\\w+\\b/g).length <= params;\n\t}, $.validator.format(\"Please enter {0} words or less.\"));\n\n\t$.validator.addMethod(\"minWords\", function(value, element, params) {\n\t\treturn this.optional(element) || stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n\t}, $.validator.format(\"Please enter at least {0} words.\"));\n\n\t$.validator.addMethod(\"rangeWords\", function(value, element, params) {\n\t\tvar valueStripped = stripHtml(value),\n\t\t\tregex = /\\b\\w+\\b/g;\n\t\treturn this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];\n\t}, $.validator.format(\"Please enter between {0} and {1} words.\"));\n\n}());\n\n// Accept a value from a file input based on a required mimetype\n$.validator.addMethod(\"accept\", function(value, element, param) {\n\t// Split mime on commas in case we have multiple types we can accept\n\tvar typeParam = typeof param === \"string\" ? param.replace(/\\s/g, \"\").replace(/,/g, \"|\") : \"image/*\",\n\toptionalValue = this.optional(element),\n\ti, file;\n\n\t// Element is optional\n\tif (optionalValue) {\n\t\treturn optionalValue;\n\t}\n\n\tif ($(element).attr(\"type\") === \"file\") {\n\t\t// If we are using a wildcard, make it regex friendly\n\t\ttypeParam = typeParam.replace(/\\*/g, \".*\");\n\n\t\t// Check if the element has a FileList before checking each file\n\t\tif (element.files && element.files.length) {\n\t\t\tfor (i = 0; i < element.files.length; i++) {\n\t\t\t\tfile = element.files[i];\n\n\t\t\t\t// Grab the mimetype from the loaded file, verify it matches\n\t\t\t\tif (!file.type.match(new RegExp( \"\\\\.?(\" + typeParam + \")$\", \"i\"))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Either return true because we've validated each file, or because the\n\t// browser does not support element.files and the FileList feature\n\treturn true;\n}, $.validator.format(\"Please enter a value with a valid mimetype.\"));\n\n$.validator.addMethod(\"alphanumeric\", function(value, element) {\n\treturn this.optional(element) || /^\\w+$/i.test(value);\n}, \"Letters, numbers, and underscores only please\");\n\n/*\n * Dutch bank account numbers (not 'giro' numbers) have 9 digits\n * and pass the '11 check'.\n * We accept the notation with spaces, as that is common.\n * acceptable: 123456789 or 12 34 56 789\n */\n$.validator.addMethod(\"bankaccountNL\", function(value, element) {\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\tif (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {\n\t\treturn false;\n\t}\n\t// now '11 check'\n\tvar account = value.replace(/ /g, \"\"), // remove spaces\n\t\tsum = 0,\n\t\tlen = account.length,\n\t\tpos, factor, digit;\n\tfor ( pos = 0; pos < len; pos++ ) {\n\t\tfactor = len - pos;\n\t\tdigit = account.substring(pos, pos + 1);\n\t\tsum = sum + factor * digit;\n\t}\n\treturn sum % 11 === 0;\n}, \"Please specify a valid bank account number\");\n\n$.validator.addMethod(\"bankorgiroaccountNL\", function(value, element) {\n\treturn this.optional(element) ||\n\t\t\t($.validator.methods.bankaccountNL.call(this, value, element)) ||\n\t\t\t($.validator.methods.giroaccountNL.call(this, value, element));\n}, \"Please specify a valid bank or giro account number\");\n\n/**\n * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.\n *\n * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)\n *\n * BIC definition in detail:\n * - First 4 characters - bank code (only letters)\n * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)\n * - Next 2 characters - location code (letters and digits)\n *   a. shall not start with '0' or '1'\n *   b. second character must be a letter ('O' is not allowed) or one of the following digits ('0' for test (therefore not allowed), '1' for passive participant and '2' for active participant)\n * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)\n */\n$.validator.addMethod(\"bic\", function(value, element) {\n    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value );\n}, \"Please specify a valid BIC code\");\n\n/*\n * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities\n * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal\n */\n$.validator.addMethod( \"cifES\", function( value ) {\n\t\"use strict\";\n\n\tvar num = [],\n\t\tcontrolDigit, sum, i, count, tmp, secondDigit;\n\n\tvalue = value.toUpperCase();\n\n\t// Quick format test\n\tif ( !value.match( \"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\" ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( i = 0; i < 9; i++ ) {\n\t\tnum[ i ] = parseInt( value.charAt( i ), 10 );\n\t}\n\n\t// Algorithm for checking CIF codes\n\tsum = num[ 2 ] + num[ 4 ] + num[ 6 ];\n\tfor ( count = 1; count < 8; count += 2 ) {\n\t\ttmp = ( 2 * num[ count ] ).toString();\n\t\tsecondDigit = tmp.charAt( 1 );\n\n\t\tsum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === \"\" ? 0 : parseInt( secondDigit, 10 ) );\n\t}\n\n\t/* The first (position 1) is a letter following the following criteria:\n\t *\tA. Corporations\n\t *\tB. LLCs\n\t *\tC. General partnerships\n\t *\tD. Companies limited partnerships\n\t *\tE. Communities of goods\n\t *\tF. Cooperative Societies\n\t *\tG. Associations\n\t *\tH. Communities of homeowners in horizontal property regime\n\t *\tJ. Civil Societies\n\t *\tK. Old format\n\t *\tL. Old format\n\t *\tM. Old format\n\t *\tN. Nonresident entities\n\t *\tP. Local authorities\n\t *\tQ. Autonomous bodies, state or not, and the like, and congregations and religious institutions\n\t *\tR. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)\n\t *\tS. Organs of State Administration and regions\n\t *\tV. Agrarian Transformation\n\t *\tW. Permanent establishments of non-resident in Spain\n\t */\n\tif ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {\n\t\tsum += \"\";\n\t\tcontrolDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );\n\t\tvalue += controlDigit;\n\t\treturn ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid CIF number.\" );\n\n/*\n * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.\n * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.\n */\n$.validator.addMethod(\"cpfBR\", function(value) {\n\t// Removing special characters from value\n\tvalue = value.replace(/([~!@#$%^&*()_+=`{}\\[\\]\\-|\\\\:;'<>,.\\/? ])+/g, \"\");\n\n\t// Checking value to have 11 digits only\n\tif (value.length !== 11) {\n\t\treturn false;\n\t}\n\n\tvar sum = 0,\n\t\tfirstCN, secondCN, checkResult, i;\n\n\tfirstCN = parseInt(value.substring(9, 10), 10);\n\tsecondCN = parseInt(value.substring(10, 11), 10);\n\n\tcheckResult = function(sum, cn) {\n\t\tvar result = (sum * 10) % 11;\n\t\tif ((result === 10) || (result === 11)) {result = 0;}\n\t\treturn (result === cn);\n\t};\n\n\t// Checking for dump data\n\tif (value === \"\" ||\n\t\tvalue === \"00000000000\" ||\n\t\tvalue === \"11111111111\" ||\n\t\tvalue === \"22222222222\" ||\n\t\tvalue === \"33333333333\" ||\n\t\tvalue === \"44444444444\" ||\n\t\tvalue === \"55555555555\" ||\n\t\tvalue === \"66666666666\" ||\n\t\tvalue === \"77777777777\" ||\n\t\tvalue === \"88888888888\" ||\n\t\tvalue === \"99999999999\"\n\t) {\n\t\treturn false;\n\t}\n\n\t// Step 1 - using first Check Number:\n\tfor ( i = 1; i <= 9; i++ ) {\n\t\tsum = sum + parseInt(value.substring(i - 1, i), 10) * (11 - i);\n\t}\n\n\t// If first Check Number (CN) is valid, move to Step 2 - using second Check Number:\n\tif ( checkResult(sum, firstCN) ) {\n\t\tsum = 0;\n\t\tfor ( i = 1; i <= 10; i++ ) {\n\t\t\tsum = sum + parseInt(value.substring(i - 1, i), 10) * (12 - i);\n\t\t}\n\t\treturn checkResult(sum, secondCN);\n\t}\n\treturn false;\n\n}, \"Please specify a valid CPF number\");\n\n/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator\n * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0\n * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)\n */\n$.validator.addMethod(\"creditcardtypes\", function(value, element, param) {\n\tif (/[^0-9\\-]+/.test(value)) {\n\t\treturn false;\n\t}\n\n\tvalue = value.replace(/\\D/g, \"\");\n\n\tvar validTypes = 0x0000;\n\n\tif (param.mastercard) {\n\t\tvalidTypes |= 0x0001;\n\t}\n\tif (param.visa) {\n\t\tvalidTypes |= 0x0002;\n\t}\n\tif (param.amex) {\n\t\tvalidTypes |= 0x0004;\n\t}\n\tif (param.dinersclub) {\n\t\tvalidTypes |= 0x0008;\n\t}\n\tif (param.enroute) {\n\t\tvalidTypes |= 0x0010;\n\t}\n\tif (param.discover) {\n\t\tvalidTypes |= 0x0020;\n\t}\n\tif (param.jcb) {\n\t\tvalidTypes |= 0x0040;\n\t}\n\tif (param.unknown) {\n\t\tvalidTypes |= 0x0080;\n\t}\n\tif (param.all) {\n\t\tvalidTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n\t}\n\tif (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub\n\t\treturn value.length === 14;\n\t}\n\tif (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0080) { //unknown\n\t\treturn true;\n\t}\n\treturn false;\n}, \"Please enter a valid credit card number.\");\n\n/**\n * Validates currencies with any given symbols by @jameslouiz\n * Symbols can be optional or required. Symbols required by default\n *\n * Usage examples:\n *  currency: [\"£\", false] - Use false for soft currency validation\n *  currency: [\"$\", false]\n *  currency: [\"RM\", false] - also works with text based symbols such as \"RM\" - Malaysia Ringgit etc\n *\n *  <input class=\"currencyInput\" name=\"currencyInput\">\n *\n * Soft symbol checking\n *  currencyInput: {\n *     currency: [\"$\", false]\n *  }\n *\n * Strict symbol checking (default)\n *  currencyInput: {\n *     currency: \"$\"\n *     //OR\n *     currency: [\"$\", true]\n *  }\n *\n * Multiple Symbols\n *  currencyInput: {\n *     currency: \"$,£,¢\"\n *  }\n */\n$.validator.addMethod(\"currency\", function(value, element, param) {\n    var isParamString = typeof param === \"string\",\n        symbol = isParamString ? param : param[0],\n        soft = isParamString ? true : param[1],\n        regex;\n\n    symbol = symbol.replace(/,/g, \"\");\n    symbol = soft ? symbol + \"]\" : symbol + \"]?\";\n    regex = \"^[\" + symbol + \"([1-9]{1}[0-9]{0,2}(\\\\,[0-9]{3})*(\\\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\\\.[0-9]{0,2})?|0(\\\\.[0-9]{0,2})?|(\\\\.[0-9]{1,2})?)$\";\n    regex = new RegExp(regex);\n    return this.optional(element) || regex.test(value);\n\n}, \"Please specify a valid currency\");\n\n$.validator.addMethod(\"dateFA\", function(value, element) {\n\treturn this.optional(element) || /^[1-4]\\d{3}\\/((0?[1-6]\\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(value);\n}, $.validator.messages.date);\n\n/**\n * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.\n *\n * @example $.validator.methods.date(\"01/01/1900\")\n * @result true\n *\n * @example $.validator.methods.date(\"01/13/1990\")\n * @result false\n *\n * @example $.validator.methods.date(\"01.01.1900\")\n * @result false\n *\n * @example <input name=\"pippo\" class=\"{dateITA:true}\" />\n * @desc Declares an optional input element whose value must be a valid date.\n *\n * @name $.validator.methods.dateITA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod(\"dateITA\", function(value, element) {\n\tvar check = false,\n\t\tre = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n\t\tadata, gg, mm, aaaa, xdata;\n\tif ( re.test(value)) {\n\t\tadata = value.split(\"/\");\n\t\tgg = parseInt(adata[0], 10);\n\t\tmm = parseInt(adata[1], 10);\n\t\taaaa = parseInt(adata[2], 10);\n\t\txdata = new Date(Date.UTC(aaaa, mm - 1, gg, 12, 0, 0, 0));\n\t\tif ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth () === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {\n\t\t\tcheck = true;\n\t\t} else {\n\t\t\tcheck = false;\n\t\t}\n\t} else {\n\t\tcheck = false;\n\t}\n\treturn this.optional(element) || check;\n}, $.validator.messages.date);\n\n$.validator.addMethod(\"dateNL\", function(value, element) {\n\treturn this.optional(element) || /^(0?[1-9]|[12]\\d|3[01])[\\.\\/\\-](0?[1-9]|1[012])[\\.\\/\\-]([12]\\d)?(\\d\\d)$/.test(value);\n}, $.validator.messages.date);\n\n// Older \"accept\" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept\n$.validator.addMethod(\"extension\", function(value, element, param) {\n\tparam = typeof param === \"string\" ? param.replace(/,/g, \"|\") : \"png|jpe?g|gif\";\n\treturn this.optional(element) || value.match(new RegExp(\"\\\\.(\" + param + \")$\", \"i\"));\n}, $.validator.format(\"Please enter a value with a valid extension.\"));\n\n/**\n * Dutch giro account numbers (not bank numbers) have max 7 digits\n */\n$.validator.addMethod(\"giroaccountNL\", function(value, element) {\n\treturn this.optional(element) || /^[0-9]{1,7}$/.test(value);\n}, \"Please specify a valid giro account number\");\n\n/**\n * IBAN is the international bank account number.\n * It has a country - specific format, that is checked here too\n */\n$.validator.addMethod(\"iban\", function(value, element) {\n\t// some quick simple tests to prevent needless work\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\n\t// remove spaces and to upper case\n\tvar iban = value.replace(/ /g, \"\").toUpperCase(),\n\t\tibancheckdigits = \"\",\n\t\tleadingZeroes = true,\n\t\tcRest = \"\",\n\t\tcOperator = \"\",\n\t\tcountrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;\n\n\t// check the country code and find the country specific format\n\tcountrycode = iban.substring(0, 2);\n\tbbancountrypatterns = {\n\t\t\"AL\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"AD\": \"\\\\d{8}[\\\\dA-Z]{12}\",\n\t\t\"AT\": \"\\\\d{16}\",\n\t\t\"AZ\": \"[\\\\dA-Z]{4}\\\\d{20}\",\n\t\t\"BE\": \"\\\\d{12}\",\n\t\t\"BH\": \"[A-Z]{4}[\\\\dA-Z]{14}\",\n\t\t\"BA\": \"\\\\d{16}\",\n\t\t\"BR\": \"\\\\d{23}[A-Z][\\\\dA-Z]\",\n\t\t\"BG\": \"[A-Z]{4}\\\\d{6}[\\\\dA-Z]{8}\",\n\t\t\"CR\": \"\\\\d{17}\",\n\t\t\"HR\": \"\\\\d{17}\",\n\t\t\"CY\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"CZ\": \"\\\\d{20}\",\n\t\t\"DK\": \"\\\\d{14}\",\n\t\t\"DO\": \"[A-Z]{4}\\\\d{20}\",\n\t\t\"EE\": \"\\\\d{16}\",\n\t\t\"FO\": \"\\\\d{14}\",\n\t\t\"FI\": \"\\\\d{14}\",\n\t\t\"FR\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"GE\": \"[\\\\dA-Z]{2}\\\\d{16}\",\n\t\t\"DE\": \"\\\\d{18}\",\n\t\t\"GI\": \"[A-Z]{4}[\\\\dA-Z]{15}\",\n\t\t\"GR\": \"\\\\d{7}[\\\\dA-Z]{16}\",\n\t\t\"GL\": \"\\\\d{14}\",\n\t\t\"GT\": \"[\\\\dA-Z]{4}[\\\\dA-Z]{20}\",\n\t\t\"HU\": \"\\\\d{24}\",\n\t\t\"IS\": \"\\\\d{22}\",\n\t\t\"IE\": \"[\\\\dA-Z]{4}\\\\d{14}\",\n\t\t\"IL\": \"\\\\d{19}\",\n\t\t\"IT\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"KZ\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"KW\": \"[A-Z]{4}[\\\\dA-Z]{22}\",\n\t\t\"LV\": \"[A-Z]{4}[\\\\dA-Z]{13}\",\n\t\t\"LB\": \"\\\\d{4}[\\\\dA-Z]{20}\",\n\t\t\"LI\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"LT\": \"\\\\d{16}\",\n\t\t\"LU\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"MK\": \"\\\\d{3}[\\\\dA-Z]{10}\\\\d{2}\",\n\t\t\"MT\": \"[A-Z]{4}\\\\d{5}[\\\\dA-Z]{18}\",\n\t\t\"MR\": \"\\\\d{23}\",\n\t\t\"MU\": \"[A-Z]{4}\\\\d{19}[A-Z]{3}\",\n\t\t\"MC\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"MD\": \"[\\\\dA-Z]{2}\\\\d{18}\",\n\t\t\"ME\": \"\\\\d{18}\",\n\t\t\"NL\": \"[A-Z]{4}\\\\d{10}\",\n\t\t\"NO\": \"\\\\d{11}\",\n\t\t\"PK\": \"[\\\\dA-Z]{4}\\\\d{16}\",\n\t\t\"PS\": \"[\\\\dA-Z]{4}\\\\d{21}\",\n\t\t\"PL\": \"\\\\d{24}\",\n\t\t\"PT\": \"\\\\d{21}\",\n\t\t\"RO\": \"[A-Z]{4}[\\\\dA-Z]{16}\",\n\t\t\"SM\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"SA\": \"\\\\d{2}[\\\\dA-Z]{18}\",\n\t\t\"RS\": \"\\\\d{18}\",\n\t\t\"SK\": \"\\\\d{20}\",\n\t\t\"SI\": \"\\\\d{15}\",\n\t\t\"ES\": \"\\\\d{20}\",\n\t\t\"SE\": \"\\\\d{20}\",\n\t\t\"CH\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"TN\": \"\\\\d{20}\",\n\t\t\"TR\": \"\\\\d{5}[\\\\dA-Z]{17}\",\n\t\t\"AE\": \"\\\\d{3}\\\\d{16}\",\n\t\t\"GB\": \"[A-Z]{4}\\\\d{14}\",\n\t\t\"VG\": \"[\\\\dA-Z]{4}\\\\d{16}\"\n\t};\n\n\tbbanpattern = bbancountrypatterns[countrycode];\n\t// As new countries will start using IBAN in the\n\t// future, we only check if the countrycode is known.\n\t// This prevents false negatives, while almost all\n\t// false positives introduced by this, will be caught\n\t// by the checksum validation below anyway.\n\t// Strict checking should return FALSE for unknown\n\t// countries.\n\tif (typeof bbanpattern !== \"undefined\") {\n\t\tibanregexp = new RegExp(\"^[A-Z]{2}\\\\d{2}\" + bbanpattern + \"$\", \"\");\n\t\tif (!(ibanregexp.test(iban))) {\n\t\t\treturn false; // invalid country specific format\n\t\t}\n\t}\n\n\t// now check the checksum, first convert to digits\n\tibancheck = iban.substring(4, iban.length) + iban.substring(0, 4);\n\tfor (i = 0; i < ibancheck.length; i++) {\n\t\tcharAt = ibancheck.charAt(i);\n\t\tif (charAt !== \"0\") {\n\t\t\tleadingZeroes = false;\n\t\t}\n\t\tif (!leadingZeroes) {\n\t\t\tibancheckdigits += \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\".indexOf(charAt);\n\t\t}\n\t}\n\n\t// calculate the result of: ibancheckdigits % 97\n\tfor (p = 0; p < ibancheckdigits.length; p++) {\n\t\tcChar = ibancheckdigits.charAt(p);\n\t\tcOperator = \"\" + cRest + \"\" + cChar;\n\t\tcRest = cOperator % 97;\n\t}\n\treturn cRest === 1;\n}, \"Please specify a valid IBAN\");\n\n$.validator.addMethod(\"integer\", function(value, element) {\n\treturn this.optional(element) || /^-?\\d+$/.test(value);\n}, \"A positive or negative non-decimal number please\");\n\n$.validator.addMethod(\"ipv4\", function(value, element) {\n\treturn this.optional(element) || /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/i.test(value);\n}, \"Please enter a valid IP v4 address.\");\n\n$.validator.addMethod(\"ipv6\", function(value, element) {\n\treturn this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);\n}, \"Please enter a valid IP v6 address.\");\n\n$.validator.addMethod(\"lettersonly\", function(value, element) {\n\treturn this.optional(element) || /^[a-z]+$/i.test(value);\n}, \"Letters only please\");\n\n$.validator.addMethod(\"letterswithbasicpunc\", function(value, element) {\n\treturn this.optional(element) || /^[a-z\\-.,()'\"\\s]+$/i.test(value);\n}, \"Letters or punctuation only please\");\n\n$.validator.addMethod(\"mobileNL\", function(value, element) {\n\treturn this.optional(element) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)6((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test(value);\n}, \"Please specify a valid mobile number\");\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod(\"mobileUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?|0)7(?:[1345789]\\d{2}|624)\\s?\\d{3}\\s?\\d{3})$/);\n}, \"Please specify a valid mobile number\");\n\n/*\n * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain\n */\n$.validator.addMethod( \"nieES\", function( value ) {\n\t\"use strict\";\n\n\tvalue = value.toUpperCase();\n\n\t// Basic format test\n\tif ( !value.match( \"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\" ) ) {\n\t\treturn false;\n\t}\n\n\t// Test NIE\n\t//T\n\tif ( /^[T]{1}/.test( value ) ) {\n\t\treturn ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );\n\t}\n\n\t//XYZ\n\tif ( /^[XYZ]{1}/.test( value ) ) {\n\t\treturn (\n\t\t\tvalue[ 8 ] === \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt(\n\t\t\t\tvalue.replace( \"X\", \"0\" )\n\t\t\t\t\t.replace( \"Y\", \"1\" )\n\t\t\t\t\t.replace( \"Z\", \"2\" )\n\t\t\t\t\t.substring( 0, 8 ) % 23\n\t\t\t)\n\t\t);\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid NIE number.\" );\n\n/*\n * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals\n */\n$.validator.addMethod( \"nifES\", function( value ) {\n\t\"use strict\";\n\n\tvalue = value.toUpperCase();\n\n\t// Basic format test\n\tif ( !value.match(\"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\") ) {\n\t\treturn false;\n\t}\n\n\t// Test NIF\n\tif ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {\n\t\treturn ( \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );\n\t}\n\t// Test specials NIF (starts with K, L or M)\n\tif ( /^[KLM]{1}/.test( value ) ) {\n\t\treturn ( value[ 8 ] === String.fromCharCode( 64 ) );\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid NIF number.\" );\n\njQuery.validator.addMethod( \"notEqualTo\", function( value, element, param ) {\n\treturn this.optional(element) || !$.validator.methods.equalTo.call( this, value, element, param );\n}, \"Please enter a different value, values must not be the same.\" );\n\n$.validator.addMethod(\"nowhitespace\", function(value, element) {\n\treturn this.optional(element) || /^\\S+$/i.test(value);\n}, \"No white space please\");\n\n/**\n* Return true if the field value matches the given format RegExp\n*\n* @example $.validator.methods.pattern(\"AR1004\",element,/^AR\\d{4}$/)\n* @result true\n*\n* @example $.validator.methods.pattern(\"BR1004\",element,/^AR\\d{4}$/)\n* @result false\n*\n* @name $.validator.methods.pattern\n* @type Boolean\n* @cat Plugins/Validate/Methods\n*/\n$.validator.addMethod(\"pattern\", function(value, element, param) {\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\tif (typeof param === \"string\") {\n\t\tparam = new RegExp(\"^(?:\" + param + \")$\");\n\t}\n\treturn param.test(value);\n}, \"Invalid format.\");\n\n/**\n * Dutch phone numbers have 10 digits (or 11 and start with +31).\n */\n$.validator.addMethod(\"phoneNL\", function(value, element) {\n\treturn this.optional(element) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)[1-9]((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test(value);\n}, \"Please specify a valid phone number.\");\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod(\"phoneUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?)|(?:\\(?0))(?:\\d{2}\\)?\\s?\\d{4}\\s?\\d{4}|\\d{3}\\)?\\s?\\d{3}\\s?\\d{3,4}|\\d{4}\\)?\\s?(?:\\d{5}|\\d{3}\\s?\\d{3})|\\d{5}\\)?\\s?\\d{4,5})$/);\n}, \"Please specify a valid phone number\");\n\n/**\n * matches US phone number format\n *\n * where the area code may not start with 1 and the prefix may not start with 1\n * allows '-' or ' ' as a separator and allows parens around area code\n * some people may want to put a '1' in front of their number\n *\n * 1(212)-999-2345 or\n * 212 999 2344 or\n * 212-999-0983\n *\n * but not\n * 111-123-5434\n * and not\n * 212 123 4567\n */\n$.validator.addMethod(\"phoneUS\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\s+/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(\\+?1-?)?(\\([2-9]([02-9]\\d|1[02-9])\\)|[2-9]([02-9]\\d|1[02-9]))-?[2-9]([02-9]\\d|1[02-9])-?\\d{4}$/);\n}, \"Please specify a valid phone number\");\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers\n$.validator.addMethod(\"phonesUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?|0)(?:1\\d{8,9}|[23]\\d{9}|7(?:[1345789]\\d{8}|624\\d{6})))$/);\n}, \"Please specify a valid uk phone number\");\n\n/**\n * Matches a valid Canadian Postal Code\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H 0H0\", element )\n * @result true\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H0H0\", element )\n * @result false\n *\n * @name jQuery.validator.methods.postalCodeCA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod( \"postalCodeCA\", function( value, element ) {\n\treturn this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\\d[A-Z] \\d[A-Z]\\d$/.test( value );\n}, \"Please specify a valid postal code\" );\n\n/*\n* Valida CEPs do brasileiros:\n*\n* Formatos aceitos:\n* 99999-999\n* 99.999-999\n* 99999999\n*/\n$.validator.addMethod(\"postalcodeBR\", function(cep_value, element) {\n\treturn this.optional(element) || /^\\d{2}.\\d{3}-\\d{3}?$|^\\d{5}-?\\d{3}?$/.test( cep_value );\n}, \"Informe um CEP válido.\");\n\n/* Matches Italian postcode (CAP) */\n$.validator.addMethod(\"postalcodeIT\", function(value, element) {\n\treturn this.optional(element) || /^\\d{5}$/.test(value);\n}, \"Please specify a valid postal code\");\n\n$.validator.addMethod(\"postalcodeNL\", function(value, element) {\n\treturn this.optional(element) || /^[1-9][0-9]{3}\\s?[a-zA-Z]{2}$/.test(value);\n}, \"Please specify a valid postal code\");\n\n// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)\n$.validator.addMethod(\"postcodeUK\", function(value, element) {\n\treturn this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\\s?(0AA))$/i.test(value);\n}, \"Please specify a valid UK postcode\");\n\n/*\n * Lets you say \"at least X inputs that match selector Y must be filled.\"\n *\n * The end result is that neither of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\n *\t...will validate unless at least one of them is filled.\n *\n * partnumber:\t{require_from_group: [1,\".productinfo\"]},\n * description: {require_from_group: [1,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n */\n$.validator.addMethod(\"require_from_group\", function(value, element, options) {\n\tvar $fields = $(options[1], element.form),\n\t\t$fieldsFirst = $fields.eq(0),\n\t\tvalidator = $fieldsFirst.data(\"valid_req_grp\") ? $fieldsFirst.data(\"valid_req_grp\") : $.extend({}, this),\n\t\tisValid = $fields.filter(function() {\n\t\t\treturn validator.elementValue(this);\n\t\t}).length >= options[0];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data(\"valid_req_grp\", validator);\n\n\t// If element isn't being validated, run each require_from_group field's validation rules\n\tif (!$(element).data(\"being_validated\")) {\n\t\t$fields.data(\"being_validated\", true);\n\t\t$fields.each(function() {\n\t\t\tvalidator.element(this);\n\t\t});\n\t\t$fields.data(\"being_validated\", false);\n\t}\n\treturn isValid;\n}, $.validator.format(\"Please fill at least {0} of these fields.\"));\n\n/*\n * Lets you say \"either at least X inputs that match selector Y must be filled,\n * OR they must all be skipped (left blank).\"\n *\n * The end result, is that none of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\t<input class=\"productinfo\" name=\"color\">\n *\n *\t...will validate unless either at least two of them are filled,\n *\tOR none of them are.\n *\n * partnumber:\t{skip_or_fill_minimum: [2,\".productinfo\"]},\n * description: {skip_or_fill_minimum: [2,\".productinfo\"]},\n * color:\t\t{skip_or_fill_minimum: [2,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n *\n */\n$.validator.addMethod(\"skip_or_fill_minimum\", function(value, element, options) {\n\tvar $fields = $(options[1], element.form),\n\t\t$fieldsFirst = $fields.eq(0),\n\t\tvalidator = $fieldsFirst.data(\"valid_skip\") ? $fieldsFirst.data(\"valid_skip\") : $.extend({}, this),\n\t\tnumberFilled = $fields.filter(function() {\n\t\t\treturn validator.elementValue(this);\n\t\t}).length,\n\t\tisValid = numberFilled === 0 || numberFilled >= options[0];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data(\"valid_skip\", validator);\n\n\t// If element isn't being validated, run each skip_or_fill_minimum field's validation rules\n\tif (!$(element).data(\"being_validated\")) {\n\t\t$fields.data(\"being_validated\", true);\n\t\t$fields.each(function() {\n\t\t\tvalidator.element(this);\n\t\t});\n\t\t$fields.data(\"being_validated\", false);\n\t}\n\treturn isValid;\n}, $.validator.format(\"Please either skip these fields or fill at least {0} of them.\"));\n\n/* Validates US States and/or Territories by @jdforsythe\n * Can be case insensitive or require capitalization - default is case insensitive\n * Can include US Territories or not - default does not\n * Can include US Military postal abbreviations (AA, AE, AP) - default does not\n *\n * Note: \"States\" always includes DC (District of Colombia)\n *\n * Usage examples:\n *\n *  This is the default - case insensitive, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false,\n *     includeTerritories: false,\n *     includeMilitary: false\n *  }\n *\n *  Only allow capital letters, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false\n *  }\n *\n *  Case insensitive, include territories but not military zones\n *  stateInput: {\n *     includeTerritories: true\n *  }\n *\n *  Only allow capital letters, include territories and military zones\n *  stateInput: {\n *     caseSensitive: true,\n *     includeTerritories: true,\n *     includeMilitary: true\n *  }\n *\n *\n *\n */\n\n$.validator.addMethod(\"stateUS\", function(value, element, options) {\n\tvar isDefault = typeof options === \"undefined\",\n\t\tcaseSensitive = ( isDefault || typeof options.caseSensitive === \"undefined\" ) ? false : options.caseSensitive,\n\t\tincludeTerritories = ( isDefault || typeof options.includeTerritories === \"undefined\" ) ? false : options.includeTerritories,\n\t\tincludeMilitary = ( isDefault || typeof options.includeMilitary === \"undefined\" ) ? false : options.includeMilitary,\n\t\tregex;\n\n\tif (!includeTerritories && !includeMilitary) {\n\t\tregex = \"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t} else if (includeTerritories && includeMilitary) {\n\t\tregex = \"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else if (includeTerritories) {\n\t\tregex = \"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else {\n\t\tregex = \"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t}\n\n\tregex = caseSensitive ? new RegExp(regex) : new RegExp(regex, \"i\");\n\treturn this.optional(element) || regex.test(value);\n},\n\"Please specify a valid state\");\n\n// TODO check if value starts with <, otherwise don't try stripping anything\n$.validator.addMethod(\"strippedminlength\", function(value, element, param) {\n\treturn $(value).text().length >= param;\n}, $.validator.format(\"Please enter at least {0} characters\"));\n\n$.validator.addMethod(\"time\", function(value, element) {\n\treturn this.optional(element) || /^([01]\\d|2[0-3]|[0-9])(:[0-5]\\d){1,2}$/.test(value);\n}, \"Please enter a valid time, between 00:00 and 23:59\");\n\n$.validator.addMethod(\"time12h\", function(value, element) {\n\treturn this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\\d){1,2}(\\ ?[AP]M))$/i.test(value);\n}, \"Please enter a valid time in 12-hour am/pm format\");\n\n// same as url, but TLD is optional\n$.validator.addMethod(\"url2\", function(value, element) {\n\treturn this.optional(element) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);\n}, $.validator.messages.url);\n\n/**\n * Return true, if the value is a valid vehicle identification number (VIN).\n *\n * Works with all kind of text inputs.\n *\n * @example <input type=\"text\" size=\"20\" name=\"VehicleID\" class=\"{required:true,vinUS:true}\" />\n * @desc Declares a required input element whose value must be a valid vehicle identification number.\n *\n * @name $.validator.methods.vinUS\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod(\"vinUS\", function(v) {\n\tif (v.length !== 17) {\n\t\treturn false;\n\t}\n\n\tvar LL = [ \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"J\", \"K\", \"L\", \"M\", \"N\", \"P\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\" ],\n\t\tVL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],\n\t\tFL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],\n\t\trs = 0,\n\t\ti, n, d, f, cd, cdv;\n\n\tfor (i = 0; i < 17; i++) {\n\t\tf = FL[i];\n\t\td = v.slice(i, i + 1);\n\t\tif (i === 8) {\n\t\t\tcdv = d;\n\t\t}\n\t\tif (!isNaN(d)) {\n\t\t\td *= f;\n\t\t} else {\n\t\t\tfor (n = 0; n < LL.length; n++) {\n\t\t\t\tif (d.toUpperCase() === LL[n]) {\n\t\t\t\t\td = VL[n];\n\t\t\t\t\td *= f;\n\t\t\t\t\tif (isNaN(cdv) && n === 8) {\n\t\t\t\t\t\tcdv = LL[n];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\trs += d;\n\t}\n\tcd = rs % 11;\n\tif (cd === 10) {\n\t\tcd = \"X\";\n\t}\n\tif (cd === cdv) {\n\t\treturn true;\n\t}\n\treturn false;\n}, \"The specified vehicle identification number (VIN) is invalid.\");\n\n$.validator.addMethod(\"zipcodeUS\", function(value, element) {\n\treturn this.optional(element) || /^\\d{5}(-\\d{4})?$/.test(value);\n}, \"The specified US ZIP Code is invalid\");\n\n$.validator.addMethod(\"ziprange\", function(value, element) {\n\treturn this.optional(element) || /^90[2-5]\\d\\{2\\}-\\d{4}$/.test(value);\n}, \"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx\");\n\n}));"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/dist/jquery.validate.js",
    "content": "/*!\n * jQuery Validation Plugin v1.14.0\n *\n * http://jqueryvalidation.org/\n *\n * Copyright (c) 2015 Jörn Zaefferer\n * Released under the MIT license\n */\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( [\"jquery\"], factory );\n\t} else {\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n\n$.extend($.fn, {\n\t// http://jqueryvalidation.org/validate/\n\tvalidate: function( options ) {\n\n\t\t// if nothing is selected, return nothing; can't chain anyway\n\t\tif ( !this.length ) {\n\t\t\tif ( options && options.debug && window.console ) {\n\t\t\t\tconsole.warn( \"Nothing selected, can't validate, returning nothing.\" );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// check if a validator for this form was already created\n\t\tvar validator = $.data( this[ 0 ], \"validator\" );\n\t\tif ( validator ) {\n\t\t\treturn validator;\n\t\t}\n\n\t\t// Add novalidate tag if HTML5.\n\t\tthis.attr( \"novalidate\", \"novalidate\" );\n\n\t\tvalidator = new $.validator( options, this[ 0 ] );\n\t\t$.data( this[ 0 ], \"validator\", validator );\n\n\t\tif ( validator.settings.onsubmit ) {\n\n\t\t\tthis.on( \"click.validate\", \":submit\", function( event ) {\n\t\t\t\tif ( validator.settings.submitHandler ) {\n\t\t\t\t\tvalidator.submitButton = event.target;\n\t\t\t\t}\n\n\t\t\t\t// allow suppressing validation by adding a cancel class to the submit button\n\t\t\t\tif ( $( this ).hasClass( \"cancel\" ) ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\n\t\t\t\t// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button\n\t\t\t\tif ( $( this ).attr( \"formnovalidate\" ) !== undefined ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// validate the form on submit\n\t\t\tthis.on( \"submit.validate\", function( event ) {\n\t\t\t\tif ( validator.settings.debug ) {\n\t\t\t\t\t// prevent form submit to be able to see console output\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t\tfunction handle() {\n\t\t\t\t\tvar hidden, result;\n\t\t\t\t\tif ( validator.settings.submitHandler ) {\n\t\t\t\t\t\tif ( validator.submitButton ) {\n\t\t\t\t\t\t\t// insert a hidden input as a replacement for the missing submit button\n\t\t\t\t\t\t\thidden = $( \"<input type='hidden'/>\" )\n\t\t\t\t\t\t\t\t.attr( \"name\", validator.submitButton.name )\n\t\t\t\t\t\t\t\t.val( $( validator.submitButton ).val() )\n\t\t\t\t\t\t\t\t.appendTo( validator.currentForm );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult = validator.settings.submitHandler.call( validator, validator.currentForm, event );\n\t\t\t\t\t\tif ( validator.submitButton ) {\n\t\t\t\t\t\t\t// and clean up afterwards; thanks to no-block-scope, hidden can be referenced\n\t\t\t\t\t\t\thidden.remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( result !== undefined ) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// prevent submit for invalid forms or custom submit handlers\n\t\t\t\tif ( validator.cancelSubmit ) {\n\t\t\t\t\tvalidator.cancelSubmit = false;\n\t\t\t\t\treturn handle();\n\t\t\t\t}\n\t\t\t\tif ( validator.form() ) {\n\t\t\t\t\tif ( validator.pendingRequest ) {\n\t\t\t\t\t\tvalidator.formSubmitted = true;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn handle();\n\t\t\t\t} else {\n\t\t\t\t\tvalidator.focusInvalid();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn validator;\n\t},\n\t// http://jqueryvalidation.org/valid/\n\tvalid: function() {\n\t\tvar valid, validator, errorList;\n\n\t\tif ( $( this[ 0 ] ).is( \"form\" ) ) {\n\t\t\tvalid = this.validate().form();\n\t\t} else {\n\t\t\terrorList = [];\n\t\t\tvalid = true;\n\t\t\tvalidator = $( this[ 0 ].form ).validate();\n\t\t\tthis.each( function() {\n\t\t\t\tvalid = validator.element( this ) && valid;\n\t\t\t\terrorList = errorList.concat( validator.errorList );\n\t\t\t});\n\t\t\tvalidator.errorList = errorList;\n\t\t}\n\t\treturn valid;\n\t},\n\n\t// http://jqueryvalidation.org/rules/\n\trules: function( command, argument ) {\n\t\tvar element = this[ 0 ],\n\t\t\tsettings, staticRules, existingRules, data, param, filtered;\n\n\t\tif ( command ) {\n\t\t\tsettings = $.data( element.form, \"validator\" ).settings;\n\t\t\tstaticRules = settings.rules;\n\t\t\texistingRules = $.validator.staticRules( element );\n\t\t\tswitch ( command ) {\n\t\t\tcase \"add\":\n\t\t\t\t$.extend( existingRules, $.validator.normalizeRule( argument ) );\n\t\t\t\t// remove messages from rules, but allow them to be set separately\n\t\t\t\tdelete existingRules.messages;\n\t\t\t\tstaticRules[ element.name ] = existingRules;\n\t\t\t\tif ( argument.messages ) {\n\t\t\t\t\tsettings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"remove\":\n\t\t\t\tif ( !argument ) {\n\t\t\t\t\tdelete staticRules[ element.name ];\n\t\t\t\t\treturn existingRules;\n\t\t\t\t}\n\t\t\t\tfiltered = {};\n\t\t\t\t$.each( argument.split( /\\s/ ), function( index, method ) {\n\t\t\t\t\tfiltered[ method ] = existingRules[ method ];\n\t\t\t\t\tdelete existingRules[ method ];\n\t\t\t\t\tif ( method === \"required\" ) {\n\t\t\t\t\t\t$( element ).removeAttr( \"aria-required\" );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn filtered;\n\t\t\t}\n\t\t}\n\n\t\tdata = $.validator.normalizeRules(\n\t\t$.extend(\n\t\t\t{},\n\t\t\t$.validator.classRules( element ),\n\t\t\t$.validator.attributeRules( element ),\n\t\t\t$.validator.dataRules( element ),\n\t\t\t$.validator.staticRules( element )\n\t\t), element );\n\n\t\t// make sure required is at front\n\t\tif ( data.required ) {\n\t\t\tparam = data.required;\n\t\t\tdelete data.required;\n\t\t\tdata = $.extend( { required: param }, data );\n\t\t\t$( element ).attr( \"aria-required\", \"true\" );\n\t\t}\n\n\t\t// make sure remote is at back\n\t\tif ( data.remote ) {\n\t\t\tparam = data.remote;\n\t\t\tdelete data.remote;\n\t\t\tdata = $.extend( data, { remote: param });\n\t\t}\n\n\t\treturn data;\n\t}\n});\n\n// Custom selectors\n$.extend( $.expr[ \":\" ], {\n\t// http://jqueryvalidation.org/blank-selector/\n\tblank: function( a ) {\n\t\treturn !$.trim( \"\" + $( a ).val() );\n\t},\n\t// http://jqueryvalidation.org/filled-selector/\n\tfilled: function( a ) {\n\t\treturn !!$.trim( \"\" + $( a ).val() );\n\t},\n\t// http://jqueryvalidation.org/unchecked-selector/\n\tunchecked: function( a ) {\n\t\treturn !$( a ).prop( \"checked\" );\n\t}\n});\n\n// constructor for validator\n$.validator = function( options, form ) {\n\tthis.settings = $.extend( true, {}, $.validator.defaults, options );\n\tthis.currentForm = form;\n\tthis.init();\n};\n\n// http://jqueryvalidation.org/jQuery.validator.format/\n$.validator.format = function( source, params ) {\n\tif ( arguments.length === 1 ) {\n\t\treturn function() {\n\t\t\tvar args = $.makeArray( arguments );\n\t\t\targs.unshift( source );\n\t\t\treturn $.validator.format.apply( this, args );\n\t\t};\n\t}\n\tif ( arguments.length > 2 && params.constructor !== Array  ) {\n\t\tparams = $.makeArray( arguments ).slice( 1 );\n\t}\n\tif ( params.constructor !== Array ) {\n\t\tparams = [ params ];\n\t}\n\t$.each( params, function( i, n ) {\n\t\tsource = source.replace( new RegExp( \"\\\\{\" + i + \"\\\\}\", \"g\" ), function() {\n\t\t\treturn n;\n\t\t});\n\t});\n\treturn source;\n};\n\n$.extend( $.validator, {\n\n\tdefaults: {\n\t\tmessages: {},\n\t\tgroups: {},\n\t\trules: {},\n\t\terrorClass: \"error\",\n\t\tvalidClass: \"valid\",\n\t\terrorElement: \"label\",\n\t\tfocusCleanup: false,\n\t\tfocusInvalid: true,\n\t\terrorContainer: $( [] ),\n\t\terrorLabelContainer: $( [] ),\n\t\tonsubmit: true,\n\t\tignore: \":hidden\",\n\t\tignoreTitle: false,\n\t\tonfocusin: function( element ) {\n\t\t\tthis.lastActive = element;\n\n\t\t\t// Hide error label and remove error class on focus if enabled\n\t\t\tif ( this.settings.focusCleanup ) {\n\t\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.hideThese( this.errorsFor( element ) );\n\t\t\t}\n\t\t},\n\t\tonfocusout: function( element ) {\n\t\t\tif ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonkeyup: function( element, event ) {\n\t\t\t// Avoid revalidate the field when pressing one of the following keys\n\t\t\t// Shift       => 16\n\t\t\t// Ctrl        => 17\n\t\t\t// Alt         => 18\n\t\t\t// Caps lock   => 20\n\t\t\t// End         => 35\n\t\t\t// Home        => 36\n\t\t\t// Left arrow  => 37\n\t\t\t// Up arrow    => 38\n\t\t\t// Right arrow => 39\n\t\t\t// Down arrow  => 40\n\t\t\t// Insert      => 45\n\t\t\t// Num lock    => 144\n\t\t\t// AltGr key   => 225\n\t\t\tvar excludedKeys = [\n\t\t\t\t16, 17, 18, 20, 35, 36, 37,\n\t\t\t\t38, 39, 40, 45, 144, 225\n\t\t\t];\n\n\t\t\tif ( event.which === 9 && this.elementValue( element ) === \"\" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t} else if ( element.name in this.submitted || element === this.lastElement ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonclick: function( element ) {\n\t\t\t// click on selects, radiobuttons and checkboxes\n\t\t\tif ( element.name in this.submitted ) {\n\t\t\t\tthis.element( element );\n\n\t\t\t// or option elements, check parent select in that case\n\t\t\t} else if ( element.parentNode.name in this.submitted ) {\n\t\t\t\tthis.element( element.parentNode );\n\t\t\t}\n\t\t},\n\t\thighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).addClass( errorClass ).removeClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).addClass( errorClass ).removeClass( validClass );\n\t\t\t}\n\t\t},\n\t\tunhighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).removeClass( errorClass ).addClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).removeClass( errorClass ).addClass( validClass );\n\t\t\t}\n\t\t}\n\t},\n\n\t// http://jqueryvalidation.org/jQuery.validator.setDefaults/\n\tsetDefaults: function( settings ) {\n\t\t$.extend( $.validator.defaults, settings );\n\t},\n\n\tmessages: {\n\t\trequired: \"This field is required.\",\n\t\tremote: \"Please fix this field.\",\n\t\temail: \"Please enter a valid email address.\",\n\t\turl: \"Please enter a valid URL.\",\n\t\tdate: \"Please enter a valid date.\",\n\t\tdateISO: \"Please enter a valid date ( ISO ).\",\n\t\tnumber: \"Please enter a valid number.\",\n\t\tdigits: \"Please enter only digits.\",\n\t\tcreditcard: \"Please enter a valid credit card number.\",\n\t\tequalTo: \"Please enter the same value again.\",\n\t\tmaxlength: $.validator.format( \"Please enter no more than {0} characters.\" ),\n\t\tminlength: $.validator.format( \"Please enter at least {0} characters.\" ),\n\t\trangelength: $.validator.format( \"Please enter a value between {0} and {1} characters long.\" ),\n\t\trange: $.validator.format( \"Please enter a value between {0} and {1}.\" ),\n\t\tmax: $.validator.format( \"Please enter a value less than or equal to {0}.\" ),\n\t\tmin: $.validator.format( \"Please enter a value greater than or equal to {0}.\" )\n\t},\n\n\tautoCreateRanges: false,\n\n\tprototype: {\n\n\t\tinit: function() {\n\t\t\tthis.labelContainer = $( this.settings.errorLabelContainer );\n\t\t\tthis.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );\n\t\t\tthis.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );\n\t\t\tthis.submitted = {};\n\t\t\tthis.valueCache = {};\n\t\t\tthis.pendingRequest = 0;\n\t\t\tthis.pending = {};\n\t\t\tthis.invalid = {};\n\t\t\tthis.reset();\n\n\t\t\tvar groups = ( this.groups = {} ),\n\t\t\t\trules;\n\t\t\t$.each( this.settings.groups, function( key, value ) {\n\t\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\t\tvalue = value.split( /\\s/ );\n\t\t\t\t}\n\t\t\t\t$.each( value, function( index, name ) {\n\t\t\t\t\tgroups[ name ] = key;\n\t\t\t\t});\n\t\t\t});\n\t\t\trules = this.settings.rules;\n\t\t\t$.each( rules, function( key, value ) {\n\t\t\t\trules[ key ] = $.validator.normalizeRule( value );\n\t\t\t});\n\n\t\t\tfunction delegate( event ) {\n\t\t\t\tvar validator = $.data( this.form, \"validator\" ),\n\t\t\t\t\teventType = \"on\" + event.type.replace( /^validate/, \"\" ),\n\t\t\t\t\tsettings = validator.settings;\n\t\t\t\tif ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {\n\t\t\t\t\tsettings[ eventType ].call( validator, this, event );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.on( \"focusin.validate focusout.validate keyup.validate\",\n\t\t\t\t\t\":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], \" +\n\t\t\t\t\t\"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], \" +\n\t\t\t\t\t\"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], \" +\n\t\t\t\t\t\"[type='radio'], [type='checkbox']\", delegate)\n\t\t\t\t// Support: Chrome, oldIE\n\t\t\t\t// \"select\" is provided as event.target when clicking a option\n\t\t\t\t.on(\"click.validate\", \"select, option, [type='radio'], [type='checkbox']\", delegate);\n\n\t\t\tif ( this.settings.invalidHandler ) {\n\t\t\t\t$( this.currentForm ).on( \"invalid-form.validate\", this.settings.invalidHandler );\n\t\t\t}\n\n\t\t\t// Add aria-required to any Static/Data/Class required fields before first validation\n\t\t\t// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html\n\t\t\t$( this.currentForm ).find( \"[required], [data-rule-required], .required\" ).attr( \"aria-required\", \"true\" );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.form/\n\t\tform: function() {\n\t\t\tthis.checkForm();\n\t\t\t$.extend( this.submitted, this.errorMap );\n\t\t\tthis.invalid = $.extend({}, this.errorMap );\n\t\t\tif ( !this.valid() ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\n\t\t\t}\n\t\t\tthis.showErrors();\n\t\t\treturn this.valid();\n\t\t},\n\n\t\tcheckForm: function() {\n\t\t\tthis.prepareForm();\n\t\t\tfor ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {\n\t\t\t\tthis.check( elements[ i ] );\n\t\t\t}\n\t\t\treturn this.valid();\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.element/\n\t\telement: function( element ) {\n\t\t\tvar cleanElement = this.clean( element ),\n\t\t\t\tcheckElement = this.validationTargetFor( cleanElement ),\n\t\t\t\tresult = true;\n\n\t\t\tthis.lastElement = checkElement;\n\n\t\t\tif ( checkElement === undefined ) {\n\t\t\t\tdelete this.invalid[ cleanElement.name ];\n\t\t\t} else {\n\t\t\t\tthis.prepareElement( checkElement );\n\t\t\t\tthis.currentElements = $( checkElement );\n\n\t\t\t\tresult = this.check( checkElement ) !== false;\n\t\t\t\tif ( result ) {\n\t\t\t\t\tdelete this.invalid[ checkElement.name ];\n\t\t\t\t} else {\n\t\t\t\t\tthis.invalid[ checkElement.name ] = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add aria-invalid status for screen readers\n\t\t\t$( element ).attr( \"aria-invalid\", !result );\n\n\t\t\tif ( !this.numberOfInvalids() ) {\n\t\t\t\t// Hide error containers on last error\n\t\t\t\tthis.toHide = this.toHide.add( this.containers );\n\t\t\t}\n\t\t\tthis.showErrors();\n\t\t\treturn result;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.showErrors/\n\t\tshowErrors: function( errors ) {\n\t\t\tif ( errors ) {\n\t\t\t\t// add items to error list and map\n\t\t\t\t$.extend( this.errorMap, errors );\n\t\t\t\tthis.errorList = [];\n\t\t\t\tfor ( var name in errors ) {\n\t\t\t\t\tthis.errorList.push({\n\t\t\t\t\t\tmessage: errors[ name ],\n\t\t\t\t\t\telement: this.findByName( name )[ 0 ]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// remove items from success list\n\t\t\t\tthis.successList = $.grep( this.successList, function( element ) {\n\t\t\t\t\treturn !( element.name in errors );\n\t\t\t\t});\n\t\t\t}\n\t\t\tif ( this.settings.showErrors ) {\n\t\t\t\tthis.settings.showErrors.call( this, this.errorMap, this.errorList );\n\t\t\t} else {\n\t\t\t\tthis.defaultShowErrors();\n\t\t\t}\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.resetForm/\n\t\tresetForm: function() {\n\t\t\tif ( $.fn.resetForm ) {\n\t\t\t\t$( this.currentForm ).resetForm();\n\t\t\t}\n\t\t\tthis.submitted = {};\n\t\t\tthis.lastElement = null;\n\t\t\tthis.prepareForm();\n\t\t\tthis.hideErrors();\n\t\t\tvar i, elements = this.elements()\n\t\t\t\t.removeData( \"previousValue\" )\n\t\t\t\t.removeAttr( \"aria-invalid\" );\n\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0; elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ],\n\t\t\t\t\t\tthis.settings.errorClass, \"\" );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\telements.removeClass( this.settings.errorClass );\n\t\t\t}\n\t\t},\n\n\t\tnumberOfInvalids: function() {\n\t\t\treturn this.objectLength( this.invalid );\n\t\t},\n\n\t\tobjectLength: function( obj ) {\n\t\t\t/* jshint unused: false */\n\t\t\tvar count = 0,\n\t\t\t\ti;\n\t\t\tfor ( i in obj ) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\thideErrors: function() {\n\t\t\tthis.hideThese( this.toHide );\n\t\t},\n\n\t\thideThese: function( errors ) {\n\t\t\terrors.not( this.containers ).text( \"\" );\n\t\t\tthis.addWrapper( errors ).hide();\n\t\t},\n\n\t\tvalid: function() {\n\t\t\treturn this.size() === 0;\n\t\t},\n\n\t\tsize: function() {\n\t\t\treturn this.errorList.length;\n\t\t},\n\n\t\tfocusInvalid: function() {\n\t\t\tif ( this.settings.focusInvalid ) {\n\t\t\t\ttry {\n\t\t\t\t\t$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])\n\t\t\t\t\t.filter( \":visible\" )\n\t\t\t\t\t.focus()\n\t\t\t\t\t// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\n\t\t\t\t\t.trigger( \"focusin\" );\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t// ignore IE throwing errors when focusing hidden elements\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tfindLastActive: function() {\n\t\t\tvar lastActive = this.lastActive;\n\t\t\treturn lastActive && $.grep( this.errorList, function( n ) {\n\t\t\t\treturn n.element.name === lastActive.name;\n\t\t\t}).length === 1 && lastActive;\n\t\t},\n\n\t\telements: function() {\n\t\t\tvar validator = this,\n\t\t\t\trulesCache = {};\n\n\t\t\t// select all valid inputs inside the form (no submit or reset buttons)\n\t\t\treturn $( this.currentForm )\n\t\t\t.find( \"input, select, textarea\" )\n\t\t\t.not( \":submit, :reset, :image, :disabled\" )\n\t\t\t.not( this.settings.ignore )\n\t\t\t.filter( function() {\n\t\t\t\tif ( !this.name && validator.settings.debug && window.console ) {\n\t\t\t\t\tconsole.error( \"%o has no name assigned\", this );\n\t\t\t\t}\n\n\t\t\t\t// select only the first element for each name, and only those with rules specified\n\t\t\t\tif ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\trulesCache[ this.name ] = true;\n\t\t\t\treturn true;\n\t\t\t});\n\t\t},\n\n\t\tclean: function( selector ) {\n\t\t\treturn $( selector )[ 0 ];\n\t\t},\n\n\t\terrors: function() {\n\t\t\tvar errorClass = this.settings.errorClass.split( \" \" ).join( \".\" );\n\t\t\treturn $( this.settings.errorElement + \".\" + errorClass, this.errorContext );\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.successList = [];\n\t\t\tthis.errorList = [];\n\t\t\tthis.errorMap = {};\n\t\t\tthis.toShow = $( [] );\n\t\t\tthis.toHide = $( [] );\n\t\t\tthis.currentElements = $( [] );\n\t\t},\n\n\t\tprepareForm: function() {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errors().add( this.containers );\n\t\t},\n\n\t\tprepareElement: function( element ) {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errorsFor( element );\n\t\t},\n\n\t\telementValue: function( element ) {\n\t\t\tvar val,\n\t\t\t\t$element = $( element ),\n\t\t\t\ttype = element.type;\n\n\t\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\t\treturn this.findByName( element.name ).filter(\":checked\").val();\n\t\t\t} else if ( type === \"number\" && typeof element.validity !== \"undefined\" ) {\n\t\t\t\treturn element.validity.badInput ? false : $element.val();\n\t\t\t}\n\n\t\t\tval = $element.val();\n\t\t\tif ( typeof val === \"string\" ) {\n\t\t\t\treturn val.replace(/\\r/g, \"\" );\n\t\t\t}\n\t\t\treturn val;\n\t\t},\n\n\t\tcheck: function( element ) {\n\t\t\telement = this.validationTargetFor( this.clean( element ) );\n\n\t\t\tvar rules = $( element ).rules(),\n\t\t\t\trulesCount = $.map( rules, function( n, i ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}).length,\n\t\t\t\tdependencyMismatch = false,\n\t\t\t\tval = this.elementValue( element ),\n\t\t\t\tresult, method, rule;\n\n\t\t\tfor ( method in rules ) {\n\t\t\t\trule = { method: method, parameters: rules[ method ] };\n\t\t\t\ttry {\n\n\t\t\t\t\tresult = $.validator.methods[ method ].call( this, val, element, rule.parameters );\n\n\t\t\t\t\t// if a method indicates that the field is optional and therefore valid,\n\t\t\t\t\t// don't mark it as valid when there are no other rules\n\t\t\t\t\tif ( result === \"dependency-mismatch\" && rulesCount === 1 ) {\n\t\t\t\t\t\tdependencyMismatch = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tdependencyMismatch = false;\n\n\t\t\t\t\tif ( result === \"pending\" ) {\n\t\t\t\t\t\tthis.toHide = this.toHide.not( this.errorsFor( element ) );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !result ) {\n\t\t\t\t\t\tthis.formatAndAdd( element, rule );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tif ( this.settings.debug && window.console ) {\n\t\t\t\t\t\tconsole.log( \"Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\", e );\n\t\t\t\t\t}\n\t\t\t\t\tif ( e instanceof TypeError ) {\n\t\t\t\t\t\te.message += \".  Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\";\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( dependencyMismatch ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( this.objectLength( rules ) ) {\n\t\t\t\tthis.successList.push( element );\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t// return the custom message for the given element and validation method\n\t\t// specified in the element's HTML5 data attribute\n\t\t// return the generic message if present and no method specific message is present\n\t\tcustomDataMessage: function( element, method ) {\n\t\t\treturn $( element ).data( \"msg\" + method.charAt( 0 ).toUpperCase() +\n\t\t\t\tmethod.substring( 1 ).toLowerCase() ) || $( element ).data( \"msg\" );\n\t\t},\n\n\t\t// return the custom message for the given element name and validation method\n\t\tcustomMessage: function( name, method ) {\n\t\t\tvar m = this.settings.messages[ name ];\n\t\t\treturn m && ( m.constructor === String ? m : m[ method ]);\n\t\t},\n\n\t\t// return the first defined argument, allowing empty strings\n\t\tfindDefined: function() {\n\t\t\tfor ( var i = 0; i < arguments.length; i++) {\n\t\t\t\tif ( arguments[ i ] !== undefined ) {\n\t\t\t\t\treturn arguments[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\n\t\tdefaultMessage: function( element, method ) {\n\t\t\treturn this.findDefined(\n\t\t\t\tthis.customMessage( element.name, method ),\n\t\t\t\tthis.customDataMessage( element, method ),\n\t\t\t\t// title is never undefined, so handle empty string as undefined\n\t\t\t\t!this.settings.ignoreTitle && element.title || undefined,\n\t\t\t\t$.validator.messages[ method ],\n\t\t\t\t\"<strong>Warning: No message defined for \" + element.name + \"</strong>\"\n\t\t\t);\n\t\t},\n\n\t\tformatAndAdd: function( element, rule ) {\n\t\t\tvar message = this.defaultMessage( element, rule.method ),\n\t\t\t\ttheregex = /\\$?\\{(\\d+)\\}/g;\n\t\t\tif ( typeof message === \"function\" ) {\n\t\t\t\tmessage = message.call( this, rule.parameters, element );\n\t\t\t} else if ( theregex.test( message ) ) {\n\t\t\t\tmessage = $.validator.format( message.replace( theregex, \"{$1}\" ), rule.parameters );\n\t\t\t}\n\t\t\tthis.errorList.push({\n\t\t\t\tmessage: message,\n\t\t\t\telement: element,\n\t\t\t\tmethod: rule.method\n\t\t\t});\n\n\t\t\tthis.errorMap[ element.name ] = message;\n\t\t\tthis.submitted[ element.name ] = message;\n\t\t},\n\n\t\taddWrapper: function( toToggle ) {\n\t\t\tif ( this.settings.wrapper ) {\n\t\t\t\ttoToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\n\t\t\t}\n\t\t\treturn toToggle;\n\t\t},\n\n\t\tdefaultShowErrors: function() {\n\t\t\tvar i, elements, error;\n\t\t\tfor ( i = 0; this.errorList[ i ]; i++ ) {\n\t\t\t\terror = this.errorList[ i ];\n\t\t\t\tif ( this.settings.highlight ) {\n\t\t\t\t\tthis.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.showLabel( error.element, error.message );\n\t\t\t}\n\t\t\tif ( this.errorList.length ) {\n\t\t\t\tthis.toShow = this.toShow.add( this.containers );\n\t\t\t}\n\t\t\tif ( this.settings.success ) {\n\t\t\t\tfor ( i = 0; this.successList[ i ]; i++ ) {\n\t\t\t\t\tthis.showLabel( this.successList[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toHide = this.toHide.not( this.toShow );\n\t\t\tthis.hideErrors();\n\t\t\tthis.addWrapper( this.toShow ).show();\n\t\t},\n\n\t\tvalidElements: function() {\n\t\t\treturn this.currentElements.not( this.invalidElements() );\n\t\t},\n\n\t\tinvalidElements: function() {\n\t\t\treturn $( this.errorList ).map(function() {\n\t\t\t\treturn this.element;\n\t\t\t});\n\t\t},\n\n\t\tshowLabel: function( element, message ) {\n\t\t\tvar place, group, errorID,\n\t\t\t\terror = this.errorsFor( element ),\n\t\t\t\telementID = this.idOrName( element ),\n\t\t\t\tdescribedBy = $( element ).attr( \"aria-describedby\" );\n\t\t\tif ( error.length ) {\n\t\t\t\t// refresh error/success class\n\t\t\t\terror.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );\n\t\t\t\t// replace message on existing label\n\t\t\t\terror.html( message );\n\t\t\t} else {\n\t\t\t\t// create error element\n\t\t\t\terror = $( \"<\" + this.settings.errorElement + \">\" )\n\t\t\t\t\t.attr( \"id\", elementID + \"-error\" )\n\t\t\t\t\t.addClass( this.settings.errorClass )\n\t\t\t\t\t.html( message || \"\" );\n\n\t\t\t\t// Maintain reference to the element to be placed into the DOM\n\t\t\t\tplace = error;\n\t\t\t\tif ( this.settings.wrapper ) {\n\t\t\t\t\t// make sure the element is visible, even in IE\n\t\t\t\t\t// actually showing the wrapped element is handled elsewhere\n\t\t\t\t\tplace = error.hide().show().wrap( \"<\" + this.settings.wrapper + \"/>\" ).parent();\n\t\t\t\t}\n\t\t\t\tif ( this.labelContainer.length ) {\n\t\t\t\t\tthis.labelContainer.append( place );\n\t\t\t\t} else if ( this.settings.errorPlacement ) {\n\t\t\t\t\tthis.settings.errorPlacement( place, $( element ) );\n\t\t\t\t} else {\n\t\t\t\t\tplace.insertAfter( element );\n\t\t\t\t}\n\n\t\t\t\t// Link error back to the element\n\t\t\t\tif ( error.is( \"label\" ) ) {\n\t\t\t\t\t// If the error is a label, then associate using 'for'\n\t\t\t\t\terror.attr( \"for\", elementID );\n\t\t\t\t} else if ( error.parents( \"label[for='\" + elementID + \"']\" ).length === 0 ) {\n\t\t\t\t\t// If the element is not a child of an associated label, then it's necessary\n\t\t\t\t\t// to explicitly apply aria-describedby\n\n\t\t\t\t\terrorID = error.attr( \"id\" ).replace( /(:|\\.|\\[|\\]|\\$)/g, \"\\\\$1\");\n\t\t\t\t\t// Respect existing non-error aria-describedby\n\t\t\t\t\tif ( !describedBy ) {\n\t\t\t\t\t\tdescribedBy = errorID;\n\t\t\t\t\t} else if ( !describedBy.match( new RegExp( \"\\\\b\" + errorID + \"\\\\b\" ) ) ) {\n\t\t\t\t\t\t// Add to end of list if not already present\n\t\t\t\t\t\tdescribedBy += \" \" + errorID;\n\t\t\t\t\t}\n\t\t\t\t\t$( element ).attr( \"aria-describedby\", describedBy );\n\n\t\t\t\t\t// If this element is grouped, then assign to all elements in the same group\n\t\t\t\t\tgroup = this.groups[ element.name ];\n\t\t\t\t\tif ( group ) {\n\t\t\t\t\t\t$.each( this.groups, function( name, testgroup ) {\n\t\t\t\t\t\t\tif ( testgroup === group ) {\n\t\t\t\t\t\t\t\t$( \"[name='\" + name + \"']\", this.currentForm )\n\t\t\t\t\t\t\t\t\t.attr( \"aria-describedby\", error.attr( \"id\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !message && this.settings.success ) {\n\t\t\t\terror.text( \"\" );\n\t\t\t\tif ( typeof this.settings.success === \"string\" ) {\n\t\t\t\t\terror.addClass( this.settings.success );\n\t\t\t\t} else {\n\t\t\t\t\tthis.settings.success( error, element );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toShow = this.toShow.add( error );\n\t\t},\n\n\t\terrorsFor: function( element ) {\n\t\t\tvar name = this.idOrName( element ),\n\t\t\t\tdescriber = $( element ).attr( \"aria-describedby\" ),\n\t\t\t\tselector = \"label[for='\" + name + \"'], label[for='\" + name + \"'] *\";\n\n\t\t\t// aria-describedby should directly reference the error element\n\t\t\tif ( describer ) {\n\t\t\t\tselector = selector + \", #\" + describer.replace( /\\s+/g, \", #\" );\n\t\t\t}\n\t\t\treturn this\n\t\t\t\t.errors()\n\t\t\t\t.filter( selector );\n\t\t},\n\n\t\tidOrName: function( element ) {\n\t\t\treturn this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );\n\t\t},\n\n\t\tvalidationTargetFor: function( element ) {\n\n\t\t\t// If radio/checkbox, validate first element in group instead\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\telement = this.findByName( element.name );\n\t\t\t}\n\n\t\t\t// Always apply ignore filter\n\t\t\treturn $( element ).not( this.settings.ignore )[ 0 ];\n\t\t},\n\n\t\tcheckable: function( element ) {\n\t\t\treturn ( /radio|checkbox/i ).test( element.type );\n\t\t},\n\n\t\tfindByName: function( name ) {\n\t\t\treturn $( this.currentForm ).find( \"[name='\" + name + \"']\" );\n\t\t},\n\n\t\tgetLength: function( value, element ) {\n\t\t\tswitch ( element.nodeName.toLowerCase() ) {\n\t\t\tcase \"select\":\n\t\t\t\treturn $( \"option:selected\", element ).length;\n\t\t\tcase \"input\":\n\t\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\t\treturn this.findByName( element.name ).filter( \":checked\" ).length;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value.length;\n\t\t},\n\n\t\tdepend: function( param, element ) {\n\t\t\treturn this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;\n\t\t},\n\n\t\tdependTypes: {\n\t\t\t\"boolean\": function( param ) {\n\t\t\t\treturn param;\n\t\t\t},\n\t\t\t\"string\": function( param, element ) {\n\t\t\t\treturn !!$( param, element.form ).length;\n\t\t\t},\n\t\t\t\"function\": function( param, element ) {\n\t\t\t\treturn param( element );\n\t\t\t}\n\t\t},\n\n\t\toptional: function( element ) {\n\t\t\tvar val = this.elementValue( element );\n\t\t\treturn !$.validator.methods.required.call( this, val, element ) && \"dependency-mismatch\";\n\t\t},\n\n\t\tstartRequest: function( element ) {\n\t\t\tif ( !this.pending[ element.name ] ) {\n\t\t\t\tthis.pendingRequest++;\n\t\t\t\tthis.pending[ element.name ] = true;\n\t\t\t}\n\t\t},\n\n\t\tstopRequest: function( element, valid ) {\n\t\t\tthis.pendingRequest--;\n\t\t\t// sometimes synchronization fails, make sure pendingRequest is never < 0\n\t\t\tif ( this.pendingRequest < 0 ) {\n\t\t\t\tthis.pendingRequest = 0;\n\t\t\t}\n\t\t\tdelete this.pending[ element.name ];\n\t\t\tif ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {\n\t\t\t\t$( this.currentForm ).submit();\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t} else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t}\n\t\t},\n\n\t\tpreviousValue: function( element ) {\n\t\t\treturn $.data( element, \"previousValue\" ) || $.data( element, \"previousValue\", {\n\t\t\t\told: null,\n\t\t\t\tvalid: true,\n\t\t\t\tmessage: this.defaultMessage( element, \"remote\" )\n\t\t\t});\n\t\t},\n\n\t\t// cleans up all forms and elements, removes validator-specific events\n\t\tdestroy: function() {\n\t\t\tthis.resetForm();\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.off( \".validate\" )\n\t\t\t\t.removeData( \"validator\" );\n\t\t}\n\n\t},\n\n\tclassRuleSettings: {\n\t\trequired: { required: true },\n\t\temail: { email: true },\n\t\turl: { url: true },\n\t\tdate: { date: true },\n\t\tdateISO: { dateISO: true },\n\t\tnumber: { number: true },\n\t\tdigits: { digits: true },\n\t\tcreditcard: { creditcard: true }\n\t},\n\n\taddClassRules: function( className, rules ) {\n\t\tif ( className.constructor === String ) {\n\t\t\tthis.classRuleSettings[ className ] = rules;\n\t\t} else {\n\t\t\t$.extend( this.classRuleSettings, className );\n\t\t}\n\t},\n\n\tclassRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tclasses = $( element ).attr( \"class\" );\n\n\t\tif ( classes ) {\n\t\t\t$.each( classes.split( \" \" ), function() {\n\t\t\t\tif ( this in $.validator.classRuleSettings ) {\n\t\t\t\t\t$.extend( rules, $.validator.classRuleSettings[ this ]);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeAttributeRule: function( rules, type, method, value ) {\n\n\t\t// convert the value to a number for number inputs, and for text for backwards compability\n\t\t// allows type=\"date\" and others to be compared as strings\n\t\tif ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {\n\t\t\tvalue = Number( value );\n\n\t\t\t// Support Opera Mini, which returns NaN for undefined minlength\n\t\t\tif ( isNaN( value ) ) {\n\t\t\t\tvalue = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif ( value || value === 0 ) {\n\t\t\trules[ method ] = value;\n\t\t} else if ( type === method && type !== \"range\" ) {\n\n\t\t\t// exception: the jquery validate 'range' method\n\t\t\t// does not test for the html5 'range' type\n\t\t\trules[ method ] = true;\n\t\t}\n\t},\n\n\tattributeRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\n\t\t\t// support for <input required> in both html5 and older browsers\n\t\t\tif ( method === \"required\" ) {\n\t\t\t\tvalue = element.getAttribute( method );\n\n\t\t\t\t// Some browsers return an empty string for the required attribute\n\t\t\t\t// and non-HTML5 browsers might have required=\"\" markup\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\tvalue = true;\n\t\t\t\t}\n\n\t\t\t\t// force non-HTML5 browsers to return bool\n\t\t\t\tvalue = !!value;\n\t\t\t} else {\n\t\t\t\tvalue = $element.attr( method );\n\t\t\t}\n\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\n\t\t// maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs\n\t\tif ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {\n\t\t\tdelete rules.maxlength;\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\tdataRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\t\t\tvalue = $element.data( \"rule\" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\t\treturn rules;\n\t},\n\n\tstaticRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tvalidator = $.data( element.form, \"validator\" );\n\n\t\tif ( validator.settings.rules ) {\n\t\t\trules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeRules: function( rules, element ) {\n\t\t// handle dependency check\n\t\t$.each( rules, function( prop, val ) {\n\t\t\t// ignore rule when param is explicitly false, eg. required:false\n\t\t\tif ( val === false ) {\n\t\t\t\tdelete rules[ prop ];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( val.param || val.depends ) {\n\t\t\t\tvar keepRule = true;\n\t\t\t\tswitch ( typeof val.depends ) {\n\t\t\t\tcase \"string\":\n\t\t\t\t\tkeepRule = !!$( val.depends, element.form ).length;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"function\":\n\t\t\t\t\tkeepRule = val.depends.call( element, element );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( keepRule ) {\n\t\t\t\t\trules[ prop ] = val.param !== undefined ? val.param : true;\n\t\t\t\t} else {\n\t\t\t\t\tdelete rules[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// evaluate parameters\n\t\t$.each( rules, function( rule, parameter ) {\n\t\t\trules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;\n\t\t});\n\n\t\t// clean number parameters\n\t\t$.each([ \"minlength\", \"maxlength\" ], function() {\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\trules[ this ] = Number( rules[ this ] );\n\t\t\t}\n\t\t});\n\t\t$.each([ \"rangelength\", \"range\" ], function() {\n\t\t\tvar parts;\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\tif ( $.isArray( rules[ this ] ) ) {\n\t\t\t\t\trules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];\n\t\t\t\t} else if ( typeof rules[ this ] === \"string\" ) {\n\t\t\t\t\tparts = rules[ this ].replace(/[\\[\\]]/g, \"\" ).split( /[\\s,]+/ );\n\t\t\t\t\trules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif ( $.validator.autoCreateRanges ) {\n\t\t\t// auto-create ranges\n\t\t\tif ( rules.min != null && rules.max != null ) {\n\t\t\t\trules.range = [ rules.min, rules.max ];\n\t\t\t\tdelete rules.min;\n\t\t\t\tdelete rules.max;\n\t\t\t}\n\t\t\tif ( rules.minlength != null && rules.maxlength != null ) {\n\t\t\t\trules.rangelength = [ rules.minlength, rules.maxlength ];\n\t\t\t\tdelete rules.minlength;\n\t\t\t\tdelete rules.maxlength;\n\t\t\t}\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\t// Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\n\tnormalizeRule: function( data ) {\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tvar transformed = {};\n\t\t\t$.each( data.split( /\\s/ ), function() {\n\t\t\t\ttransformed[ this ] = true;\n\t\t\t});\n\t\t\tdata = transformed;\n\t\t}\n\t\treturn data;\n\t},\n\n\t// http://jqueryvalidation.org/jQuery.validator.addMethod/\n\taddMethod: function( name, method, message ) {\n\t\t$.validator.methods[ name ] = method;\n\t\t$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];\n\t\tif ( method.length < 3 ) {\n\t\t\t$.validator.addClassRules( name, $.validator.normalizeRule( name ) );\n\t\t}\n\t},\n\n\tmethods: {\n\n\t\t// http://jqueryvalidation.org/required-method/\n\t\trequired: function( value, element, param ) {\n\t\t\t// check if dependency is met\n\t\t\tif ( !this.depend( param, element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\t\t\tif ( element.nodeName.toLowerCase() === \"select\" ) {\n\t\t\t\t// could be an array for select-multiple or a string, both are fine this way\n\t\t\t\tvar val = $( element ).val();\n\t\t\t\treturn val && val.length > 0;\n\t\t\t}\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\treturn this.getLength( value, element ) > 0;\n\t\t\t}\n\t\t\treturn value.length > 0;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/email-method/\n\t\temail: function( value, element ) {\n\t\t\t// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address\n\t\t\t// Retrieved 2014-01-14\n\t\t\t// If you have a problem with this implementation, report a bug against the above spec\n\t\t\t// Or use custom methods to implement your own email validation\n\t\t\treturn this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/url-method/\n\t\turl: function( value, element ) {\n\n\t\t\t// Copyright (c) 2010-2013 Diego Perini, MIT licensed\n\t\t\t// https://gist.github.com/dperini/729294\n\t\t\t// see also https://mathiasbynens.be/demo/url-regex\n\t\t\t// modified to allow protocol-relative URLs\n\t\t\treturn this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})).?)(?::\\d{2,5})?(?:[/?#]\\S*)?$/i.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/date-method/\n\t\tdate: function( value, element ) {\n\t\t\treturn this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/dateISO-method/\n\t\tdateISO: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/number-method/\n\t\tnumber: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^(?:-?\\d+|-?\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/digits-method/\n\t\tdigits: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d+$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/creditcard-method/\n\t\t// based on http://en.wikipedia.org/wiki/Luhn_algorithm\n\t\tcreditcard: function( value, element ) {\n\t\t\tif ( this.optional( element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\t\t\t// accept only spaces, digits and dashes\n\t\t\tif ( /[^0-9 \\-]+/.test( value ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar nCheck = 0,\n\t\t\t\tnDigit = 0,\n\t\t\t\tbEven = false,\n\t\t\t\tn, cDigit;\n\n\t\t\tvalue = value.replace( /\\D/g, \"\" );\n\n\t\t\t// Basing min and max length on\n\t\t\t// http://developer.ean.com/general_info/Valid_Credit_Card_Types\n\t\t\tif ( value.length < 13 || value.length > 19 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor ( n = value.length - 1; n >= 0; n--) {\n\t\t\t\tcDigit = value.charAt( n );\n\t\t\t\tnDigit = parseInt( cDigit, 10 );\n\t\t\t\tif ( bEven ) {\n\t\t\t\t\tif ( ( nDigit *= 2 ) > 9 ) {\n\t\t\t\t\t\tnDigit -= 9;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnCheck += nDigit;\n\t\t\t\tbEven = !bEven;\n\t\t\t}\n\n\t\t\treturn ( nCheck % 10 ) === 0;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/minlength-method/\n\t\tminlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length >= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/maxlength-method/\n\t\tmaxlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length <= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/rangelength-method/\n\t\trangelength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/min-method/\n\t\tmin: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value >= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/max-method/\n\t\tmax: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value <= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/range-method/\n\t\trange: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/equalTo-method/\n\t\tequalTo: function( value, element, param ) {\n\t\t\t// bind to the blur event of the target in order to revalidate whenever the target field is updated\n\t\t\t// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead\n\t\t\tvar target = $( param );\n\t\t\tif ( this.settings.onfocusout ) {\n\t\t\t\ttarget.off( \".validate-equalTo\" ).on( \"blur.validate-equalTo\", function() {\n\t\t\t\t\t$( element ).valid();\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn value === target.val();\n\t\t},\n\n\t\t// http://jqueryvalidation.org/remote-method/\n\t\tremote: function( value, element, param ) {\n\t\t\tif ( this.optional( element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\n\t\t\tvar previous = this.previousValue( element ),\n\t\t\t\tvalidator, data;\n\n\t\t\tif (!this.settings.messages[ element.name ] ) {\n\t\t\t\tthis.settings.messages[ element.name ] = {};\n\t\t\t}\n\t\t\tprevious.originalMessage = this.settings.messages[ element.name ].remote;\n\t\t\tthis.settings.messages[ element.name ].remote = previous.message;\n\n\t\t\tparam = typeof param === \"string\" && { url: param } || param;\n\n\t\t\tif ( previous.old === value ) {\n\t\t\t\treturn previous.valid;\n\t\t\t}\n\n\t\t\tprevious.old = value;\n\t\t\tvalidator = this;\n\t\t\tthis.startRequest( element );\n\t\t\tdata = {};\n\t\t\tdata[ element.name ] = value;\n\t\t\t$.ajax( $.extend( true, {\n\t\t\t\tmode: \"abort\",\n\t\t\t\tport: \"validate\" + element.name,\n\t\t\t\tdataType: \"json\",\n\t\t\t\tdata: data,\n\t\t\t\tcontext: validator.currentForm,\n\t\t\t\tsuccess: function( response ) {\n\t\t\t\t\tvar valid = response === true || response === \"true\",\n\t\t\t\t\t\terrors, message, submitted;\n\n\t\t\t\t\tvalidator.settings.messages[ element.name ].remote = previous.originalMessage;\n\t\t\t\t\tif ( valid ) {\n\t\t\t\t\t\tsubmitted = validator.formSubmitted;\n\t\t\t\t\t\tvalidator.prepareElement( element );\n\t\t\t\t\t\tvalidator.formSubmitted = submitted;\n\t\t\t\t\t\tvalidator.successList.push( element );\n\t\t\t\t\t\tdelete validator.invalid[ element.name ];\n\t\t\t\t\t\tvalidator.showErrors();\n\t\t\t\t\t} else {\n\t\t\t\t\t\terrors = {};\n\t\t\t\t\t\tmessage = response || validator.defaultMessage( element, \"remote\" );\n\t\t\t\t\t\terrors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;\n\t\t\t\t\t\tvalidator.invalid[ element.name ] = true;\n\t\t\t\t\t\tvalidator.showErrors( errors );\n\t\t\t\t\t}\n\t\t\t\t\tprevious.valid = valid;\n\t\t\t\t\tvalidator.stopRequest( element, valid );\n\t\t\t\t}\n\t\t\t}, param ) );\n\t\t\treturn \"pending\";\n\t\t}\n\t}\n\n});\n\n// ajax mode: abort\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()\n\nvar pendingRequests = {},\n\tajax;\n// Use a prefilter if available (1.5+)\nif ( $.ajaxPrefilter ) {\n\t$.ajaxPrefilter(function( settings, _, xhr ) {\n\t\tvar port = settings.port;\n\t\tif ( settings.mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[port] ) {\n\t\t\t\tpendingRequests[port].abort();\n\t\t\t}\n\t\t\tpendingRequests[port] = xhr;\n\t\t}\n\t});\n} else {\n\t// Proxy ajax\n\tajax = $.ajax;\n\t$.ajax = function( settings ) {\n\t\tvar mode = ( \"mode\" in settings ? settings : $.ajaxSettings ).mode,\n\t\t\tport = ( \"port\" in settings ? settings : $.ajaxSettings ).port;\n\t\tif ( mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[port] ) {\n\t\t\t\tpendingRequests[port].abort();\n\t\t\t}\n\t\t\tpendingRequests[port] = ajax.apply(this, arguments);\n\t\t\treturn pendingRequests[port];\n\t\t}\n\t\treturn ajax.apply(this, arguments);\n\t};\n}\n\n}));"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/package.json",
    "content": "{\n\t\"name\": \"jquery-validation\",\n\t\"title\": \"jQuery Validation Plugin\",\n\t\"description\": \"Client-side form validation made easy\",\n\t\"version\": \"1.14.0\",\n\t\"homepage\": \"http://jqueryvalidation.org/\",\n\t\"license\": \"MIT\",\n\t\"author\": {\n\t\t\"name\": \"Jörn Zaefferer\",\n\t\t\"email\": \"joern.zaefferer@gmail.com\",\n\t\t\"url\": \"http://bassistance.de\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"git://github.com/jzaefferer/jquery-validation.git\"\n\t},\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/jzaefferer/jquery-validation/issues\"\n\t},\n\t\"licenses\": [\n\t\t{\n\t\t\t\"type\": \"MIT\",\n\t\t\t\"url\": \"http://www.opensource.org/licenses/MIT\"\n\t\t}\n\t],\n\t\"scripts\": {\n\t\t\"test\": \"grunt\",\n\t\t\"prepublish\": \"grunt\"\n\t},\n\t\"files\": [\n\t\t\"dist/localization/\",\n\t\t\"dist/additional-methods.js\",\n\t\t\"dist/jquery.validate.js\"\n\t],\n\t\"main\": \"dist/jquery.validate.js\",\n\t\"dependencies\": {},\n\t\"devDependencies\": {\n\t\t\"commitplease\": \"2.0.0\",\n\t\t\"grunt\": \"0.4.4\",\n\t\t\"grunt-contrib-compress\": \"0.7.0\",\n\t\t\"grunt-contrib-concat\": \"0.3.0\",\n\t\t\"grunt-contrib-copy\": \"0.5.0\",\n\t\t\"grunt-contrib-jshint\": \"^0.10.0\",\n\t\t\"grunt-contrib-qunit\": \"0.4.0\",\n\t\t\"grunt-contrib-uglify\": \"0.4.0\",\n\t\t\"grunt-contrib-watch\": \"0.6.0\",\n\t\t\"grunt-jscs\": \"1.0.0\",\n\t\t\"grunt-text-replace\": \"0.3.11\"\n\t},\n\t\"keywords\": [\n\t\t\"jquery\",\n\t\t\"jquery-plugin\",\n\t\t\"forms\",\n\t\t\"validation\",\n\t\t\"validate\"\n\t]\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/accept.js",
    "content": "// Accept a value from a file input based on a required mimetype\n$.validator.addMethod(\"accept\", function(value, element, param) {\n\t// Split mime on commas in case we have multiple types we can accept\n\tvar typeParam = typeof param === \"string\" ? param.replace(/\\s/g, \"\").replace(/,/g, \"|\") : \"image/*\",\n\toptionalValue = this.optional(element),\n\ti, file;\n\n\t// Element is optional\n\tif (optionalValue) {\n\t\treturn optionalValue;\n\t}\n\n\tif ($(element).attr(\"type\") === \"file\") {\n\t\t// If we are using a wildcard, make it regex friendly\n\t\ttypeParam = typeParam.replace(/\\*/g, \".*\");\n\n\t\t// Check if the element has a FileList before checking each file\n\t\tif (element.files && element.files.length) {\n\t\t\tfor (i = 0; i < element.files.length; i++) {\n\t\t\t\tfile = element.files[i];\n\n\t\t\t\t// Grab the mimetype from the loaded file, verify it matches\n\t\t\t\tif (!file.type.match(new RegExp( \"\\\\.?(\" + typeParam + \")$\", \"i\"))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Either return true because we've validated each file, or because the\n\t// browser does not support element.files and the FileList feature\n\treturn true;\n}, $.validator.format(\"Please enter a value with a valid mimetype.\"));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/additional.js",
    "content": "(function() {\n\n\tfunction stripHtml(value) {\n\t\t// remove html tags and space chars\n\t\treturn value.replace(/<.[^<>]*?>/g, \" \").replace(/&nbsp;|&#160;/gi, \" \")\n\t\t// remove punctuation\n\t\t.replace(/[.(),;:!?%#$'\\\"_+=\\/\\-“”’]*/g, \"\");\n\t}\n\n\t$.validator.addMethod(\"maxWords\", function(value, element, params) {\n\t\treturn this.optional(element) || stripHtml(value).match(/\\b\\w+\\b/g).length <= params;\n\t}, $.validator.format(\"Please enter {0} words or less.\"));\n\n\t$.validator.addMethod(\"minWords\", function(value, element, params) {\n\t\treturn this.optional(element) || stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n\t}, $.validator.format(\"Please enter at least {0} words.\"));\n\n\t$.validator.addMethod(\"rangeWords\", function(value, element, params) {\n\t\tvar valueStripped = stripHtml(value),\n\t\t\tregex = /\\b\\w+\\b/g;\n\t\treturn this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];\n\t}, $.validator.format(\"Please enter between {0} and {1} words.\"));\n\n}());\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/alphanumeric.js",
    "content": "$.validator.addMethod(\"alphanumeric\", function(value, element) {\n\treturn this.optional(element) || /^\\w+$/i.test(value);\n}, \"Letters, numbers, and underscores only please\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/bankaccountNL.js",
    "content": "/*\n * Dutch bank account numbers (not 'giro' numbers) have 9 digits\n * and pass the '11 check'.\n * We accept the notation with spaces, as that is common.\n * acceptable: 123456789 or 12 34 56 789\n */\n$.validator.addMethod(\"bankaccountNL\", function(value, element) {\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\tif (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {\n\t\treturn false;\n\t}\n\t// now '11 check'\n\tvar account = value.replace(/ /g, \"\"), // remove spaces\n\t\tsum = 0,\n\t\tlen = account.length,\n\t\tpos, factor, digit;\n\tfor ( pos = 0; pos < len; pos++ ) {\n\t\tfactor = len - pos;\n\t\tdigit = account.substring(pos, pos + 1);\n\t\tsum = sum + factor * digit;\n\t}\n\treturn sum % 11 === 0;\n}, \"Please specify a valid bank account number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/bankorgiroaccountNL.js",
    "content": "$.validator.addMethod(\"bankorgiroaccountNL\", function(value, element) {\n\treturn this.optional(element) ||\n\t\t\t($.validator.methods.bankaccountNL.call(this, value, element)) ||\n\t\t\t($.validator.methods.giroaccountNL.call(this, value, element));\n}, \"Please specify a valid bank or giro account number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/bic.js",
    "content": "/**\n * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.\n *\n * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)\n *\n * BIC definition in detail:\n * - First 4 characters - bank code (only letters)\n * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)\n * - Next 2 characters - location code (letters and digits)\n *   a. shall not start with '0' or '1'\n *   b. second character must be a letter ('O' is not allowed) or one of the following digits ('0' for test (therefore not allowed), '1' for passive participant and '2' for active participant)\n * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)\n */\n$.validator.addMethod(\"bic\", function(value, element) {\n    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value );\n}, \"Please specify a valid BIC code\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/cifES.js",
    "content": "/*\n * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities\n * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal\n */\n$.validator.addMethod( \"cifES\", function( value ) {\n\t\"use strict\";\n\n\tvar num = [],\n\t\tcontrolDigit, sum, i, count, tmp, secondDigit;\n\n\tvalue = value.toUpperCase();\n\n\t// Quick format test\n\tif ( !value.match( \"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\" ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( i = 0; i < 9; i++ ) {\n\t\tnum[ i ] = parseInt( value.charAt( i ), 10 );\n\t}\n\n\t// Algorithm for checking CIF codes\n\tsum = num[ 2 ] + num[ 4 ] + num[ 6 ];\n\tfor ( count = 1; count < 8; count += 2 ) {\n\t\ttmp = ( 2 * num[ count ] ).toString();\n\t\tsecondDigit = tmp.charAt( 1 );\n\n\t\tsum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === \"\" ? 0 : parseInt( secondDigit, 10 ) );\n\t}\n\n\t/* The first (position 1) is a letter following the following criteria:\n\t *\tA. Corporations\n\t *\tB. LLCs\n\t *\tC. General partnerships\n\t *\tD. Companies limited partnerships\n\t *\tE. Communities of goods\n\t *\tF. Cooperative Societies\n\t *\tG. Associations\n\t *\tH. Communities of homeowners in horizontal property regime\n\t *\tJ. Civil Societies\n\t *\tK. Old format\n\t *\tL. Old format\n\t *\tM. Old format\n\t *\tN. Nonresident entities\n\t *\tP. Local authorities\n\t *\tQ. Autonomous bodies, state or not, and the like, and congregations and religious institutions\n\t *\tR. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)\n\t *\tS. Organs of State Administration and regions\n\t *\tV. Agrarian Transformation\n\t *\tW. Permanent establishments of non-resident in Spain\n\t */\n\tif ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {\n\t\tsum += \"\";\n\t\tcontrolDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );\n\t\tvalue += controlDigit;\n\t\treturn ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid CIF number.\" );\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/cpfBR.js",
    "content": "/*\n * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.\n * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.\n */\n$.validator.addMethod(\"cpfBR\", function(value) {\n\t// Removing special characters from value\n\tvalue = value.replace(/([~!@#$%^&*()_+=`{}\\[\\]\\-|\\\\:;'<>,.\\/? ])+/g, \"\");\n\n\t// Checking value to have 11 digits only\n\tif (value.length !== 11) {\n\t\treturn false;\n\t}\n\n\tvar sum = 0,\n\t\tfirstCN, secondCN, checkResult, i;\n\n\tfirstCN = parseInt(value.substring(9, 10), 10);\n\tsecondCN = parseInt(value.substring(10, 11), 10);\n\n\tcheckResult = function(sum, cn) {\n\t\tvar result = (sum * 10) % 11;\n\t\tif ((result === 10) || (result === 11)) {result = 0;}\n\t\treturn (result === cn);\n\t};\n\n\t// Checking for dump data\n\tif (value === \"\" ||\n\t\tvalue === \"00000000000\" ||\n\t\tvalue === \"11111111111\" ||\n\t\tvalue === \"22222222222\" ||\n\t\tvalue === \"33333333333\" ||\n\t\tvalue === \"44444444444\" ||\n\t\tvalue === \"55555555555\" ||\n\t\tvalue === \"66666666666\" ||\n\t\tvalue === \"77777777777\" ||\n\t\tvalue === \"88888888888\" ||\n\t\tvalue === \"99999999999\"\n\t) {\n\t\treturn false;\n\t}\n\n\t// Step 1 - using first Check Number:\n\tfor ( i = 1; i <= 9; i++ ) {\n\t\tsum = sum + parseInt(value.substring(i - 1, i), 10) * (11 - i);\n\t}\n\n\t// If first Check Number (CN) is valid, move to Step 2 - using second Check Number:\n\tif ( checkResult(sum, firstCN) ) {\n\t\tsum = 0;\n\t\tfor ( i = 1; i <= 10; i++ ) {\n\t\t\tsum = sum + parseInt(value.substring(i - 1, i), 10) * (12 - i);\n\t\t}\n\t\treturn checkResult(sum, secondCN);\n\t}\n\treturn false;\n\n}, \"Please specify a valid CPF number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/creditcardtypes.js",
    "content": "/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator\n * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0\n * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)\n */\n$.validator.addMethod(\"creditcardtypes\", function(value, element, param) {\n\tif (/[^0-9\\-]+/.test(value)) {\n\t\treturn false;\n\t}\n\n\tvalue = value.replace(/\\D/g, \"\");\n\n\tvar validTypes = 0x0000;\n\n\tif (param.mastercard) {\n\t\tvalidTypes |= 0x0001;\n\t}\n\tif (param.visa) {\n\t\tvalidTypes |= 0x0002;\n\t}\n\tif (param.amex) {\n\t\tvalidTypes |= 0x0004;\n\t}\n\tif (param.dinersclub) {\n\t\tvalidTypes |= 0x0008;\n\t}\n\tif (param.enroute) {\n\t\tvalidTypes |= 0x0010;\n\t}\n\tif (param.discover) {\n\t\tvalidTypes |= 0x0020;\n\t}\n\tif (param.jcb) {\n\t\tvalidTypes |= 0x0040;\n\t}\n\tif (param.unknown) {\n\t\tvalidTypes |= 0x0080;\n\t}\n\tif (param.all) {\n\t\tvalidTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n\t}\n\tif (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub\n\t\treturn value.length === 14;\n\t}\n\tif (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n\t\treturn value.length === 16;\n\t}\n\tif (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n\t\treturn value.length === 15;\n\t}\n\tif (validTypes & 0x0080) { //unknown\n\t\treturn true;\n\t}\n\treturn false;\n}, \"Please enter a valid credit card number.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/currency.js",
    "content": "/**\n * Validates currencies with any given symbols by @jameslouiz\n * Symbols can be optional or required. Symbols required by default\n *\n * Usage examples:\n *  currency: [\"£\", false] - Use false for soft currency validation\n *  currency: [\"$\", false]\n *  currency: [\"RM\", false] - also works with text based symbols such as \"RM\" - Malaysia Ringgit etc\n *\n *  <input class=\"currencyInput\" name=\"currencyInput\">\n *\n * Soft symbol checking\n *  currencyInput: {\n *     currency: [\"$\", false]\n *  }\n *\n * Strict symbol checking (default)\n *  currencyInput: {\n *     currency: \"$\"\n *     //OR\n *     currency: [\"$\", true]\n *  }\n *\n * Multiple Symbols\n *  currencyInput: {\n *     currency: \"$,£,¢\"\n *  }\n */\n$.validator.addMethod(\"currency\", function(value, element, param) {\n    var isParamString = typeof param === \"string\",\n        symbol = isParamString ? param : param[0],\n        soft = isParamString ? true : param[1],\n        regex;\n\n    symbol = symbol.replace(/,/g, \"\");\n    symbol = soft ? symbol + \"]\" : symbol + \"]?\";\n    regex = \"^[\" + symbol + \"([1-9]{1}[0-9]{0,2}(\\\\,[0-9]{3})*(\\\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\\\.[0-9]{0,2})?|0(\\\\.[0-9]{0,2})?|(\\\\.[0-9]{1,2})?)$\";\n    regex = new RegExp(regex);\n    return this.optional(element) || regex.test(value);\n\n}, \"Please specify a valid currency\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/dateFA.js",
    "content": "$.validator.addMethod(\"dateFA\", function(value, element) {\n\treturn this.optional(element) || /^[1-4]\\d{3}\\/((0?[1-6]\\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(value);\n}, $.validator.messages.date);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/dateITA.js",
    "content": "/**\n * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.\n *\n * @example $.validator.methods.date(\"01/01/1900\")\n * @result true\n *\n * @example $.validator.methods.date(\"01/13/1990\")\n * @result false\n *\n * @example $.validator.methods.date(\"01.01.1900\")\n * @result false\n *\n * @example <input name=\"pippo\" class=\"{dateITA:true}\" />\n * @desc Declares an optional input element whose value must be a valid date.\n *\n * @name $.validator.methods.dateITA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod(\"dateITA\", function(value, element) {\n\tvar check = false,\n\t\tre = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n\t\tadata, gg, mm, aaaa, xdata;\n\tif ( re.test(value)) {\n\t\tadata = value.split(\"/\");\n\t\tgg = parseInt(adata[0], 10);\n\t\tmm = parseInt(adata[1], 10);\n\t\taaaa = parseInt(adata[2], 10);\n\t\txdata = new Date(Date.UTC(aaaa, mm - 1, gg, 12, 0, 0, 0));\n\t\tif ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth () === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {\n\t\t\tcheck = true;\n\t\t} else {\n\t\t\tcheck = false;\n\t\t}\n\t} else {\n\t\tcheck = false;\n\t}\n\treturn this.optional(element) || check;\n}, $.validator.messages.date);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/dateNL.js",
    "content": "$.validator.addMethod(\"dateNL\", function(value, element) {\n\treturn this.optional(element) || /^(0?[1-9]|[12]\\d|3[01])[\\.\\/\\-](0?[1-9]|1[012])[\\.\\/\\-]([12]\\d)?(\\d\\d)$/.test(value);\n}, $.validator.messages.date);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/extension.js",
    "content": "// Older \"accept\" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept\n$.validator.addMethod(\"extension\", function(value, element, param) {\n\tparam = typeof param === \"string\" ? param.replace(/,/g, \"|\") : \"png|jpe?g|gif\";\n\treturn this.optional(element) || value.match(new RegExp(\"\\\\.(\" + param + \")$\", \"i\"));\n}, $.validator.format(\"Please enter a value with a valid extension.\"));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/giroaccountNL.js",
    "content": "/**\n * Dutch giro account numbers (not bank numbers) have max 7 digits\n */\n$.validator.addMethod(\"giroaccountNL\", function(value, element) {\n\treturn this.optional(element) || /^[0-9]{1,7}$/.test(value);\n}, \"Please specify a valid giro account number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/iban.js",
    "content": "/**\n * IBAN is the international bank account number.\n * It has a country - specific format, that is checked here too\n */\n$.validator.addMethod(\"iban\", function(value, element) {\n\t// some quick simple tests to prevent needless work\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\n\t// remove spaces and to upper case\n\tvar iban = value.replace(/ /g, \"\").toUpperCase(),\n\t\tibancheckdigits = \"\",\n\t\tleadingZeroes = true,\n\t\tcRest = \"\",\n\t\tcOperator = \"\",\n\t\tcountrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;\n\n\t// check the country code and find the country specific format\n\tcountrycode = iban.substring(0, 2);\n\tbbancountrypatterns = {\n\t\t\"AL\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"AD\": \"\\\\d{8}[\\\\dA-Z]{12}\",\n\t\t\"AT\": \"\\\\d{16}\",\n\t\t\"AZ\": \"[\\\\dA-Z]{4}\\\\d{20}\",\n\t\t\"BE\": \"\\\\d{12}\",\n\t\t\"BH\": \"[A-Z]{4}[\\\\dA-Z]{14}\",\n\t\t\"BA\": \"\\\\d{16}\",\n\t\t\"BR\": \"\\\\d{23}[A-Z][\\\\dA-Z]\",\n\t\t\"BG\": \"[A-Z]{4}\\\\d{6}[\\\\dA-Z]{8}\",\n\t\t\"CR\": \"\\\\d{17}\",\n\t\t\"HR\": \"\\\\d{17}\",\n\t\t\"CY\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"CZ\": \"\\\\d{20}\",\n\t\t\"DK\": \"\\\\d{14}\",\n\t\t\"DO\": \"[A-Z]{4}\\\\d{20}\",\n\t\t\"EE\": \"\\\\d{16}\",\n\t\t\"FO\": \"\\\\d{14}\",\n\t\t\"FI\": \"\\\\d{14}\",\n\t\t\"FR\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"GE\": \"[\\\\dA-Z]{2}\\\\d{16}\",\n\t\t\"DE\": \"\\\\d{18}\",\n\t\t\"GI\": \"[A-Z]{4}[\\\\dA-Z]{15}\",\n\t\t\"GR\": \"\\\\d{7}[\\\\dA-Z]{16}\",\n\t\t\"GL\": \"\\\\d{14}\",\n\t\t\"GT\": \"[\\\\dA-Z]{4}[\\\\dA-Z]{20}\",\n\t\t\"HU\": \"\\\\d{24}\",\n\t\t\"IS\": \"\\\\d{22}\",\n\t\t\"IE\": \"[\\\\dA-Z]{4}\\\\d{14}\",\n\t\t\"IL\": \"\\\\d{19}\",\n\t\t\"IT\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"KZ\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"KW\": \"[A-Z]{4}[\\\\dA-Z]{22}\",\n\t\t\"LV\": \"[A-Z]{4}[\\\\dA-Z]{13}\",\n\t\t\"LB\": \"\\\\d{4}[\\\\dA-Z]{20}\",\n\t\t\"LI\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"LT\": \"\\\\d{16}\",\n\t\t\"LU\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"MK\": \"\\\\d{3}[\\\\dA-Z]{10}\\\\d{2}\",\n\t\t\"MT\": \"[A-Z]{4}\\\\d{5}[\\\\dA-Z]{18}\",\n\t\t\"MR\": \"\\\\d{23}\",\n\t\t\"MU\": \"[A-Z]{4}\\\\d{19}[A-Z]{3}\",\n\t\t\"MC\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"MD\": \"[\\\\dA-Z]{2}\\\\d{18}\",\n\t\t\"ME\": \"\\\\d{18}\",\n\t\t\"NL\": \"[A-Z]{4}\\\\d{10}\",\n\t\t\"NO\": \"\\\\d{11}\",\n\t\t\"PK\": \"[\\\\dA-Z]{4}\\\\d{16}\",\n\t\t\"PS\": \"[\\\\dA-Z]{4}\\\\d{21}\",\n\t\t\"PL\": \"\\\\d{24}\",\n\t\t\"PT\": \"\\\\d{21}\",\n\t\t\"RO\": \"[A-Z]{4}[\\\\dA-Z]{16}\",\n\t\t\"SM\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"SA\": \"\\\\d{2}[\\\\dA-Z]{18}\",\n\t\t\"RS\": \"\\\\d{18}\",\n\t\t\"SK\": \"\\\\d{20}\",\n\t\t\"SI\": \"\\\\d{15}\",\n\t\t\"ES\": \"\\\\d{20}\",\n\t\t\"SE\": \"\\\\d{20}\",\n\t\t\"CH\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"TN\": \"\\\\d{20}\",\n\t\t\"TR\": \"\\\\d{5}[\\\\dA-Z]{17}\",\n\t\t\"AE\": \"\\\\d{3}\\\\d{16}\",\n\t\t\"GB\": \"[A-Z]{4}\\\\d{14}\",\n\t\t\"VG\": \"[\\\\dA-Z]{4}\\\\d{16}\"\n\t};\n\n\tbbanpattern = bbancountrypatterns[countrycode];\n\t// As new countries will start using IBAN in the\n\t// future, we only check if the countrycode is known.\n\t// This prevents false negatives, while almost all\n\t// false positives introduced by this, will be caught\n\t// by the checksum validation below anyway.\n\t// Strict checking should return FALSE for unknown\n\t// countries.\n\tif (typeof bbanpattern !== \"undefined\") {\n\t\tibanregexp = new RegExp(\"^[A-Z]{2}\\\\d{2}\" + bbanpattern + \"$\", \"\");\n\t\tif (!(ibanregexp.test(iban))) {\n\t\t\treturn false; // invalid country specific format\n\t\t}\n\t}\n\n\t// now check the checksum, first convert to digits\n\tibancheck = iban.substring(4, iban.length) + iban.substring(0, 4);\n\tfor (i = 0; i < ibancheck.length; i++) {\n\t\tcharAt = ibancheck.charAt(i);\n\t\tif (charAt !== \"0\") {\n\t\t\tleadingZeroes = false;\n\t\t}\n\t\tif (!leadingZeroes) {\n\t\t\tibancheckdigits += \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\".indexOf(charAt);\n\t\t}\n\t}\n\n\t// calculate the result of: ibancheckdigits % 97\n\tfor (p = 0; p < ibancheckdigits.length; p++) {\n\t\tcChar = ibancheckdigits.charAt(p);\n\t\tcOperator = \"\" + cRest + \"\" + cChar;\n\t\tcRest = cOperator % 97;\n\t}\n\treturn cRest === 1;\n}, \"Please specify a valid IBAN\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/integer.js",
    "content": "$.validator.addMethod(\"integer\", function(value, element) {\n\treturn this.optional(element) || /^-?\\d+$/.test(value);\n}, \"A positive or negative non-decimal number please\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/ipv4.js",
    "content": "$.validator.addMethod(\"ipv4\", function(value, element) {\n\treturn this.optional(element) || /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/i.test(value);\n}, \"Please enter a valid IP v4 address.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/ipv6.js",
    "content": "$.validator.addMethod(\"ipv6\", function(value, element) {\n\treturn this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);\n}, \"Please enter a valid IP v6 address.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/lettersonly.js",
    "content": "$.validator.addMethod(\"lettersonly\", function(value, element) {\n\treturn this.optional(element) || /^[a-z]+$/i.test(value);\n}, \"Letters only please\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/letterswithbasicpunc.js",
    "content": "$.validator.addMethod(\"letterswithbasicpunc\", function(value, element) {\n\treturn this.optional(element) || /^[a-z\\-.,()'\"\\s]+$/i.test(value);\n}, \"Letters or punctuation only please\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/mobileNL.js",
    "content": "$.validator.addMethod(\"mobileNL\", function(value, element) {\n\treturn this.optional(element) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)6((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test(value);\n}, \"Please specify a valid mobile number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/mobileUK.js",
    "content": "/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod(\"mobileUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?|0)7(?:[1345789]\\d{2}|624)\\s?\\d{3}\\s?\\d{3})$/);\n}, \"Please specify a valid mobile number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/nieES.js",
    "content": "/*\n * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain\n */\n$.validator.addMethod( \"nieES\", function( value ) {\n\t\"use strict\";\n\n\tvalue = value.toUpperCase();\n\n\t// Basic format test\n\tif ( !value.match( \"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\" ) ) {\n\t\treturn false;\n\t}\n\n\t// Test NIE\n\t//T\n\tif ( /^[T]{1}/.test( value ) ) {\n\t\treturn ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );\n\t}\n\n\t//XYZ\n\tif ( /^[XYZ]{1}/.test( value ) ) {\n\t\treturn (\n\t\t\tvalue[ 8 ] === \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt(\n\t\t\t\tvalue.replace( \"X\", \"0\" )\n\t\t\t\t\t.replace( \"Y\", \"1\" )\n\t\t\t\t\t.replace( \"Z\", \"2\" )\n\t\t\t\t\t.substring( 0, 8 ) % 23\n\t\t\t)\n\t\t);\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid NIE number.\" );\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/nifES.js",
    "content": "/*\n * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals\n */\n$.validator.addMethod( \"nifES\", function( value ) {\n\t\"use strict\";\n\n\tvalue = value.toUpperCase();\n\n\t// Basic format test\n\tif ( !value.match(\"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\") ) {\n\t\treturn false;\n\t}\n\n\t// Test NIF\n\tif ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {\n\t\treturn ( \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );\n\t}\n\t// Test specials NIF (starts with K, L or M)\n\tif ( /^[KLM]{1}/.test( value ) ) {\n\t\treturn ( value[ 8 ] === String.fromCharCode( 64 ) );\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid NIF number.\" );\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/notEqualTo.js",
    "content": "jQuery.validator.addMethod( \"notEqualTo\", function( value, element, param ) {\n\treturn this.optional(element) || !$.validator.methods.equalTo.call( this, value, element, param );\n}, \"Please enter a different value, values must not be the same.\" );\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/nowhitespace.js",
    "content": "$.validator.addMethod(\"nowhitespace\", function(value, element) {\n\treturn this.optional(element) || /^\\S+$/i.test(value);\n}, \"No white space please\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/pattern.js",
    "content": "/**\n* Return true if the field value matches the given format RegExp\n*\n* @example $.validator.methods.pattern(\"AR1004\",element,/^AR\\d{4}$/)\n* @result true\n*\n* @example $.validator.methods.pattern(\"BR1004\",element,/^AR\\d{4}$/)\n* @result false\n*\n* @name $.validator.methods.pattern\n* @type Boolean\n* @cat Plugins/Validate/Methods\n*/\n$.validator.addMethod(\"pattern\", function(value, element, param) {\n\tif (this.optional(element)) {\n\t\treturn true;\n\t}\n\tif (typeof param === \"string\") {\n\t\tparam = new RegExp(\"^(?:\" + param + \")$\");\n\t}\n\treturn param.test(value);\n}, \"Invalid format.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/phoneNL.js",
    "content": "/**\n * Dutch phone numbers have 10 digits (or 11 and start with +31).\n */\n$.validator.addMethod(\"phoneNL\", function(value, element) {\n\treturn this.optional(element) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)[1-9]((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test(value);\n}, \"Please specify a valid phone number.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/phoneUK.js",
    "content": "/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod(\"phoneUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?)|(?:\\(?0))(?:\\d{2}\\)?\\s?\\d{4}\\s?\\d{4}|\\d{3}\\)?\\s?\\d{3}\\s?\\d{3,4}|\\d{4}\\)?\\s?(?:\\d{5}|\\d{3}\\s?\\d{3})|\\d{5}\\)?\\s?\\d{4,5})$/);\n}, \"Please specify a valid phone number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/phoneUS.js",
    "content": "/**\n * matches US phone number format\n *\n * where the area code may not start with 1 and the prefix may not start with 1\n * allows '-' or ' ' as a separator and allows parens around area code\n * some people may want to put a '1' in front of their number\n *\n * 1(212)-999-2345 or\n * 212 999 2344 or\n * 212-999-0983\n *\n * but not\n * 111-123-5434\n * and not\n * 212 123 4567\n */\n$.validator.addMethod(\"phoneUS\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\s+/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(\\+?1-?)?(\\([2-9]([02-9]\\d|1[02-9])\\)|[2-9]([02-9]\\d|1[02-9]))-?[2-9]([02-9]\\d|1[02-9])-?\\d{4}$/);\n}, \"Please specify a valid phone number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/phonesUK.js",
    "content": "/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers\n$.validator.addMethod(\"phonesUK\", function(phone_number, element) {\n\tphone_number = phone_number.replace(/\\(|\\)|\\s+|-/g, \"\");\n\treturn this.optional(element) || phone_number.length > 9 &&\n\t\tphone_number.match(/^(?:(?:(?:00\\s?|\\+)44\\s?|0)(?:1\\d{8,9}|[23]\\d{9}|7(?:[1345789]\\d{8}|624\\d{6})))$/);\n}, \"Please specify a valid uk phone number\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/postalCodeCA.js",
    "content": "/**\n * Matches a valid Canadian Postal Code\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H 0H0\", element )\n * @result true\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H0H0\", element )\n * @result false\n *\n * @name jQuery.validator.methods.postalCodeCA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod( \"postalCodeCA\", function( value, element ) {\n\treturn this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\\d[A-Z] \\d[A-Z]\\d$/.test( value );\n}, \"Please specify a valid postal code\" );\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/postalcodeBR.js",
    "content": "/*\n* Valida CEPs do brasileiros:\n*\n* Formatos aceitos:\n* 99999-999\n* 99.999-999\n* 99999999\n*/\n$.validator.addMethod(\"postalcodeBR\", function(cep_value, element) {\n\treturn this.optional(element) || /^\\d{2}.\\d{3}-\\d{3}?$|^\\d{5}-?\\d{3}?$/.test( cep_value );\n}, \"Informe um CEP válido.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/postalcodeIT.js",
    "content": "/* Matches Italian postcode (CAP) */\n$.validator.addMethod(\"postalcodeIT\", function(value, element) {\n\treturn this.optional(element) || /^\\d{5}$/.test(value);\n}, \"Please specify a valid postal code\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/postalcodeNL.js",
    "content": "$.validator.addMethod(\"postalcodeNL\", function(value, element) {\n\treturn this.optional(element) || /^[1-9][0-9]{3}\\s?[a-zA-Z]{2}$/.test(value);\n}, \"Please specify a valid postal code\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/postcodeUK.js",
    "content": "// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)\n$.validator.addMethod(\"postcodeUK\", function(value, element) {\n\treturn this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\\s?(0AA))$/i.test(value);\n}, \"Please specify a valid UK postcode\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/require_from_group.js",
    "content": "/*\n * Lets you say \"at least X inputs that match selector Y must be filled.\"\n *\n * The end result is that neither of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\n *\t...will validate unless at least one of them is filled.\n *\n * partnumber:\t{require_from_group: [1,\".productinfo\"]},\n * description: {require_from_group: [1,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n */\n$.validator.addMethod(\"require_from_group\", function(value, element, options) {\n\tvar $fields = $(options[1], element.form),\n\t\t$fieldsFirst = $fields.eq(0),\n\t\tvalidator = $fieldsFirst.data(\"valid_req_grp\") ? $fieldsFirst.data(\"valid_req_grp\") : $.extend({}, this),\n\t\tisValid = $fields.filter(function() {\n\t\t\treturn validator.elementValue(this);\n\t\t}).length >= options[0];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data(\"valid_req_grp\", validator);\n\n\t// If element isn't being validated, run each require_from_group field's validation rules\n\tif (!$(element).data(\"being_validated\")) {\n\t\t$fields.data(\"being_validated\", true);\n\t\t$fields.each(function() {\n\t\t\tvalidator.element(this);\n\t\t});\n\t\t$fields.data(\"being_validated\", false);\n\t}\n\treturn isValid;\n}, $.validator.format(\"Please fill at least {0} of these fields.\"));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/skip_or_fill_minimum.js",
    "content": "/*\n * Lets you say \"either at least X inputs that match selector Y must be filled,\n * OR they must all be skipped (left blank).\"\n *\n * The end result, is that none of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\t<input class=\"productinfo\" name=\"color\">\n *\n *\t...will validate unless either at least two of them are filled,\n *\tOR none of them are.\n *\n * partnumber:\t{skip_or_fill_minimum: [2,\".productinfo\"]},\n * description: {skip_or_fill_minimum: [2,\".productinfo\"]},\n * color:\t\t{skip_or_fill_minimum: [2,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n *\n */\n$.validator.addMethod(\"skip_or_fill_minimum\", function(value, element, options) {\n\tvar $fields = $(options[1], element.form),\n\t\t$fieldsFirst = $fields.eq(0),\n\t\tvalidator = $fieldsFirst.data(\"valid_skip\") ? $fieldsFirst.data(\"valid_skip\") : $.extend({}, this),\n\t\tnumberFilled = $fields.filter(function() {\n\t\t\treturn validator.elementValue(this);\n\t\t}).length,\n\t\tisValid = numberFilled === 0 || numberFilled >= options[0];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data(\"valid_skip\", validator);\n\n\t// If element isn't being validated, run each skip_or_fill_minimum field's validation rules\n\tif (!$(element).data(\"being_validated\")) {\n\t\t$fields.data(\"being_validated\", true);\n\t\t$fields.each(function() {\n\t\t\tvalidator.element(this);\n\t\t});\n\t\t$fields.data(\"being_validated\", false);\n\t}\n\treturn isValid;\n}, $.validator.format(\"Please either skip these fields or fill at least {0} of them.\"));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/statesUS.js",
    "content": "/* Validates US States and/or Territories by @jdforsythe\n * Can be case insensitive or require capitalization - default is case insensitive\n * Can include US Territories or not - default does not\n * Can include US Military postal abbreviations (AA, AE, AP) - default does not\n *\n * Note: \"States\" always includes DC (District of Colombia)\n *\n * Usage examples:\n *\n *  This is the default - case insensitive, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false,\n *     includeTerritories: false,\n *     includeMilitary: false\n *  }\n *\n *  Only allow capital letters, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false\n *  }\n *\n *  Case insensitive, include territories but not military zones\n *  stateInput: {\n *     includeTerritories: true\n *  }\n *\n *  Only allow capital letters, include territories and military zones\n *  stateInput: {\n *     caseSensitive: true,\n *     includeTerritories: true,\n *     includeMilitary: true\n *  }\n *\n *\n *\n */\n\n$.validator.addMethod(\"stateUS\", function(value, element, options) {\n\tvar isDefault = typeof options === \"undefined\",\n\t\tcaseSensitive = ( isDefault || typeof options.caseSensitive === \"undefined\" ) ? false : options.caseSensitive,\n\t\tincludeTerritories = ( isDefault || typeof options.includeTerritories === \"undefined\" ) ? false : options.includeTerritories,\n\t\tincludeMilitary = ( isDefault || typeof options.includeMilitary === \"undefined\" ) ? false : options.includeMilitary,\n\t\tregex;\n\n\tif (!includeTerritories && !includeMilitary) {\n\t\tregex = \"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t} else if (includeTerritories && includeMilitary) {\n\t\tregex = \"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else if (includeTerritories) {\n\t\tregex = \"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else {\n\t\tregex = \"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t}\n\n\tregex = caseSensitive ? new RegExp(regex) : new RegExp(regex, \"i\");\n\treturn this.optional(element) || regex.test(value);\n},\n\"Please specify a valid state\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/strippedminlength.js",
    "content": "// TODO check if value starts with <, otherwise don't try stripping anything\n$.validator.addMethod(\"strippedminlength\", function(value, element, param) {\n\treturn $(value).text().length >= param;\n}, $.validator.format(\"Please enter at least {0} characters\"));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/time.js",
    "content": "$.validator.addMethod(\"time\", function(value, element) {\n\treturn this.optional(element) || /^([01]\\d|2[0-3]|[0-9])(:[0-5]\\d){1,2}$/.test(value);\n}, \"Please enter a valid time, between 00:00 and 23:59\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/time12h.js",
    "content": "$.validator.addMethod(\"time12h\", function(value, element) {\n\treturn this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\\d){1,2}(\\ ?[AP]M))$/i.test(value);\n}, \"Please enter a valid time in 12-hour am/pm format\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/url2.js",
    "content": "// same as url, but TLD is optional\n$.validator.addMethod(\"url2\", function(value, element) {\n\treturn this.optional(element) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);\n}, $.validator.messages.url);\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/vinUS.js",
    "content": "/**\n * Return true, if the value is a valid vehicle identification number (VIN).\n *\n * Works with all kind of text inputs.\n *\n * @example <input type=\"text\" size=\"20\" name=\"VehicleID\" class=\"{required:true,vinUS:true}\" />\n * @desc Declares a required input element whose value must be a valid vehicle identification number.\n *\n * @name $.validator.methods.vinUS\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod(\"vinUS\", function(v) {\n\tif (v.length !== 17) {\n\t\treturn false;\n\t}\n\n\tvar LL = [ \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"J\", \"K\", \"L\", \"M\", \"N\", \"P\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\" ],\n\t\tVL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],\n\t\tFL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],\n\t\trs = 0,\n\t\ti, n, d, f, cd, cdv;\n\n\tfor (i = 0; i < 17; i++) {\n\t\tf = FL[i];\n\t\td = v.slice(i, i + 1);\n\t\tif (i === 8) {\n\t\t\tcdv = d;\n\t\t}\n\t\tif (!isNaN(d)) {\n\t\t\td *= f;\n\t\t} else {\n\t\t\tfor (n = 0; n < LL.length; n++) {\n\t\t\t\tif (d.toUpperCase() === LL[n]) {\n\t\t\t\t\td = VL[n];\n\t\t\t\t\td *= f;\n\t\t\t\t\tif (isNaN(cdv) && n === 8) {\n\t\t\t\t\t\tcdv = LL[n];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\trs += d;\n\t}\n\tcd = rs % 11;\n\tif (cd === 10) {\n\t\tcd = \"X\";\n\t}\n\tif (cd === cdv) {\n\t\treturn true;\n\t}\n\treturn false;\n}, \"The specified vehicle identification number (VIN) is invalid.\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/zipcodeUS.js",
    "content": "$.validator.addMethod(\"zipcodeUS\", function(value, element) {\n\treturn this.optional(element) || /^\\d{5}(-\\d{4})?$/.test(value);\n}, \"The specified US ZIP Code is invalid\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/additional/ziprange.js",
    "content": "$.validator.addMethod(\"ziprange\", function(value, element) {\n\treturn this.optional(element) || /^90[2-5]\\d\\{2\\}-\\d{4}$/.test(value);\n}, \"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx\");\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/ajax.js",
    "content": "// ajax mode: abort\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()\n\nvar pendingRequests = {},\n\tajax;\n// Use a prefilter if available (1.5+)\nif ( $.ajaxPrefilter ) {\n\t$.ajaxPrefilter(function( settings, _, xhr ) {\n\t\tvar port = settings.port;\n\t\tif ( settings.mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[port] ) {\n\t\t\t\tpendingRequests[port].abort();\n\t\t\t}\n\t\t\tpendingRequests[port] = xhr;\n\t\t}\n\t});\n} else {\n\t// Proxy ajax\n\tajax = $.ajax;\n\t$.ajax = function( settings ) {\n\t\tvar mode = ( \"mode\" in settings ? settings : $.ajaxSettings ).mode,\n\t\t\tport = ( \"port\" in settings ? settings : $.ajaxSettings ).port;\n\t\tif ( mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[port] ) {\n\t\t\t\tpendingRequests[port].abort();\n\t\t\t}\n\t\t\tpendingRequests[port] = ajax.apply(this, arguments);\n\t\t\treturn pendingRequests[port];\n\t\t}\n\t\treturn ajax.apply(this, arguments);\n\t};\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/core.js",
    "content": "$.extend($.fn, {\n\t// http://jqueryvalidation.org/validate/\n\tvalidate: function( options ) {\n\n\t\t// if nothing is selected, return nothing; can't chain anyway\n\t\tif ( !this.length ) {\n\t\t\tif ( options && options.debug && window.console ) {\n\t\t\t\tconsole.warn( \"Nothing selected, can't validate, returning nothing.\" );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// check if a validator for this form was already created\n\t\tvar validator = $.data( this[ 0 ], \"validator\" );\n\t\tif ( validator ) {\n\t\t\treturn validator;\n\t\t}\n\n\t\t// Add novalidate tag if HTML5.\n\t\tthis.attr( \"novalidate\", \"novalidate\" );\n\n\t\tvalidator = new $.validator( options, this[ 0 ] );\n\t\t$.data( this[ 0 ], \"validator\", validator );\n\n\t\tif ( validator.settings.onsubmit ) {\n\n\t\t\tthis.on( \"click.validate\", \":submit\", function( event ) {\n\t\t\t\tif ( validator.settings.submitHandler ) {\n\t\t\t\t\tvalidator.submitButton = event.target;\n\t\t\t\t}\n\n\t\t\t\t// allow suppressing validation by adding a cancel class to the submit button\n\t\t\t\tif ( $( this ).hasClass( \"cancel\" ) ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\n\t\t\t\t// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button\n\t\t\t\tif ( $( this ).attr( \"formnovalidate\" ) !== undefined ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// validate the form on submit\n\t\t\tthis.on( \"submit.validate\", function( event ) {\n\t\t\t\tif ( validator.settings.debug ) {\n\t\t\t\t\t// prevent form submit to be able to see console output\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t\tfunction handle() {\n\t\t\t\t\tvar hidden, result;\n\t\t\t\t\tif ( validator.settings.submitHandler ) {\n\t\t\t\t\t\tif ( validator.submitButton ) {\n\t\t\t\t\t\t\t// insert a hidden input as a replacement for the missing submit button\n\t\t\t\t\t\t\thidden = $( \"<input type='hidden'/>\" )\n\t\t\t\t\t\t\t\t.attr( \"name\", validator.submitButton.name )\n\t\t\t\t\t\t\t\t.val( $( validator.submitButton ).val() )\n\t\t\t\t\t\t\t\t.appendTo( validator.currentForm );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult = validator.settings.submitHandler.call( validator, validator.currentForm, event );\n\t\t\t\t\t\tif ( validator.submitButton ) {\n\t\t\t\t\t\t\t// and clean up afterwards; thanks to no-block-scope, hidden can be referenced\n\t\t\t\t\t\t\thidden.remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( result !== undefined ) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// prevent submit for invalid forms or custom submit handlers\n\t\t\t\tif ( validator.cancelSubmit ) {\n\t\t\t\t\tvalidator.cancelSubmit = false;\n\t\t\t\t\treturn handle();\n\t\t\t\t}\n\t\t\t\tif ( validator.form() ) {\n\t\t\t\t\tif ( validator.pendingRequest ) {\n\t\t\t\t\t\tvalidator.formSubmitted = true;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn handle();\n\t\t\t\t} else {\n\t\t\t\t\tvalidator.focusInvalid();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn validator;\n\t},\n\t// http://jqueryvalidation.org/valid/\n\tvalid: function() {\n\t\tvar valid, validator, errorList;\n\n\t\tif ( $( this[ 0 ] ).is( \"form\" ) ) {\n\t\t\tvalid = this.validate().form();\n\t\t} else {\n\t\t\terrorList = [];\n\t\t\tvalid = true;\n\t\t\tvalidator = $( this[ 0 ].form ).validate();\n\t\t\tthis.each( function() {\n\t\t\t\tvalid = validator.element( this ) && valid;\n\t\t\t\terrorList = errorList.concat( validator.errorList );\n\t\t\t});\n\t\t\tvalidator.errorList = errorList;\n\t\t}\n\t\treturn valid;\n\t},\n\n\t// http://jqueryvalidation.org/rules/\n\trules: function( command, argument ) {\n\t\tvar element = this[ 0 ],\n\t\t\tsettings, staticRules, existingRules, data, param, filtered;\n\n\t\tif ( command ) {\n\t\t\tsettings = $.data( element.form, \"validator\" ).settings;\n\t\t\tstaticRules = settings.rules;\n\t\t\texistingRules = $.validator.staticRules( element );\n\t\t\tswitch ( command ) {\n\t\t\tcase \"add\":\n\t\t\t\t$.extend( existingRules, $.validator.normalizeRule( argument ) );\n\t\t\t\t// remove messages from rules, but allow them to be set separately\n\t\t\t\tdelete existingRules.messages;\n\t\t\t\tstaticRules[ element.name ] = existingRules;\n\t\t\t\tif ( argument.messages ) {\n\t\t\t\t\tsettings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"remove\":\n\t\t\t\tif ( !argument ) {\n\t\t\t\t\tdelete staticRules[ element.name ];\n\t\t\t\t\treturn existingRules;\n\t\t\t\t}\n\t\t\t\tfiltered = {};\n\t\t\t\t$.each( argument.split( /\\s/ ), function( index, method ) {\n\t\t\t\t\tfiltered[ method ] = existingRules[ method ];\n\t\t\t\t\tdelete existingRules[ method ];\n\t\t\t\t\tif ( method === \"required\" ) {\n\t\t\t\t\t\t$( element ).removeAttr( \"aria-required\" );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn filtered;\n\t\t\t}\n\t\t}\n\n\t\tdata = $.validator.normalizeRules(\n\t\t$.extend(\n\t\t\t{},\n\t\t\t$.validator.classRules( element ),\n\t\t\t$.validator.attributeRules( element ),\n\t\t\t$.validator.dataRules( element ),\n\t\t\t$.validator.staticRules( element )\n\t\t), element );\n\n\t\t// make sure required is at front\n\t\tif ( data.required ) {\n\t\t\tparam = data.required;\n\t\t\tdelete data.required;\n\t\t\tdata = $.extend( { required: param }, data );\n\t\t\t$( element ).attr( \"aria-required\", \"true\" );\n\t\t}\n\n\t\t// make sure remote is at back\n\t\tif ( data.remote ) {\n\t\t\tparam = data.remote;\n\t\t\tdelete data.remote;\n\t\t\tdata = $.extend( data, { remote: param });\n\t\t}\n\n\t\treturn data;\n\t}\n});\n\n// Custom selectors\n$.extend( $.expr[ \":\" ], {\n\t// http://jqueryvalidation.org/blank-selector/\n\tblank: function( a ) {\n\t\treturn !$.trim( \"\" + $( a ).val() );\n\t},\n\t// http://jqueryvalidation.org/filled-selector/\n\tfilled: function( a ) {\n\t\treturn !!$.trim( \"\" + $( a ).val() );\n\t},\n\t// http://jqueryvalidation.org/unchecked-selector/\n\tunchecked: function( a ) {\n\t\treturn !$( a ).prop( \"checked\" );\n\t}\n});\n\n// constructor for validator\n$.validator = function( options, form ) {\n\tthis.settings = $.extend( true, {}, $.validator.defaults, options );\n\tthis.currentForm = form;\n\tthis.init();\n};\n\n// http://jqueryvalidation.org/jQuery.validator.format/\n$.validator.format = function( source, params ) {\n\tif ( arguments.length === 1 ) {\n\t\treturn function() {\n\t\t\tvar args = $.makeArray( arguments );\n\t\t\targs.unshift( source );\n\t\t\treturn $.validator.format.apply( this, args );\n\t\t};\n\t}\n\tif ( arguments.length > 2 && params.constructor !== Array  ) {\n\t\tparams = $.makeArray( arguments ).slice( 1 );\n\t}\n\tif ( params.constructor !== Array ) {\n\t\tparams = [ params ];\n\t}\n\t$.each( params, function( i, n ) {\n\t\tsource = source.replace( new RegExp( \"\\\\{\" + i + \"\\\\}\", \"g\" ), function() {\n\t\t\treturn n;\n\t\t});\n\t});\n\treturn source;\n};\n\n$.extend( $.validator, {\n\n\tdefaults: {\n\t\tmessages: {},\n\t\tgroups: {},\n\t\trules: {},\n\t\terrorClass: \"error\",\n\t\tvalidClass: \"valid\",\n\t\terrorElement: \"label\",\n\t\tfocusCleanup: false,\n\t\tfocusInvalid: true,\n\t\terrorContainer: $( [] ),\n\t\terrorLabelContainer: $( [] ),\n\t\tonsubmit: true,\n\t\tignore: \":hidden\",\n\t\tignoreTitle: false,\n\t\tonfocusin: function( element ) {\n\t\t\tthis.lastActive = element;\n\n\t\t\t// Hide error label and remove error class on focus if enabled\n\t\t\tif ( this.settings.focusCleanup ) {\n\t\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.hideThese( this.errorsFor( element ) );\n\t\t\t}\n\t\t},\n\t\tonfocusout: function( element ) {\n\t\t\tif ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonkeyup: function( element, event ) {\n\t\t\t// Avoid revalidate the field when pressing one of the following keys\n\t\t\t// Shift       => 16\n\t\t\t// Ctrl        => 17\n\t\t\t// Alt         => 18\n\t\t\t// Caps lock   => 20\n\t\t\t// End         => 35\n\t\t\t// Home        => 36\n\t\t\t// Left arrow  => 37\n\t\t\t// Up arrow    => 38\n\t\t\t// Right arrow => 39\n\t\t\t// Down arrow  => 40\n\t\t\t// Insert      => 45\n\t\t\t// Num lock    => 144\n\t\t\t// AltGr key   => 225\n\t\t\tvar excludedKeys = [\n\t\t\t\t16, 17, 18, 20, 35, 36, 37,\n\t\t\t\t38, 39, 40, 45, 144, 225\n\t\t\t];\n\n\t\t\tif ( event.which === 9 && this.elementValue( element ) === \"\" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t} else if ( element.name in this.submitted || element === this.lastElement ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonclick: function( element ) {\n\t\t\t// click on selects, radiobuttons and checkboxes\n\t\t\tif ( element.name in this.submitted ) {\n\t\t\t\tthis.element( element );\n\n\t\t\t// or option elements, check parent select in that case\n\t\t\t} else if ( element.parentNode.name in this.submitted ) {\n\t\t\t\tthis.element( element.parentNode );\n\t\t\t}\n\t\t},\n\t\thighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).addClass( errorClass ).removeClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).addClass( errorClass ).removeClass( validClass );\n\t\t\t}\n\t\t},\n\t\tunhighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).removeClass( errorClass ).addClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).removeClass( errorClass ).addClass( validClass );\n\t\t\t}\n\t\t}\n\t},\n\n\t// http://jqueryvalidation.org/jQuery.validator.setDefaults/\n\tsetDefaults: function( settings ) {\n\t\t$.extend( $.validator.defaults, settings );\n\t},\n\n\tmessages: {\n\t\trequired: \"This field is required.\",\n\t\tremote: \"Please fix this field.\",\n\t\temail: \"Please enter a valid email address.\",\n\t\turl: \"Please enter a valid URL.\",\n\t\tdate: \"Please enter a valid date.\",\n\t\tdateISO: \"Please enter a valid date ( ISO ).\",\n\t\tnumber: \"Please enter a valid number.\",\n\t\tdigits: \"Please enter only digits.\",\n\t\tcreditcard: \"Please enter a valid credit card number.\",\n\t\tequalTo: \"Please enter the same value again.\",\n\t\tmaxlength: $.validator.format( \"Please enter no more than {0} characters.\" ),\n\t\tminlength: $.validator.format( \"Please enter at least {0} characters.\" ),\n\t\trangelength: $.validator.format( \"Please enter a value between {0} and {1} characters long.\" ),\n\t\trange: $.validator.format( \"Please enter a value between {0} and {1}.\" ),\n\t\tmax: $.validator.format( \"Please enter a value less than or equal to {0}.\" ),\n\t\tmin: $.validator.format( \"Please enter a value greater than or equal to {0}.\" )\n\t},\n\n\tautoCreateRanges: false,\n\n\tprototype: {\n\n\t\tinit: function() {\n\t\t\tthis.labelContainer = $( this.settings.errorLabelContainer );\n\t\t\tthis.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );\n\t\t\tthis.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );\n\t\t\tthis.submitted = {};\n\t\t\tthis.valueCache = {};\n\t\t\tthis.pendingRequest = 0;\n\t\t\tthis.pending = {};\n\t\t\tthis.invalid = {};\n\t\t\tthis.reset();\n\n\t\t\tvar groups = ( this.groups = {} ),\n\t\t\t\trules;\n\t\t\t$.each( this.settings.groups, function( key, value ) {\n\t\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\t\tvalue = value.split( /\\s/ );\n\t\t\t\t}\n\t\t\t\t$.each( value, function( index, name ) {\n\t\t\t\t\tgroups[ name ] = key;\n\t\t\t\t});\n\t\t\t});\n\t\t\trules = this.settings.rules;\n\t\t\t$.each( rules, function( key, value ) {\n\t\t\t\trules[ key ] = $.validator.normalizeRule( value );\n\t\t\t});\n\n\t\t\tfunction delegate( event ) {\n\t\t\t\tvar validator = $.data( this.form, \"validator\" ),\n\t\t\t\t\teventType = \"on\" + event.type.replace( /^validate/, \"\" ),\n\t\t\t\t\tsettings = validator.settings;\n\t\t\t\tif ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {\n\t\t\t\t\tsettings[ eventType ].call( validator, this, event );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.on( \"focusin.validate focusout.validate keyup.validate\",\n\t\t\t\t\t\":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], \" +\n\t\t\t\t\t\"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], \" +\n\t\t\t\t\t\"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], \" +\n\t\t\t\t\t\"[type='radio'], [type='checkbox']\", delegate)\n\t\t\t\t// Support: Chrome, oldIE\n\t\t\t\t// \"select\" is provided as event.target when clicking a option\n\t\t\t\t.on(\"click.validate\", \"select, option, [type='radio'], [type='checkbox']\", delegate);\n\n\t\t\tif ( this.settings.invalidHandler ) {\n\t\t\t\t$( this.currentForm ).on( \"invalid-form.validate\", this.settings.invalidHandler );\n\t\t\t}\n\n\t\t\t// Add aria-required to any Static/Data/Class required fields before first validation\n\t\t\t// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html\n\t\t\t$( this.currentForm ).find( \"[required], [data-rule-required], .required\" ).attr( \"aria-required\", \"true\" );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.form/\n\t\tform: function() {\n\t\t\tthis.checkForm();\n\t\t\t$.extend( this.submitted, this.errorMap );\n\t\t\tthis.invalid = $.extend({}, this.errorMap );\n\t\t\tif ( !this.valid() ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\n\t\t\t}\n\t\t\tthis.showErrors();\n\t\t\treturn this.valid();\n\t\t},\n\n\t\tcheckForm: function() {\n\t\t\tthis.prepareForm();\n\t\t\tfor ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {\n\t\t\t\tthis.check( elements[ i ] );\n\t\t\t}\n\t\t\treturn this.valid();\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.element/\n\t\telement: function( element ) {\n\t\t\tvar cleanElement = this.clean( element ),\n\t\t\t\tcheckElement = this.validationTargetFor( cleanElement ),\n\t\t\t\tresult = true;\n\n\t\t\tthis.lastElement = checkElement;\n\n\t\t\tif ( checkElement === undefined ) {\n\t\t\t\tdelete this.invalid[ cleanElement.name ];\n\t\t\t} else {\n\t\t\t\tthis.prepareElement( checkElement );\n\t\t\t\tthis.currentElements = $( checkElement );\n\n\t\t\t\tresult = this.check( checkElement ) !== false;\n\t\t\t\tif ( result ) {\n\t\t\t\t\tdelete this.invalid[ checkElement.name ];\n\t\t\t\t} else {\n\t\t\t\t\tthis.invalid[ checkElement.name ] = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add aria-invalid status for screen readers\n\t\t\t$( element ).attr( \"aria-invalid\", !result );\n\n\t\t\tif ( !this.numberOfInvalids() ) {\n\t\t\t\t// Hide error containers on last error\n\t\t\t\tthis.toHide = this.toHide.add( this.containers );\n\t\t\t}\n\t\t\tthis.showErrors();\n\t\t\treturn result;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.showErrors/\n\t\tshowErrors: function( errors ) {\n\t\t\tif ( errors ) {\n\t\t\t\t// add items to error list and map\n\t\t\t\t$.extend( this.errorMap, errors );\n\t\t\t\tthis.errorList = [];\n\t\t\t\tfor ( var name in errors ) {\n\t\t\t\t\tthis.errorList.push({\n\t\t\t\t\t\tmessage: errors[ name ],\n\t\t\t\t\t\telement: this.findByName( name )[ 0 ]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// remove items from success list\n\t\t\t\tthis.successList = $.grep( this.successList, function( element ) {\n\t\t\t\t\treturn !( element.name in errors );\n\t\t\t\t});\n\t\t\t}\n\t\t\tif ( this.settings.showErrors ) {\n\t\t\t\tthis.settings.showErrors.call( this, this.errorMap, this.errorList );\n\t\t\t} else {\n\t\t\t\tthis.defaultShowErrors();\n\t\t\t}\n\t\t},\n\n\t\t// http://jqueryvalidation.org/Validator.resetForm/\n\t\tresetForm: function() {\n\t\t\tif ( $.fn.resetForm ) {\n\t\t\t\t$( this.currentForm ).resetForm();\n\t\t\t}\n\t\t\tthis.submitted = {};\n\t\t\tthis.lastElement = null;\n\t\t\tthis.prepareForm();\n\t\t\tthis.hideErrors();\n\t\t\tvar i, elements = this.elements()\n\t\t\t\t.removeData( \"previousValue\" )\n\t\t\t\t.removeAttr( \"aria-invalid\" );\n\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0; elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ],\n\t\t\t\t\t\tthis.settings.errorClass, \"\" );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\telements.removeClass( this.settings.errorClass );\n\t\t\t}\n\t\t},\n\n\t\tnumberOfInvalids: function() {\n\t\t\treturn this.objectLength( this.invalid );\n\t\t},\n\n\t\tobjectLength: function( obj ) {\n\t\t\t/* jshint unused: false */\n\t\t\tvar count = 0,\n\t\t\t\ti;\n\t\t\tfor ( i in obj ) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\thideErrors: function() {\n\t\t\tthis.hideThese( this.toHide );\n\t\t},\n\n\t\thideThese: function( errors ) {\n\t\t\terrors.not( this.containers ).text( \"\" );\n\t\t\tthis.addWrapper( errors ).hide();\n\t\t},\n\n\t\tvalid: function() {\n\t\t\treturn this.size() === 0;\n\t\t},\n\n\t\tsize: function() {\n\t\t\treturn this.errorList.length;\n\t\t},\n\n\t\tfocusInvalid: function() {\n\t\t\tif ( this.settings.focusInvalid ) {\n\t\t\t\ttry {\n\t\t\t\t\t$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])\n\t\t\t\t\t.filter( \":visible\" )\n\t\t\t\t\t.focus()\n\t\t\t\t\t// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\n\t\t\t\t\t.trigger( \"focusin\" );\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t// ignore IE throwing errors when focusing hidden elements\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tfindLastActive: function() {\n\t\t\tvar lastActive = this.lastActive;\n\t\t\treturn lastActive && $.grep( this.errorList, function( n ) {\n\t\t\t\treturn n.element.name === lastActive.name;\n\t\t\t}).length === 1 && lastActive;\n\t\t},\n\n\t\telements: function() {\n\t\t\tvar validator = this,\n\t\t\t\trulesCache = {};\n\n\t\t\t// select all valid inputs inside the form (no submit or reset buttons)\n\t\t\treturn $( this.currentForm )\n\t\t\t.find( \"input, select, textarea\" )\n\t\t\t.not( \":submit, :reset, :image, :disabled\" )\n\t\t\t.not( this.settings.ignore )\n\t\t\t.filter( function() {\n\t\t\t\tif ( !this.name && validator.settings.debug && window.console ) {\n\t\t\t\t\tconsole.error( \"%o has no name assigned\", this );\n\t\t\t\t}\n\n\t\t\t\t// select only the first element for each name, and only those with rules specified\n\t\t\t\tif ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\trulesCache[ this.name ] = true;\n\t\t\t\treturn true;\n\t\t\t});\n\t\t},\n\n\t\tclean: function( selector ) {\n\t\t\treturn $( selector )[ 0 ];\n\t\t},\n\n\t\terrors: function() {\n\t\t\tvar errorClass = this.settings.errorClass.split( \" \" ).join( \".\" );\n\t\t\treturn $( this.settings.errorElement + \".\" + errorClass, this.errorContext );\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.successList = [];\n\t\t\tthis.errorList = [];\n\t\t\tthis.errorMap = {};\n\t\t\tthis.toShow = $( [] );\n\t\t\tthis.toHide = $( [] );\n\t\t\tthis.currentElements = $( [] );\n\t\t},\n\n\t\tprepareForm: function() {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errors().add( this.containers );\n\t\t},\n\n\t\tprepareElement: function( element ) {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errorsFor( element );\n\t\t},\n\n\t\telementValue: function( element ) {\n\t\t\tvar val,\n\t\t\t\t$element = $( element ),\n\t\t\t\ttype = element.type;\n\n\t\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\t\treturn this.findByName( element.name ).filter(\":checked\").val();\n\t\t\t} else if ( type === \"number\" && typeof element.validity !== \"undefined\" ) {\n\t\t\t\treturn element.validity.badInput ? false : $element.val();\n\t\t\t}\n\n\t\t\tval = $element.val();\n\t\t\tif ( typeof val === \"string\" ) {\n\t\t\t\treturn val.replace(/\\r/g, \"\" );\n\t\t\t}\n\t\t\treturn val;\n\t\t},\n\n\t\tcheck: function( element ) {\n\t\t\telement = this.validationTargetFor( this.clean( element ) );\n\n\t\t\tvar rules = $( element ).rules(),\n\t\t\t\trulesCount = $.map( rules, function( n, i ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}).length,\n\t\t\t\tdependencyMismatch = false,\n\t\t\t\tval = this.elementValue( element ),\n\t\t\t\tresult, method, rule;\n\n\t\t\tfor ( method in rules ) {\n\t\t\t\trule = { method: method, parameters: rules[ method ] };\n\t\t\t\ttry {\n\n\t\t\t\t\tresult = $.validator.methods[ method ].call( this, val, element, rule.parameters );\n\n\t\t\t\t\t// if a method indicates that the field is optional and therefore valid,\n\t\t\t\t\t// don't mark it as valid when there are no other rules\n\t\t\t\t\tif ( result === \"dependency-mismatch\" && rulesCount === 1 ) {\n\t\t\t\t\t\tdependencyMismatch = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tdependencyMismatch = false;\n\n\t\t\t\t\tif ( result === \"pending\" ) {\n\t\t\t\t\t\tthis.toHide = this.toHide.not( this.errorsFor( element ) );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !result ) {\n\t\t\t\t\t\tthis.formatAndAdd( element, rule );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tif ( this.settings.debug && window.console ) {\n\t\t\t\t\t\tconsole.log( \"Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\", e );\n\t\t\t\t\t}\n\t\t\t\t\tif ( e instanceof TypeError ) {\n\t\t\t\t\t\te.message += \".  Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\";\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( dependencyMismatch ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( this.objectLength( rules ) ) {\n\t\t\t\tthis.successList.push( element );\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t// return the custom message for the given element and validation method\n\t\t// specified in the element's HTML5 data attribute\n\t\t// return the generic message if present and no method specific message is present\n\t\tcustomDataMessage: function( element, method ) {\n\t\t\treturn $( element ).data( \"msg\" + method.charAt( 0 ).toUpperCase() +\n\t\t\t\tmethod.substring( 1 ).toLowerCase() ) || $( element ).data( \"msg\" );\n\t\t},\n\n\t\t// return the custom message for the given element name and validation method\n\t\tcustomMessage: function( name, method ) {\n\t\t\tvar m = this.settings.messages[ name ];\n\t\t\treturn m && ( m.constructor === String ? m : m[ method ]);\n\t\t},\n\n\t\t// return the first defined argument, allowing empty strings\n\t\tfindDefined: function() {\n\t\t\tfor ( var i = 0; i < arguments.length; i++) {\n\t\t\t\tif ( arguments[ i ] !== undefined ) {\n\t\t\t\t\treturn arguments[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\n\t\tdefaultMessage: function( element, method ) {\n\t\t\treturn this.findDefined(\n\t\t\t\tthis.customMessage( element.name, method ),\n\t\t\t\tthis.customDataMessage( element, method ),\n\t\t\t\t// title is never undefined, so handle empty string as undefined\n\t\t\t\t!this.settings.ignoreTitle && element.title || undefined,\n\t\t\t\t$.validator.messages[ method ],\n\t\t\t\t\"<strong>Warning: No message defined for \" + element.name + \"</strong>\"\n\t\t\t);\n\t\t},\n\n\t\tformatAndAdd: function( element, rule ) {\n\t\t\tvar message = this.defaultMessage( element, rule.method ),\n\t\t\t\ttheregex = /\\$?\\{(\\d+)\\}/g;\n\t\t\tif ( typeof message === \"function\" ) {\n\t\t\t\tmessage = message.call( this, rule.parameters, element );\n\t\t\t} else if ( theregex.test( message ) ) {\n\t\t\t\tmessage = $.validator.format( message.replace( theregex, \"{$1}\" ), rule.parameters );\n\t\t\t}\n\t\t\tthis.errorList.push({\n\t\t\t\tmessage: message,\n\t\t\t\telement: element,\n\t\t\t\tmethod: rule.method\n\t\t\t});\n\n\t\t\tthis.errorMap[ element.name ] = message;\n\t\t\tthis.submitted[ element.name ] = message;\n\t\t},\n\n\t\taddWrapper: function( toToggle ) {\n\t\t\tif ( this.settings.wrapper ) {\n\t\t\t\ttoToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\n\t\t\t}\n\t\t\treturn toToggle;\n\t\t},\n\n\t\tdefaultShowErrors: function() {\n\t\t\tvar i, elements, error;\n\t\t\tfor ( i = 0; this.errorList[ i ]; i++ ) {\n\t\t\t\terror = this.errorList[ i ];\n\t\t\t\tif ( this.settings.highlight ) {\n\t\t\t\t\tthis.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.showLabel( error.element, error.message );\n\t\t\t}\n\t\t\tif ( this.errorList.length ) {\n\t\t\t\tthis.toShow = this.toShow.add( this.containers );\n\t\t\t}\n\t\t\tif ( this.settings.success ) {\n\t\t\t\tfor ( i = 0; this.successList[ i ]; i++ ) {\n\t\t\t\t\tthis.showLabel( this.successList[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toHide = this.toHide.not( this.toShow );\n\t\t\tthis.hideErrors();\n\t\t\tthis.addWrapper( this.toShow ).show();\n\t\t},\n\n\t\tvalidElements: function() {\n\t\t\treturn this.currentElements.not( this.invalidElements() );\n\t\t},\n\n\t\tinvalidElements: function() {\n\t\t\treturn $( this.errorList ).map(function() {\n\t\t\t\treturn this.element;\n\t\t\t});\n\t\t},\n\n\t\tshowLabel: function( element, message ) {\n\t\t\tvar place, group, errorID,\n\t\t\t\terror = this.errorsFor( element ),\n\t\t\t\telementID = this.idOrName( element ),\n\t\t\t\tdescribedBy = $( element ).attr( \"aria-describedby\" );\n\t\t\tif ( error.length ) {\n\t\t\t\t// refresh error/success class\n\t\t\t\terror.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );\n\t\t\t\t// replace message on existing label\n\t\t\t\terror.html( message );\n\t\t\t} else {\n\t\t\t\t// create error element\n\t\t\t\terror = $( \"<\" + this.settings.errorElement + \">\" )\n\t\t\t\t\t.attr( \"id\", elementID + \"-error\" )\n\t\t\t\t\t.addClass( this.settings.errorClass )\n\t\t\t\t\t.html( message || \"\" );\n\n\t\t\t\t// Maintain reference to the element to be placed into the DOM\n\t\t\t\tplace = error;\n\t\t\t\tif ( this.settings.wrapper ) {\n\t\t\t\t\t// make sure the element is visible, even in IE\n\t\t\t\t\t// actually showing the wrapped element is handled elsewhere\n\t\t\t\t\tplace = error.hide().show().wrap( \"<\" + this.settings.wrapper + \"/>\" ).parent();\n\t\t\t\t}\n\t\t\t\tif ( this.labelContainer.length ) {\n\t\t\t\t\tthis.labelContainer.append( place );\n\t\t\t\t} else if ( this.settings.errorPlacement ) {\n\t\t\t\t\tthis.settings.errorPlacement( place, $( element ) );\n\t\t\t\t} else {\n\t\t\t\t\tplace.insertAfter( element );\n\t\t\t\t}\n\n\t\t\t\t// Link error back to the element\n\t\t\t\tif ( error.is( \"label\" ) ) {\n\t\t\t\t\t// If the error is a label, then associate using 'for'\n\t\t\t\t\terror.attr( \"for\", elementID );\n\t\t\t\t} else if ( error.parents( \"label[for='\" + elementID + \"']\" ).length === 0 ) {\n\t\t\t\t\t// If the element is not a child of an associated label, then it's necessary\n\t\t\t\t\t// to explicitly apply aria-describedby\n\n\t\t\t\t\terrorID = error.attr( \"id\" ).replace( /(:|\\.|\\[|\\]|\\$)/g, \"\\\\$1\");\n\t\t\t\t\t// Respect existing non-error aria-describedby\n\t\t\t\t\tif ( !describedBy ) {\n\t\t\t\t\t\tdescribedBy = errorID;\n\t\t\t\t\t} else if ( !describedBy.match( new RegExp( \"\\\\b\" + errorID + \"\\\\b\" ) ) ) {\n\t\t\t\t\t\t// Add to end of list if not already present\n\t\t\t\t\t\tdescribedBy += \" \" + errorID;\n\t\t\t\t\t}\n\t\t\t\t\t$( element ).attr( \"aria-describedby\", describedBy );\n\n\t\t\t\t\t// If this element is grouped, then assign to all elements in the same group\n\t\t\t\t\tgroup = this.groups[ element.name ];\n\t\t\t\t\tif ( group ) {\n\t\t\t\t\t\t$.each( this.groups, function( name, testgroup ) {\n\t\t\t\t\t\t\tif ( testgroup === group ) {\n\t\t\t\t\t\t\t\t$( \"[name='\" + name + \"']\", this.currentForm )\n\t\t\t\t\t\t\t\t\t.attr( \"aria-describedby\", error.attr( \"id\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !message && this.settings.success ) {\n\t\t\t\terror.text( \"\" );\n\t\t\t\tif ( typeof this.settings.success === \"string\" ) {\n\t\t\t\t\terror.addClass( this.settings.success );\n\t\t\t\t} else {\n\t\t\t\t\tthis.settings.success( error, element );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toShow = this.toShow.add( error );\n\t\t},\n\n\t\terrorsFor: function( element ) {\n\t\t\tvar name = this.idOrName( element ),\n\t\t\t\tdescriber = $( element ).attr( \"aria-describedby\" ),\n\t\t\t\tselector = \"label[for='\" + name + \"'], label[for='\" + name + \"'] *\";\n\n\t\t\t// aria-describedby should directly reference the error element\n\t\t\tif ( describer ) {\n\t\t\t\tselector = selector + \", #\" + describer.replace( /\\s+/g, \", #\" );\n\t\t\t}\n\t\t\treturn this\n\t\t\t\t.errors()\n\t\t\t\t.filter( selector );\n\t\t},\n\n\t\tidOrName: function( element ) {\n\t\t\treturn this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );\n\t\t},\n\n\t\tvalidationTargetFor: function( element ) {\n\n\t\t\t// If radio/checkbox, validate first element in group instead\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\telement = this.findByName( element.name );\n\t\t\t}\n\n\t\t\t// Always apply ignore filter\n\t\t\treturn $( element ).not( this.settings.ignore )[ 0 ];\n\t\t},\n\n\t\tcheckable: function( element ) {\n\t\t\treturn ( /radio|checkbox/i ).test( element.type );\n\t\t},\n\n\t\tfindByName: function( name ) {\n\t\t\treturn $( this.currentForm ).find( \"[name='\" + name + \"']\" );\n\t\t},\n\n\t\tgetLength: function( value, element ) {\n\t\t\tswitch ( element.nodeName.toLowerCase() ) {\n\t\t\tcase \"select\":\n\t\t\t\treturn $( \"option:selected\", element ).length;\n\t\t\tcase \"input\":\n\t\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\t\treturn this.findByName( element.name ).filter( \":checked\" ).length;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value.length;\n\t\t},\n\n\t\tdepend: function( param, element ) {\n\t\t\treturn this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;\n\t\t},\n\n\t\tdependTypes: {\n\t\t\t\"boolean\": function( param ) {\n\t\t\t\treturn param;\n\t\t\t},\n\t\t\t\"string\": function( param, element ) {\n\t\t\t\treturn !!$( param, element.form ).length;\n\t\t\t},\n\t\t\t\"function\": function( param, element ) {\n\t\t\t\treturn param( element );\n\t\t\t}\n\t\t},\n\n\t\toptional: function( element ) {\n\t\t\tvar val = this.elementValue( element );\n\t\t\treturn !$.validator.methods.required.call( this, val, element ) && \"dependency-mismatch\";\n\t\t},\n\n\t\tstartRequest: function( element ) {\n\t\t\tif ( !this.pending[ element.name ] ) {\n\t\t\t\tthis.pendingRequest++;\n\t\t\t\tthis.pending[ element.name ] = true;\n\t\t\t}\n\t\t},\n\n\t\tstopRequest: function( element, valid ) {\n\t\t\tthis.pendingRequest--;\n\t\t\t// sometimes synchronization fails, make sure pendingRequest is never < 0\n\t\t\tif ( this.pendingRequest < 0 ) {\n\t\t\t\tthis.pendingRequest = 0;\n\t\t\t}\n\t\t\tdelete this.pending[ element.name ];\n\t\t\tif ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {\n\t\t\t\t$( this.currentForm ).submit();\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t} else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t}\n\t\t},\n\n\t\tpreviousValue: function( element ) {\n\t\t\treturn $.data( element, \"previousValue\" ) || $.data( element, \"previousValue\", {\n\t\t\t\told: null,\n\t\t\t\tvalid: true,\n\t\t\t\tmessage: this.defaultMessage( element, \"remote\" )\n\t\t\t});\n\t\t},\n\n\t\t// cleans up all forms and elements, removes validator-specific events\n\t\tdestroy: function() {\n\t\t\tthis.resetForm();\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.off( \".validate\" )\n\t\t\t\t.removeData( \"validator\" );\n\t\t}\n\n\t},\n\n\tclassRuleSettings: {\n\t\trequired: { required: true },\n\t\temail: { email: true },\n\t\turl: { url: true },\n\t\tdate: { date: true },\n\t\tdateISO: { dateISO: true },\n\t\tnumber: { number: true },\n\t\tdigits: { digits: true },\n\t\tcreditcard: { creditcard: true }\n\t},\n\n\taddClassRules: function( className, rules ) {\n\t\tif ( className.constructor === String ) {\n\t\t\tthis.classRuleSettings[ className ] = rules;\n\t\t} else {\n\t\t\t$.extend( this.classRuleSettings, className );\n\t\t}\n\t},\n\n\tclassRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tclasses = $( element ).attr( \"class\" );\n\n\t\tif ( classes ) {\n\t\t\t$.each( classes.split( \" \" ), function() {\n\t\t\t\tif ( this in $.validator.classRuleSettings ) {\n\t\t\t\t\t$.extend( rules, $.validator.classRuleSettings[ this ]);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeAttributeRule: function( rules, type, method, value ) {\n\n\t\t// convert the value to a number for number inputs, and for text for backwards compability\n\t\t// allows type=\"date\" and others to be compared as strings\n\t\tif ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {\n\t\t\tvalue = Number( value );\n\n\t\t\t// Support Opera Mini, which returns NaN for undefined minlength\n\t\t\tif ( isNaN( value ) ) {\n\t\t\t\tvalue = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif ( value || value === 0 ) {\n\t\t\trules[ method ] = value;\n\t\t} else if ( type === method && type !== \"range\" ) {\n\n\t\t\t// exception: the jquery validate 'range' method\n\t\t\t// does not test for the html5 'range' type\n\t\t\trules[ method ] = true;\n\t\t}\n\t},\n\n\tattributeRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\n\t\t\t// support for <input required> in both html5 and older browsers\n\t\t\tif ( method === \"required\" ) {\n\t\t\t\tvalue = element.getAttribute( method );\n\n\t\t\t\t// Some browsers return an empty string for the required attribute\n\t\t\t\t// and non-HTML5 browsers might have required=\"\" markup\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\tvalue = true;\n\t\t\t\t}\n\n\t\t\t\t// force non-HTML5 browsers to return bool\n\t\t\t\tvalue = !!value;\n\t\t\t} else {\n\t\t\t\tvalue = $element.attr( method );\n\t\t\t}\n\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\n\t\t// maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs\n\t\tif ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {\n\t\t\tdelete rules.maxlength;\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\tdataRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\t\t\tvalue = $element.data( \"rule\" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\t\treturn rules;\n\t},\n\n\tstaticRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tvalidator = $.data( element.form, \"validator\" );\n\n\t\tif ( validator.settings.rules ) {\n\t\t\trules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeRules: function( rules, element ) {\n\t\t// handle dependency check\n\t\t$.each( rules, function( prop, val ) {\n\t\t\t// ignore rule when param is explicitly false, eg. required:false\n\t\t\tif ( val === false ) {\n\t\t\t\tdelete rules[ prop ];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( val.param || val.depends ) {\n\t\t\t\tvar keepRule = true;\n\t\t\t\tswitch ( typeof val.depends ) {\n\t\t\t\tcase \"string\":\n\t\t\t\t\tkeepRule = !!$( val.depends, element.form ).length;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"function\":\n\t\t\t\t\tkeepRule = val.depends.call( element, element );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( keepRule ) {\n\t\t\t\t\trules[ prop ] = val.param !== undefined ? val.param : true;\n\t\t\t\t} else {\n\t\t\t\t\tdelete rules[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// evaluate parameters\n\t\t$.each( rules, function( rule, parameter ) {\n\t\t\trules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;\n\t\t});\n\n\t\t// clean number parameters\n\t\t$.each([ \"minlength\", \"maxlength\" ], function() {\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\trules[ this ] = Number( rules[ this ] );\n\t\t\t}\n\t\t});\n\t\t$.each([ \"rangelength\", \"range\" ], function() {\n\t\t\tvar parts;\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\tif ( $.isArray( rules[ this ] ) ) {\n\t\t\t\t\trules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];\n\t\t\t\t} else if ( typeof rules[ this ] === \"string\" ) {\n\t\t\t\t\tparts = rules[ this ].replace(/[\\[\\]]/g, \"\" ).split( /[\\s,]+/ );\n\t\t\t\t\trules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif ( $.validator.autoCreateRanges ) {\n\t\t\t// auto-create ranges\n\t\t\tif ( rules.min != null && rules.max != null ) {\n\t\t\t\trules.range = [ rules.min, rules.max ];\n\t\t\t\tdelete rules.min;\n\t\t\t\tdelete rules.max;\n\t\t\t}\n\t\t\tif ( rules.minlength != null && rules.maxlength != null ) {\n\t\t\t\trules.rangelength = [ rules.minlength, rules.maxlength ];\n\t\t\t\tdelete rules.minlength;\n\t\t\t\tdelete rules.maxlength;\n\t\t\t}\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\t// Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\n\tnormalizeRule: function( data ) {\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tvar transformed = {};\n\t\t\t$.each( data.split( /\\s/ ), function() {\n\t\t\t\ttransformed[ this ] = true;\n\t\t\t});\n\t\t\tdata = transformed;\n\t\t}\n\t\treturn data;\n\t},\n\n\t// http://jqueryvalidation.org/jQuery.validator.addMethod/\n\taddMethod: function( name, method, message ) {\n\t\t$.validator.methods[ name ] = method;\n\t\t$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];\n\t\tif ( method.length < 3 ) {\n\t\t\t$.validator.addClassRules( name, $.validator.normalizeRule( name ) );\n\t\t}\n\t},\n\n\tmethods: {\n\n\t\t// http://jqueryvalidation.org/required-method/\n\t\trequired: function( value, element, param ) {\n\t\t\t// check if dependency is met\n\t\t\tif ( !this.depend( param, element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\t\t\tif ( element.nodeName.toLowerCase() === \"select\" ) {\n\t\t\t\t// could be an array for select-multiple or a string, both are fine this way\n\t\t\t\tvar val = $( element ).val();\n\t\t\t\treturn val && val.length > 0;\n\t\t\t}\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\treturn this.getLength( value, element ) > 0;\n\t\t\t}\n\t\t\treturn value.length > 0;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/email-method/\n\t\temail: function( value, element ) {\n\t\t\t// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address\n\t\t\t// Retrieved 2014-01-14\n\t\t\t// If you have a problem with this implementation, report a bug against the above spec\n\t\t\t// Or use custom methods to implement your own email validation\n\t\t\treturn this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/url-method/\n\t\turl: function( value, element ) {\n\n\t\t\t// Copyright (c) 2010-2013 Diego Perini, MIT licensed\n\t\t\t// https://gist.github.com/dperini/729294\n\t\t\t// see also https://mathiasbynens.be/demo/url-regex\n\t\t\t// modified to allow protocol-relative URLs\n\t\t\treturn this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})).?)(?::\\d{2,5})?(?:[/?#]\\S*)?$/i.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/date-method/\n\t\tdate: function( value, element ) {\n\t\t\treturn this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/dateISO-method/\n\t\tdateISO: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/number-method/\n\t\tnumber: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^(?:-?\\d+|-?\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/digits-method/\n\t\tdigits: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d+$/.test( value );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/creditcard-method/\n\t\t// based on http://en.wikipedia.org/wiki/Luhn_algorithm\n\t\tcreditcard: function( value, element ) {\n\t\t\tif ( this.optional( element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\t\t\t// accept only spaces, digits and dashes\n\t\t\tif ( /[^0-9 \\-]+/.test( value ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar nCheck = 0,\n\t\t\t\tnDigit = 0,\n\t\t\t\tbEven = false,\n\t\t\t\tn, cDigit;\n\n\t\t\tvalue = value.replace( /\\D/g, \"\" );\n\n\t\t\t// Basing min and max length on\n\t\t\t// http://developer.ean.com/general_info/Valid_Credit_Card_Types\n\t\t\tif ( value.length < 13 || value.length > 19 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor ( n = value.length - 1; n >= 0; n--) {\n\t\t\t\tcDigit = value.charAt( n );\n\t\t\t\tnDigit = parseInt( cDigit, 10 );\n\t\t\t\tif ( bEven ) {\n\t\t\t\t\tif ( ( nDigit *= 2 ) > 9 ) {\n\t\t\t\t\t\tnDigit -= 9;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnCheck += nDigit;\n\t\t\t\tbEven = !bEven;\n\t\t\t}\n\n\t\t\treturn ( nCheck % 10 ) === 0;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/minlength-method/\n\t\tminlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length >= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/maxlength-method/\n\t\tmaxlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length <= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/rangelength-method/\n\t\trangelength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/min-method/\n\t\tmin: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value >= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/max-method/\n\t\tmax: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value <= param;\n\t\t},\n\n\t\t// http://jqueryvalidation.org/range-method/\n\t\trange: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );\n\t\t},\n\n\t\t// http://jqueryvalidation.org/equalTo-method/\n\t\tequalTo: function( value, element, param ) {\n\t\t\t// bind to the blur event of the target in order to revalidate whenever the target field is updated\n\t\t\t// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead\n\t\t\tvar target = $( param );\n\t\t\tif ( this.settings.onfocusout ) {\n\t\t\t\ttarget.off( \".validate-equalTo\" ).on( \"blur.validate-equalTo\", function() {\n\t\t\t\t\t$( element ).valid();\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn value === target.val();\n\t\t},\n\n\t\t// http://jqueryvalidation.org/remote-method/\n\t\tremote: function( value, element, param ) {\n\t\t\tif ( this.optional( element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\n\t\t\tvar previous = this.previousValue( element ),\n\t\t\t\tvalidator, data;\n\n\t\t\tif (!this.settings.messages[ element.name ] ) {\n\t\t\t\tthis.settings.messages[ element.name ] = {};\n\t\t\t}\n\t\t\tprevious.originalMessage = this.settings.messages[ element.name ].remote;\n\t\t\tthis.settings.messages[ element.name ].remote = previous.message;\n\n\t\t\tparam = typeof param === \"string\" && { url: param } || param;\n\n\t\t\tif ( previous.old === value ) {\n\t\t\t\treturn previous.valid;\n\t\t\t}\n\n\t\t\tprevious.old = value;\n\t\t\tvalidator = this;\n\t\t\tthis.startRequest( element );\n\t\t\tdata = {};\n\t\t\tdata[ element.name ] = value;\n\t\t\t$.ajax( $.extend( true, {\n\t\t\t\tmode: \"abort\",\n\t\t\t\tport: \"validate\" + element.name,\n\t\t\t\tdataType: \"json\",\n\t\t\t\tdata: data,\n\t\t\t\tcontext: validator.currentForm,\n\t\t\t\tsuccess: function( response ) {\n\t\t\t\t\tvar valid = response === true || response === \"true\",\n\t\t\t\t\t\terrors, message, submitted;\n\n\t\t\t\t\tvalidator.settings.messages[ element.name ].remote = previous.originalMessage;\n\t\t\t\t\tif ( valid ) {\n\t\t\t\t\t\tsubmitted = validator.formSubmitted;\n\t\t\t\t\t\tvalidator.prepareElement( element );\n\t\t\t\t\t\tvalidator.formSubmitted = submitted;\n\t\t\t\t\t\tvalidator.successList.push( element );\n\t\t\t\t\t\tdelete validator.invalid[ element.name ];\n\t\t\t\t\t\tvalidator.showErrors();\n\t\t\t\t\t} else {\n\t\t\t\t\t\terrors = {};\n\t\t\t\t\t\tmessage = response || validator.defaultMessage( element, \"remote\" );\n\t\t\t\t\t\terrors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;\n\t\t\t\t\t\tvalidator.invalid[ element.name ] = true;\n\t\t\t\t\t\tvalidator.showErrors( errors );\n\t\t\t\t\t}\n\t\t\t\t\tprevious.valid = valid;\n\t\t\t\t\tvalidator.stopRequest( element, valid );\n\t\t\t\t}\n\t\t\t}, param ) );\n\t\t\treturn \"pending\";\n\t\t}\n\t}\n\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ar.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: AR (Arabic; العربية)\n */\n$.extend($.validator.messages, {\n\trequired: \"هذا الحقل إلزامي\",\n\tremote: \"يرجى تصحيح هذا الحقل للمتابعة\",\n\temail: \"رجاء إدخال عنوان بريد إلكتروني صحيح\",\n\turl: \"رجاء إدخال عنوان موقع إلكتروني صحيح\",\n\tdate: \"رجاء إدخال تاريخ صحيح\",\n\tdateISO: \"رجاء إدخال تاريخ صحيح (ISO)\",\n\tnumber: \"رجاء إدخال عدد بطريقة صحيحة\",\n\tdigits: \"رجاء إدخال أرقام فقط\",\n\tcreditcard: \"رجاء إدخال رقم بطاقة ائتمان صحيح\",\n\tequalTo: \"رجاء إدخال نفس القيمة\",\n\textension: \"رجاء إدخال ملف بامتداد موافق عليه\",\n\tmaxlength: $.validator.format(\"الحد الأقصى لعدد الحروف هو {0}\"),\n\tminlength: $.validator.format(\"الحد الأدنى لعدد الحروف هو {0}\"),\n\trangelength: $.validator.format(\"عدد الحروف يجب أن يكون بين {0} و {1}\"),\n\trange: $.validator.format(\"رجاء إدخال عدد قيمته بين {0} و {1}\"),\n\tmax: $.validator.format(\"رجاء إدخال عدد أقل من أو يساوي (0}\"),\n\tmin: $.validator.format(\"رجاء إدخال عدد أكبر من أو يساوي (0}\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_bg.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: BG (Bulgarian; български език)\n */\n$.extend($.validator.messages, {\n\trequired: \"Полето е задължително.\",\n\tremote: \"Моля, въведете правилната стойност.\",\n\temail: \"Моля, въведете валиден email.\",\n\turl: \"Моля, въведете валидно URL.\",\n\tdate: \"Моля, въведете валидна дата.\",\n\tdateISO: \"Моля, въведете валидна дата (ISO).\",\n\tnumber: \"Моля, въведете валиден номер.\",\n\tdigits: \"Моля, въведете само цифри.\",\n\tcreditcard: \"Моля, въведете валиден номер на кредитна карта.\",\n\tequalTo: \"Моля, въведете същата стойност отново.\",\n\textension: \"Моля, въведете стойност с валидно разширение.\",\n\tmaxlength: $.validator.format(\"Моля, въведете повече от {0} символа.\"),\n\tminlength: $.validator.format(\"Моля, въведете поне {0} символа.\"),\n\trangelength: $.validator.format(\"Моля, въведете стойност с дължина между {0} и {1} символа.\"),\n\trange: $.validator.format(\"Моля, въведете стойност между {0} и {1}.\"),\n\tmax: $.validator.format(\"Моля, въведете стойност по-малка или равна на {0}.\"),\n\tmin: $.validator.format(\"Моля, въведете стойност по-голяма или равна на {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_bn_BD.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: bn_BD (Bengali, Bangladesh)\n */\n$.extend($.validator.messages, {\n\trequired: \"এই তথ্যটি আবশ্যক।\",\n\tremote: \"এই তথ্যটি ঠিক করুন।\",\n\temail: \"অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।\",\n\turl: \"অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।\",\n\tdate: \"তারিখ সঠিক নয়।\",\n\tdateISO: \"অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।\",\n\tnumber: \"অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।\",\n\tdigits: \"এখানে শুধু সংখ্যা ব্যবহার করা যাবে।\",\n\tcreditcard: \"অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।\",\n\tequalTo: \"একই মান আবার লিখুন।\",\n\textension: \"সঠিক ধরনের ফাইল আপলোড করুন।\",\n\tmaxlength: $.validator.format(\"{0}টির বেশি অক্ষর লেখা যাবে না।\"),\n\tminlength: $.validator.format(\"{0}টির কম অক্ষর লেখা যাবে না।\"),\n\trangelength: $.validator.format(\"{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।\"),\n\trange: $.validator.format(\"{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।\"),\n\tmax: $.validator.format(\"অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।\"),\n\tmin: $.validator.format(\"অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ca.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: CA (Catalan; català)\n */\n$.extend($.validator.messages, {\n\trequired: \"Aquest camp és obligatori.\",\n\tremote: \"Si us plau, omple aquest camp.\",\n\temail: \"Si us plau, escriu una adreça de correu-e vàlida\",\n\turl: \"Si us plau, escriu una URL vàlida.\",\n\tdate: \"Si us plau, escriu una data vàlida.\",\n\tdateISO: \"Si us plau, escriu una data (ISO) vàlida.\",\n\tnumber: \"Si us plau, escriu un número enter vàlid.\",\n\tdigits: \"Si us plau, escriu només dígits.\",\n\tcreditcard: \"Si us plau, escriu un número de tarjeta vàlid.\",\n\tequalTo: \"Si us plau, escriu el mateix valor de nou.\",\n\textension: \"Si us plau, escriu un valor amb una extensió acceptada.\",\n\tmaxlength: $.validator.format(\"Si us plau, no escriguis més de {0} caracters.\"),\n\tminlength: $.validator.format(\"Si us plau, no escriguis menys de {0} caracters.\"),\n\trangelength: $.validator.format(\"Si us plau, escriu un valor entre {0} i {1} caracters.\"),\n\trange: $.validator.format(\"Si us plau, escriu un valor entre {0} i {1}.\"),\n\tmax: $.validator.format(\"Si us plau, escriu un valor menor o igual a {0}.\"),\n\tmin: $.validator.format(\"Si us plau, escriu un valor major o igual a {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_cs.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: CS (Czech; čeština, český jazyk)\n */\n$.extend($.validator.messages, {\n\trequired: \"Tento údaj je povinný.\",\n\tremote: \"Prosím, opravte tento údaj.\",\n\temail: \"Prosím, zadejte platný e-mail.\",\n\turl: \"Prosím, zadejte platné URL.\",\n\tdate: \"Prosím, zadejte platné datum.\",\n\tdateISO: \"Prosím, zadejte platné datum (ISO).\",\n\tnumber: \"Prosím, zadejte číslo.\",\n\tdigits: \"Prosím, zadávejte pouze číslice.\",\n\tcreditcard: \"Prosím, zadejte číslo kreditní karty.\",\n\tequalTo: \"Prosím, zadejte znovu stejnou hodnotu.\",\n\textension: \"Prosím, zadejte soubor se správnou příponou.\",\n\tmaxlength: $.validator.format(\"Prosím, zadejte nejvíce {0} znaků.\"),\n\tminlength: $.validator.format(\"Prosím, zadejte nejméně {0} znaků.\"),\n\trangelength: $.validator.format(\"Prosím, zadejte od {0} do {1} znaků.\"),\n\trange: $.validator.format(\"Prosím, zadejte hodnotu od {0} do {1}.\"),\n\tmax: $.validator.format(\"Prosím, zadejte hodnotu menší nebo rovnu {0}.\"),\n\tmin: $.validator.format(\"Prosím, zadejte hodnotu větší nebo rovnu {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_da.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: DA (Danish; dansk)\n */\n$.extend($.validator.messages, {\n\trequired: \"Dette felt er påkrævet.\",\n\tmaxlength: $.validator.format(\"Indtast højst {0} tegn.\"),\n\tminlength: $.validator.format(\"Indtast mindst {0} tegn.\"),\n\trangelength: $.validator.format(\"Indtast mindst {0} og højst {1} tegn.\"),\n\temail: \"Indtast en gyldig email-adresse.\",\n\turl: \"Indtast en gyldig URL.\",\n\tdate: \"Indtast en gyldig dato.\",\n\tnumber: \"Indtast et tal.\",\n\tdigits: \"Indtast kun cifre.\",\n\tequalTo: \"Indtast den samme værdi igen.\",\n\trange: $.validator.format(\"Angiv en værdi mellem {0} og {1}.\"),\n\tmax: $.validator.format(\"Angiv en værdi der højst er {0}.\"),\n\tmin: $.validator.format(\"Angiv en værdi der mindst er {0}.\"),\n\tcreditcard: \"Indtast et gyldigt kreditkortnummer.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_de.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: DE (German, Deutsch)\n */\n$.extend($.validator.messages, {\n\trequired: \"Dieses Feld ist ein Pflichtfeld.\",\n\tmaxlength: $.validator.format(\"Geben Sie bitte maximal {0} Zeichen ein.\"),\n\tminlength: $.validator.format(\"Geben Sie bitte mindestens {0} Zeichen ein.\"),\n\trangelength: $.validator.format(\"Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein.\"),\n\temail: \"Geben Sie bitte eine gültige E-Mail Adresse ein.\",\n\turl: \"Geben Sie bitte eine gültige URL ein.\",\n\tdate: \"Bitte geben Sie ein gültiges Datum ein.\",\n\tnumber: \"Geben Sie bitte eine Nummer ein.\",\n\tdigits: \"Geben Sie bitte nur Ziffern ein.\",\n\tequalTo: \"Bitte denselben Wert wiederholen.\",\n\trange: $.validator.format(\"Geben Sie bitte einen Wert zwischen {0} und {1} ein.\"),\n\tmax: $.validator.format(\"Geben Sie bitte einen Wert kleiner oder gleich {0} ein.\"),\n\tmin: $.validator.format(\"Geben Sie bitte einen Wert größer oder gleich {0} ein.\"),\n\tcreditcard: \"Geben Sie bitte eine gültige Kreditkarten-Nummer ein.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_el.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: EL (Greek; ελληνικά)\n */\n$.extend($.validator.messages, {\n\trequired: \"Αυτό το πεδίο είναι υποχρεωτικό.\",\n\tremote: \"Παρακαλώ διορθώστε αυτό το πεδίο.\",\n\temail: \"Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.\",\n\turl: \"Παρακαλώ εισάγετε ένα έγκυρο URL.\",\n\tdate: \"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.\",\n\tdateISO: \"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).\",\n\tnumber: \"Παρακαλώ εισάγετε έναν έγκυρο αριθμό.\",\n\tdigits: \"Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.\",\n\tcreditcard: \"Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.\",\n\tequalTo: \"Παρακαλώ εισάγετε την ίδια τιμή ξανά.\",\n\textension: \"Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.\",\n\tmaxlength: $.validator.format(\"Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες.\"),\n\tminlength: $.validator.format(\"Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες.\"),\n\trangelength: $.validator.format(\"Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων.\"),\n\trange: $.validator.format(\"Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}.\"),\n\tmax: $.validator.format(\"Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}.\"),\n\tmin: $.validator.format(\"Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_es.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ES (Spanish; Español)\n */\n$.extend($.validator.messages, {\n\trequired: \"Este campo es obligatorio.\",\n\tremote: \"Por favor, rellena este campo.\",\n\temail: \"Por favor, escribe una dirección de correo válida.\",\n\turl: \"Por favor, escribe una URL válida.\",\n\tdate: \"Por favor, escribe una fecha válida.\",\n\tdateISO: \"Por favor, escribe una fecha (ISO) válida.\",\n\tnumber: \"Por favor, escribe un número válido.\",\n\tdigits: \"Por favor, escribe sólo dígitos.\",\n\tcreditcard: \"Por favor, escribe un número de tarjeta válido.\",\n\tequalTo: \"Por favor, escribe el mismo valor de nuevo.\",\n\textension: \"Por favor, escribe un valor con una extensión aceptada.\",\n\tmaxlength: $.validator.format(\"Por favor, no escribas más de {0} caracteres.\"),\n\tminlength: $.validator.format(\"Por favor, no escribas menos de {0} caracteres.\"),\n\trangelength: $.validator.format(\"Por favor, escribe un valor entre {0} y {1} caracteres.\"),\n\trange: $.validator.format(\"Por favor, escribe un valor entre {0} y {1}.\"),\n\tmax: $.validator.format(\"Por favor, escribe un valor menor o igual a {0}.\"),\n\tmin: $.validator.format(\"Por favor, escribe un valor mayor o igual a {0}.\"),\n\tnifES: \"Por favor, escribe un NIF válido.\",\n\tnieES: \"Por favor, escribe un NIE válido.\",\n\tcifES: \"Por favor, escribe un CIF válido.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_es_AR.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ES (Spanish; Español)\n * Region: AR (Argentina)\n */\n$.extend($.validator.messages, {\n\trequired: \"Este campo es obligatorio.\",\n\tremote: \"Por favor, completá este campo.\",\n\temail: \"Por favor, escribí una dirección de correo válida.\",\n\turl: \"Por favor, escribí una URL válida.\",\n\tdate: \"Por favor, escribí una fecha válida.\",\n\tdateISO: \"Por favor, escribí una fecha (ISO) válida.\",\n\tnumber: \"Por favor, escribí un número entero válido.\",\n\tdigits: \"Por favor, escribí sólo dígitos.\",\n\tcreditcard: \"Por favor, escribí un número de tarjeta válido.\",\n\tequalTo: \"Por favor, escribí el mismo valor de nuevo.\",\n\textension: \"Por favor, escribí un valor con una extensión aceptada.\",\n\tmaxlength: $.validator.format(\"Por favor, no escribas más de {0} caracteres.\"),\n\tminlength: $.validator.format(\"Por favor, no escribas menos de {0} caracteres.\"),\n\trangelength: $.validator.format(\"Por favor, escribí un valor entre {0} y {1} caracteres.\"),\n\trange: $.validator.format(\"Por favor, escribí un valor entre {0} y {1}.\"),\n\tmax: $.validator.format(\"Por favor, escribí un valor menor o igual a {0}.\"),\n\tmin: $.validator.format(\"Por favor, escribí un valor mayor o igual a {0}.\"),\n\tnifES: \"Por favor, escribí un NIF válido.\",\n\tnieES: \"Por favor, escribí un NIE válido.\",\n\tcifES: \"Por favor, escribí un CIF válido.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_es_PE.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ES (Spanish; Español)\n * Region: PE (Perú)\n */\n$.extend($.validator.messages, {\n\trequired: \"Este campo es obligatorio.\",\n\tremote: \"Por favor, llene este campo.\",\n\temail: \"Por favor, escriba un correo electrónico válido.\",\n\turl: \"Por favor, escriba una URL válida.\",\n\tdate: \"Por favor, escriba una fecha válida.\",\n\tdateISO: \"Por favor, escriba una fecha (ISO) válida.\",\n\tnumber: \"Por favor, escriba un número válido.\",\n\tdigits: \"Por favor, escriba sólo dígitos.\",\n\tcreditcard: \"Por favor, escriba un número de tarjeta válido.\",\n\tequalTo: \"Por favor, escriba el mismo valor de nuevo.\",\n\textension: \"Por favor, escriba un valor con una extensión permitida.\",\n\tmaxlength: $.validator.format(\"Por favor, no escriba más de {0} caracteres.\"),\n\tminlength: $.validator.format(\"Por favor, no escriba menos de {0} caracteres.\"),\n\trangelength: $.validator.format(\"Por favor, escriba un valor entre {0} y {1} caracteres.\"),\n\trange: $.validator.format(\"Por favor, escriba un valor entre {0} y {1}.\"),\n\tmax: $.validator.format(\"Por favor, escriba un valor menor o igual a {0}.\"),\n\tmin: $.validator.format(\"Por favor, escriba un valor mayor o igual a {0}.\"),\n\tnifES: \"Por favor, escriba un NIF válido.\",\n\tnieES: \"Por favor, escriba un NIE válido.\",\n\tcifES: \"Por favor, escriba un CIF válido.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_et.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ET (Estonian; eesti, eesti keel)\n */\n$.extend($.validator.messages, {\n\trequired: \"See väli peab olema täidetud.\",\n\tmaxlength: $.validator.format(\"Palun sisestage vähem kui {0} tähemärki.\"),\n\tminlength: $.validator.format(\"Palun sisestage vähemalt {0} tähemärki.\"),\n\trangelength: $.validator.format(\"Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki.\"),\n\temail: \"Palun sisestage korrektne e-maili aadress.\",\n\turl: \"Palun sisestage korrektne URL.\",\n\tdate: \"Palun sisestage korrektne kuupäev.\",\n\tdateISO: \"Palun sisestage korrektne kuupäev (YYYY-MM-DD).\",\n\tnumber: \"Palun sisestage korrektne number.\",\n\tdigits: \"Palun sisestage ainult numbreid.\",\n\tequalTo: \"Palun sisestage sama väärtus uuesti.\",\n\trange: $.validator.format(\"Palun sisestage väärtus vahemikus {0} kuni {1}.\"),\n\tmax: $.validator.format(\"Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}.\"),\n\tmin: $.validator.format(\"Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}.\"),\n\tcreditcard: \"Palun sisestage korrektne krediitkaardi number.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_eu.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: EU (Basque; euskara, euskera)\n */\n$.extend($.validator.messages, {\n\trequired: \"Eremu hau beharrezkoa da.\",\n\tremote: \"Mesedez, bete eremu hau.\",\n\temail: \"Mesedez, idatzi baliozko posta helbide bat.\",\n\turl: \"Mesedez, idatzi baliozko URL bat.\",\n\tdate: \"Mesedez, idatzi baliozko data bat.\",\n\tdateISO: \"Mesedez, idatzi baliozko (ISO) data bat.\",\n\tnumber: \"Mesedez, idatzi baliozko zenbaki oso bat.\",\n\tdigits: \"Mesedez, idatzi digituak soilik.\",\n\tcreditcard: \"Mesedez, idatzi baliozko txartel zenbaki bat.\",\n\tequalTo: \"Mesedez, idatzi berdina berriro ere.\",\n\textension: \"Mesedez, idatzi onartutako luzapena duen balio bat.\",\n\tmaxlength: $.validator.format(\"Mesedez, ez idatzi {0} karaktere baino gehiago.\"),\n\tminlength: $.validator.format(\"Mesedez, ez idatzi {0} karaktere baino gutxiago.\"),\n\trangelength: $.validator.format(\"Mesedez, idatzi {0} eta {1} karaktere arteko balio bat.\"),\n\trange: $.validator.format(\"Mesedez, idatzi {0} eta {1} arteko balio bat.\"),\n\tmax: $.validator.format(\"Mesedez, idatzi {0} edo txikiagoa den balio bat.\"),\n\tmin: $.validator.format(\"Mesedez, idatzi {0} edo handiagoa den balio bat.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_fa.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: FA (Persian; فارسی)\n */\n$.extend($.validator.messages, {\n\trequired: \"تکمیل این فیلد اجباری است.\",\n\tremote: \"لطفا این فیلد را تصحیح کنید.\",\n\temail: \".لطفا یک ایمیل صحیح وارد کنید\",\n\turl: \"لطفا آدرس صحیح وارد کنید.\",\n\tdate: \"لطفا یک تاریخ صحیح وارد کنید\",\n\tdateFA: \"لطفا یک تاریخ صحیح وارد کنید\",\n\tdateISO: \"لطفا تاریخ صحیح وارد کنید (ISO).\",\n\tnumber: \"لطفا عدد صحیح وارد کنید.\",\n\tdigits: \"لطفا تنها رقم وارد کنید\",\n\tcreditcard: \"لطفا کریدیت کارت صحیح وارد کنید.\",\n\tequalTo: \"لطفا مقدار برابری وارد کنید\",\n\textension: \"لطفا مقداری وارد کنید که \",\n\tmaxlength: $.validator.format(\"لطفا بیشتر از {0} حرف وارد نکنید.\"),\n\tminlength: $.validator.format(\"لطفا کمتر از {0} حرف وارد نکنید.\"),\n\trangelength: $.validator.format(\"لطفا مقداری بین {0} تا {1} حرف وارد کنید.\"),\n\trange: $.validator.format(\"لطفا مقداری بین {0} تا {1} حرف وارد کنید.\"),\n\tmax: $.validator.format(\"لطفا مقداری کمتر از {0} حرف وارد کنید.\"),\n\tmin: $.validator.format(\"لطفا مقداری بیشتر از {0} حرف وارد کنید.\"),\n\tminWords: $.validator.format(\"لطفا حداقل {0} کلمه وارد کنید.\"),\n\tmaxWords: $.validator.format(\"لطفا حداکثر {0} کلمه وارد کنید.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_fi.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: FI (Finnish; suomi, suomen kieli)\n */\n$.extend($.validator.messages, {\n\trequired: \"T&auml;m&auml; kentt&auml; on pakollinen.\",\n\temail: \"Sy&ouml;t&auml; oikea s&auml;hk&ouml;postiosoite.\",\n\turl: \"Sy&ouml;t&auml; oikea URL-osoite.\",\n\tdate: \"Sy&ouml;t&auml; oikea p&auml;iv&auml;m&auml;&auml;r&auml;.\",\n\tdateISO: \"Sy&ouml;t&auml; oikea p&auml;iv&auml;m&auml;&auml;r&auml; muodossa VVVV-KK-PP.\",\n\tnumber: \"Sy&ouml;t&auml; luku.\",\n\tcreditcard: \"Sy&ouml;t&auml; voimassa oleva luottokorttinumero.\",\n\tdigits: \"Sy&ouml;t&auml; pelk&auml;st&auml;&auml;n numeroita.\",\n\tequalTo: \"Sy&ouml;t&auml; sama arvo uudestaan.\",\n\tmaxlength: $.validator.format(\"Voit sy&ouml;tt&auml;&auml; enint&auml;&auml;n {0} merkki&auml;.\"),\n\tminlength: $.validator.format(\"V&auml;hint&auml;&auml;n {0} merkki&auml;.\"),\n\trangelength: $.validator.format(\"Sy&ouml;t&auml; v&auml;hint&auml;&auml;n {0} ja enint&auml;&auml;n {1} merkki&auml;.\"),\n\trange: $.validator.format(\"Sy&ouml;t&auml; arvo v&auml;lilt&auml; {0}&ndash;{1}.\"),\n\tmax: $.validator.format(\"Sy&ouml;t&auml; arvo, joka on enint&auml;&auml;n {0}.\"),\n\tmin: $.validator.format(\"Sy&ouml;t&auml; arvo, joka on v&auml;hint&auml;&auml;n {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_fr.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: FR (French; français)\n */\n$.extend($.validator.messages, {\n\trequired: \"Ce champ est obligatoire.\",\n\tremote: \"Veuillez corriger ce champ.\",\n\temail: \"Veuillez fournir une adresse électronique valide.\",\n\turl: \"Veuillez fournir une adresse URL valide.\",\n\tdate: \"Veuillez fournir une date valide.\",\n\tdateISO: \"Veuillez fournir une date valide (ISO).\",\n\tnumber: \"Veuillez fournir un numéro valide.\",\n\tdigits: \"Veuillez fournir seulement des chiffres.\",\n\tcreditcard: \"Veuillez fournir un numéro de carte de crédit valide.\",\n\tequalTo: \"Veuillez fournir encore la même valeur.\",\n\textension: \"Veuillez fournir une valeur avec une extension valide.\",\n\tmaxlength: $.validator.format(\"Veuillez fournir au plus {0} caractères.\"),\n\tminlength: $.validator.format(\"Veuillez fournir au moins {0} caractères.\"),\n\trangelength: $.validator.format(\"Veuillez fournir une valeur qui contient entre {0} et {1} caractères.\"),\n\trange: $.validator.format(\"Veuillez fournir une valeur entre {0} et {1}.\"),\n\tmax: $.validator.format(\"Veuillez fournir une valeur inférieure ou égale à {0}.\"),\n\tmin: $.validator.format(\"Veuillez fournir une valeur supérieure ou égale à {0}.\"),\n\tmaxWords: $.validator.format(\"Veuillez fournir au plus {0} mots.\"),\n\tminWords: $.validator.format(\"Veuillez fournir au moins {0} mots.\"),\n\trangeWords: $.validator.format(\"Veuillez fournir entre {0} et {1} mots.\"),\n\tletterswithbasicpunc: \"Veuillez fournir seulement des lettres et des signes de ponctuation.\",\n\talphanumeric: \"Veuillez fournir seulement des lettres, nombres, espaces et soulignages.\",\n\tlettersonly: \"Veuillez fournir seulement des lettres.\",\n\tnowhitespace: \"Veuillez ne pas inscrire d'espaces blancs.\",\n\tziprange: \"Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.\",\n\tinteger: \"Veuillez fournir un nombre non décimal qui est positif ou négatif.\",\n\tvinUS: \"Veuillez fournir un numéro d'identification du véhicule (VIN).\",\n\tdateITA: \"Veuillez fournir une date valide.\",\n\ttime: \"Veuillez fournir une heure valide entre 00:00 et 23:59.\",\n\tphoneUS: \"Veuillez fournir un numéro de téléphone valide.\",\n\tphoneUK: \"Veuillez fournir un numéro de téléphone valide.\",\n\tmobileUK: \"Veuillez fournir un numéro de téléphone mobile valide.\",\n\tstrippedminlength: $.validator.format(\"Veuillez fournir au moins {0} caractères.\"),\n\temail2: \"Veuillez fournir une adresse électronique valide.\",\n\turl2: \"Veuillez fournir une adresse URL valide.\",\n\tcreditcardtypes: \"Veuillez fournir un numéro de carte de crédit valide.\",\n\tipv4: \"Veuillez fournir une adresse IP v4 valide.\",\n\tipv6: \"Veuillez fournir une adresse IP v6 valide.\",\n\trequire_from_group: \"Veuillez fournir au moins {0} de ces champs.\",\n\tnifES: \"Veuillez fournir un numéro NIF valide.\",\n\tnieES: \"Veuillez fournir un numéro NIE valide.\",\n\tcifES: \"Veuillez fournir un numéro CIF valide.\",\n\tpostalCodeCA: \"Veuillez fournir un code postal valide.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ge.js",
    "content": "/**\n * @author  @tatocaster <kutaliatato@gmail.com>\n * Translated default messages for the jQuery validation plugin.\n * Locale: GE (Georgian; ქართული)\n */\n$.extend($.validator.messages, {\n\trequired: \"ეს ველი სავალდებულოა\",\n\tremote: \"გთხოვთ შეასწოროთ.\",\n\temail: \"გთხოვთ შეიყვანოთ სწორი ფორმატით.\",\n\turl: \"გთხოვთ შეიყვანოთ სწორი ფორმატით.\",\n\tdate: \"გთხოვთ შეიყვანოთ სწორი თარიღი.\",\n\tdateISO: \"გთხოვთ შეიყვანოთ სწორი ფორმატით ( ISO ).\",\n\tnumber: \"გთხოვთ შეიყვანოთ რიცხვი.\",\n\tdigits: \"დაშვებულია მხოლოდ ციფრები.\",\n\tcreditcard: \"გთხოვთ შეიყვანოთ სწორი ფორმატის ბარათის კოდი.\",\n\tequalTo: \"გთხოვთ შეიყვანოთ იგივე მნიშვნელობა.\",\n\tmaxlength: $.validator.format( \"გთხოვთ შეიყვანოთ არა უმეტეს {0} სიმბოლოსი.\" ),\n\tminlength: $.validator.format( \"შეიყვანეთ მინიმუმ {0} სიმბოლო.\" ),\n\trangelength: $.validator.format( \"გთხოვთ შეიყვანოთ {0} -დან {1} -მდე რაოდენობის სიმბოლოები.\" ),\n\trange: $.validator.format( \"შეიყვანეთ {0} -სა {1} -ს შორის.\" ),\n\tmax: $.validator.format( \"გთხოვთ შეიყვანოთ მნიშვნელობა ნაკლები ან ტოლი {0} -ს.\" ),\n\tmin: $.validator.format( \"გთხოვთ შეიყვანოთ მნიშვნელობა მეტი ან ტოლი {0} -ს.\" )\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_gl.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: GL (Galician; Galego)\n */\n(function($) {\n\t$.extend($.validator.messages, {\n\t\trequired: \"Este campo é obrigatorio.\",\n\t\tremote: \"Por favor, cubre este campo.\",\n\t\temail: \"Por favor, escribe unha dirección de correo válida.\",\n\t\turl: \"Por favor, escribe unha URL válida.\",\n\t\tdate: \"Por favor, escribe unha data válida.\",\n\t\tdateISO: \"Por favor, escribe unha data (ISO) válida.\",\n\t\tnumber: \"Por favor, escribe un número válido.\",\n\t\tdigits: \"Por favor, escribe só díxitos.\",\n\t\tcreditcard: \"Por favor, escribe un número de tarxeta válido.\",\n\t\tequalTo: \"Por favor, escribe o mesmo valor de novo.\",\n\t\textension: \"Por favor, escribe un valor cunha extensión aceptada.\",\n\t\tmaxlength: $.validator.format(\"Por favor, non escribas máis de {0} caracteres.\"),\n\t\tminlength: $.validator.format(\"Por favor, non escribas menos de {0} caracteres.\"),\n\t\trangelength: $.validator.format(\"Por favor, escribe un valor entre {0} e {1} caracteres.\"),\n\t\trange: $.validator.format(\"Por favor, escribe un valor entre {0} e {1}.\"),\n\t\tmax: $.validator.format(\"Por favor, escribe un valor menor ou igual a {0}.\"),\n\t\tmin: $.validator.format(\"Por favor, escribe un valor maior ou igual a {0}.\"),\n\t\tnifES: \"Por favor, escribe un NIF válido.\",\n\t\tnieES: \"Por favor, escribe un NIE válido.\",\n\t\tcifES: \"Por favor, escribe un CIF válido.\"\n\t});\n}(jQuery));\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_he.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: HE (Hebrew; עברית)\n */\n$.extend($.validator.messages, {\n\trequired: \"השדה הזה הינו שדה חובה\",\n\tremote: \"נא לתקן שדה זה\",\n\temail: \"נא למלא כתובת דוא\\\"ל חוקית\",\n\turl: \"נא למלא כתובת אינטרנט חוקית\",\n\tdate: \"נא למלא תאריך חוקי\",\n\tdateISO: \"נא למלא תאריך חוקי (ISO)\",\n\tnumber: \"נא למלא מספר\",\n\tdigits: \"נא למלא רק מספרים\",\n\tcreditcard: \"נא למלא מספר כרטיס אשראי חוקי\",\n\tequalTo: \"נא למלא את אותו ערך שוב\",\n\textension: \"נא למלא ערך עם סיומת חוקית\",\n\tmaxlength: $.validator.format(\".נא לא למלא יותר מ- {0} תווים\"),\n\tminlength: $.validator.format(\"נא למלא לפחות {0} תווים\"),\n\trangelength: $.validator.format(\"נא למלא ערך בין {0} ל- {1} תווים\"),\n\trange: $.validator.format(\"נא למלא ערך בין {0} ל- {1}\"),\n\tmax: $.validator.format(\"נא למלא ערך קטן או שווה ל- {0}\"),\n\tmin: $.validator.format(\"נא למלא ערך גדול או שווה ל- {0}\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_hr.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: HR (Croatia; hrvatski jezik)\n */\n$.extend($.validator.messages, {\n\trequired: \"Ovo polje je obavezno.\",\n\tremote: \"Ovo polje treba popraviti.\",\n\temail: \"Unesite ispravnu e-mail adresu.\",\n\turl: \"Unesite ispravan URL.\",\n\tdate: \"Unesite ispravan datum.\",\n\tdateISO: \"Unesite ispravan datum (ISO).\",\n\tnumber: \"Unesite ispravan broj.\",\n\tdigits: \"Unesite samo brojeve.\",\n\tcreditcard: \"Unesite ispravan broj kreditne kartice.\",\n\tequalTo: \"Unesite ponovo istu vrijednost.\",\n\textension: \"Unesite vrijednost sa ispravnom ekstenzijom.\",\n\tmaxlength: $.validator.format(\"Maksimalni broj znakova je {0} .\"),\n\tminlength: $.validator.format(\"Minimalni broj znakova je {0} .\"),\n\trangelength: $.validator.format(\"Unesite vrijednost između {0} i {1} znakova.\"),\n\trange: $.validator.format(\"Unesite vrijednost između {0} i {1}.\"),\n\tmax: $.validator.format(\"Unesite vrijednost manju ili jednaku {0}.\"),\n\tmin: $.validator.format(\"Unesite vrijednost veću ili jednaku {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_hu.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: HU (Hungarian; Magyar)\n */\n$.extend($.validator.messages, {\n\trequired: \"Kötelező megadni.\",\n\tmaxlength: $.validator.format(\"Legfeljebb {0} karakter hosszú legyen.\"),\n\tminlength: $.validator.format(\"Legalább {0} karakter hosszú legyen.\"),\n\trangelength: $.validator.format(\"Legalább {0} és legfeljebb {1} karakter hosszú legyen.\"),\n\temail: \"Érvényes e-mail címnek kell lennie.\",\n\turl: \"Érvényes URL-nek kell lennie.\",\n\tdate: \"Dátumnak kell lennie.\",\n\tnumber: \"Számnak kell lennie.\",\n\tdigits: \"Csak számjegyek lehetnek.\",\n\tequalTo: \"Meg kell egyeznie a két értéknek.\",\n\trange: $.validator.format(\"{0} és {1} közé kell esnie.\"),\n\tmax: $.validator.format(\"Nem lehet nagyobb, mint {0}.\"),\n\tmin: $.validator.format(\"Nem lehet kisebb, mint {0}.\"),\n\tcreditcard: \"Érvényes hitelkártyaszámnak kell lennie.\",\n\tremote: \"Kérem javítsa ki ezt a mezőt.\",\n\tdateISO: \"Kérem írjon be egy érvényes dátumot (ISO).\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_hy_AM.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: HY_AM (Armenian; հայերեն լեզու)\n */\n$.extend($.validator.messages, {\n\trequired: \"Պարտադիր լրացման դաշտ\",\n\tremote: \"Ներմուծեք ճիշտ արժեքը\",\n\temail: \"Ներմուծեք վավեր էլեկտրոնային փոստի հասցե\",\n\turl: \"Ներմուծեք վավեր URL\",\n\tdate: \"Ներմուծեք վավեր ամսաթիվ\",\n\tdateISO: \"Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։\",\n\tnumber: \"Ներմուծեք թիվ\",\n\tdigits: \"Ներմուծեք միայն թվեր\",\n\tcreditcard: \"Ներմուծեք ճիշտ բանկային քարտի համար\",\n\tequalTo: \"Ներմուծեք միևնուն արժեքը ևս մեկ անգամ\",\n\textension: \"Ընտրեք ճիշտ ընդլանումով ֆայլ\",\n\tmaxlength: $.validator.format(\"Ներմուծեք ոչ ավել քան {0} նիշ\"),\n\tminlength: $.validator.format(\"Ներմուծեք ոչ պակաս քան {0} նիշ\"),\n\trangelength: $.validator.format(\"Ներմուծեք {0}֊ից {1} երկարությամբ արժեք\"),\n\trange: $.validator.format(\"Ներմուծեք թիվ {0}֊ից {1} միջակայքում\"),\n\tmax: $.validator.format(\"Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին\"),\n\tmin: $.validator.format(\"Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_id.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ID (Indonesia; Indonesian)\n */\n$.extend($.validator.messages, {\n\trequired: \"Kolom ini diperlukan.\",\n\tremote: \"Harap benarkan kolom ini.\",\n\temail: \"Silakan masukkan format email yang benar.\",\n\turl: \"Silakan masukkan format URL yang benar.\",\n\tdate: \"Silakan masukkan format tanggal yang benar.\",\n\tdateISO: \"Silakan masukkan format tanggal(ISO) yang benar.\",\n\tnumber: \"Silakan masukkan angka yang benar.\",\n\tdigits: \"Harap masukan angka saja.\",\n\tcreditcard: \"Harap masukkan format kartu kredit yang benar.\",\n\tequalTo: \"Harap masukkan nilai yg sama dengan sebelumnya.\",\n\tmaxlength: $.validator.format(\"Input dibatasi hanya {0} karakter.\"),\n\tminlength: $.validator.format(\"Input tidak kurang dari {0} karakter.\"),\n\trangelength: $.validator.format(\"Panjang karakter yg diizinkan antara {0} dan {1} karakter.\"),\n\trange: $.validator.format(\"Harap masukkan nilai antara {0} dan {1}.\"),\n\tmax: $.validator.format(\"Harap masukkan nilai lebih kecil atau sama dengan {0}.\"),\n\tmin: $.validator.format(\"Harap masukkan nilai lebih besar atau sama dengan {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_is.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: IS (Icelandic; íslenska)\n */\n$.extend($.validator.messages, {\n\trequired: \"Þessi reitur er nauðsynlegur.\",\n\tremote: \"Lagaðu þennan reit.\",\n\tmaxlength: $.validator.format(\"Sláðu inn mest {0} stafi.\"),\n\tminlength: $.validator.format(\"Sláðu inn minnst {0} stafi.\"),\n\trangelength: $.validator.format(\"Sláðu inn minnst {0} og mest {1} stafi.\"),\n\temail: \"Sláðu inn gilt netfang.\",\n\turl: \"Sláðu inn gilda vefslóð.\",\n\tdate: \"Sláðu inn gilda dagsetningu.\",\n\tnumber: \"Sláðu inn tölu.\",\n\tdigits: \"Sláðu inn tölustafi eingöngu.\",\n\tequalTo: \"Sláðu sama gildi inn aftur.\",\n\trange: $.validator.format(\"Sláðu inn gildi milli {0} og {1}.\"),\n\tmax: $.validator.format(\"Sláðu inn gildi sem er minna en eða jafnt og {0}.\"),\n\tmin: $.validator.format(\"Sláðu inn gildi sem er stærra en eða jafnt og {0}.\"),\n\tcreditcard: \"Sláðu inn gilt greiðslukortanúmer.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_it.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: IT (Italian; Italiano)\n */\n$.extend($.validator.messages, {\n\trequired: \"Campo obbligatorio\",\n\tremote: \"Controlla questo campo\",\n\temail: \"Inserisci un indirizzo email valido\",\n\turl: \"Inserisci un indirizzo web valido\",\n\tdate: \"Inserisci una data valida\",\n\tdateISO: \"Inserisci una data valida (ISO)\",\n\tnumber: \"Inserisci un numero valido\",\n\tdigits: \"Inserisci solo numeri\",\n\tcreditcard: \"Inserisci un numero di carta di credito valido\",\n\tequalTo: \"Il valore non corrisponde\",\n\textension: \"Inserisci un valore con un&apos;estensione valida\",\n\tmaxlength: $.validator.format(\"Non inserire pi&ugrave; di {0} caratteri\"),\n\tminlength: $.validator.format(\"Inserisci almeno {0} caratteri\"),\n\trangelength: $.validator.format(\"Inserisci un valore compreso tra {0} e {1} caratteri\"),\n\trange: $.validator.format(\"Inserisci un valore compreso tra {0} e {1}\"),\n\tmax: $.validator.format(\"Inserisci un valore minore o uguale a {0}\"),\n\tmin: $.validator.format(\"Inserisci un valore maggiore o uguale a {0}\"),\n\tnifES: \"Inserisci un NIF valido\",\n\tnieES: \"Inserisci un NIE valido\",\n\tcifES: \"Inserisci un CIF valido\",\n\tcurrency: \"Inserisci una valuta valida\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ja.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: JA (Japanese; 日本語)\n */\n$.extend($.validator.messages, {\n\trequired: \"このフィールドは必須です。\",\n\tremote: \"このフィールドを修正してください。\",\n\temail: \"有効なEメールアドレスを入力してください。\",\n\turl: \"有効なURLを入力してください。\",\n\tdate: \"有効な日付を入力してください。\",\n\tdateISO: \"有効な日付（ISO）を入力してください。\",\n\tnumber: \"有効な数字を入力してください。\",\n\tdigits: \"数字のみを入力してください。\",\n\tcreditcard: \"有効なクレジットカード番号を入力してください。\",\n\tequalTo: \"同じ値をもう一度入力してください。\",\n\textension: \"有効な拡張子を含む値を入力してください。\",\n\tmaxlength: $.validator.format(\"{0} 文字以内で入力してください。\"),\n\tminlength: $.validator.format(\"{0} 文字以上で入力してください。\"),\n\trangelength: $.validator.format(\"{0} 文字から {1} 文字までの値を入力してください。\"),\n\trange: $.validator.format(\"{0} から {1} までの値を入力してください。\"),\n\tmax: $.validator.format(\"{0} 以下の値を入力してください。\"),\n\tmin: $.validator.format(\"{0} 以上の値を入力してください。\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ka.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: KA (Georgian; ქართული)\n */\n$.extend($.validator.messages, {\n\trequired: \"ამ ველის შევსება აუცილებელია.\",\n\tremote: \"გთხოვთ მიუთითოთ სწორი მნიშვნელობა.\",\n\temail: \"გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.\",\n\turl: \"გთხოვთ მიუთითოთ კორექტული URL.\",\n\tdate: \"გთხოვთ მიუთითოთ კორექტული თარიღი.\",\n\tdateISO: \"გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.\",\n\tnumber: \"გთხოვთ მიუთითოთ ციფრი.\",\n\tdigits: \"გთხოვთ მიუთითოთ მხოლოდ ციფრები.\",\n\tcreditcard: \"გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.\",\n\tequalTo: \"გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.\",\n\textension: \"გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.\",\n\tmaxlength: $.validator.format(\"დასაშვებია არაუმეტეს {0} სიმბოლო.\"),\n\tminlength: $.validator.format(\"აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო.\"),\n\trangelength: $.validator.format(\"ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე.\"),\n\trange: $.validator.format(\"გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე.\"),\n\tmax: $.validator.format(\"გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს.\"),\n\tmin: $.validator.format(\"გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_kk.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: KK (Kazakh; қазақ тілі)\n */\n$.extend($.validator.messages, {\n\trequired: \"Бұл өрісті міндетті түрде толтырыңыз.\",\n\tremote: \"Дұрыс мағына енгізуіңізді сұраймыз.\",\n\temail: \"Нақты электронды поштаңызды енгізуіңізді сұраймыз.\",\n\turl: \"Нақты URL-ды енгізуіңізді сұраймыз.\",\n\tdate: \"Нақты URL-ды енгізуіңізді сұраймыз.\",\n\tdateISO: \"Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.\",\n\tnumber: \"Күнді енгізуіңізді сұраймыз.\",\n\tdigits: \"Тек қана сандарды енгізуіңізді сұраймыз.\",\n\tcreditcard: \"Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.\",\n\tequalTo: \"Осы мәнді қайта енгізуіңізді сұраймыз.\",\n\textension: \"Файлдың кеңейтуін дұрыс таңдаңыз.\",\n\tmaxlength: $.validator.format(\"Ұзындығы {0} символдан көр болмасын.\"),\n\tminlength: $.validator.format(\"Ұзындығы {0} символдан аз болмасын.\"),\n\trangelength: $.validator.format(\"Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз.\"),\n\trange: $.validator.format(\"Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз.\"),\n\tmax: $.validator.format(\"{0} аз немесе тең санын енгізуіңіді сұраймыз.\"),\n\tmin: $.validator.format(\"{0} көп немесе тең санын енгізуіңізді сұраймыз.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ko.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: KO (Korean; 한국어)\n */\n$.extend($.validator.messages, {\n\trequired: \"필수 항목입니다.\",\n\tremote: \"항목을 수정하세요.\",\n\temail: \"유효하지 않은 E-Mail주소입니다.\",\n\turl: \"유효하지 않은 URL입니다.\",\n\tdate: \"올바른 날짜를 입력하세요.\",\n\tdateISO: \"올바른 날짜(ISO)를 입력하세요.\",\n\tnumber: \"유효한 숫자가 아닙니다.\",\n\tdigits: \"숫자만 입력 가능합니다.\",\n\tcreditcard: \"신용카드 번호가 바르지 않습니다.\",\n\tequalTo: \"같은 값을 다시 입력하세요.\",\n\textension: \"올바른 확장자가 아닙니다.\",\n\tmaxlength: $.validator.format(\"{0}자를 넘을 수 없습니다. \"),\n\tminlength: $.validator.format(\"{0}자 이상 입력하세요.\"),\n\trangelength: $.validator.format(\"문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요.\"),\n\trange: $.validator.format(\"{0} 에서 {1} 사이의 값을 입력하세요.\"),\n\tmax: $.validator.format(\"{0} 이하의 값을 입력하세요.\"),\n\tmin: $.validator.format(\"{0} 이상의 값을 입력하세요.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_lt.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: LT (Lithuanian; lietuvių kalba)\n */\n$.extend($.validator.messages, {\n\trequired: \"Šis laukas yra privalomas.\",\n\tremote: \"Prašau pataisyti šį lauką.\",\n\temail: \"Prašau įvesti teisingą elektroninio pašto adresą.\",\n\turl: \"Prašau įvesti teisingą URL.\",\n\tdate: \"Prašau įvesti teisingą datą.\",\n\tdateISO: \"Prašau įvesti teisingą datą (ISO).\",\n\tnumber: \"Prašau įvesti teisingą skaičių.\",\n\tdigits: \"Prašau naudoti tik skaitmenis.\",\n\tcreditcard: \"Prašau įvesti teisingą kreditinės kortelės numerį.\",\n\tequalTo: \"Prašau įvestį tą pačią reikšmę dar kartą.\",\n\textension: \"Prašau įvesti reikšmę su teisingu plėtiniu.\",\n\tmaxlength: $.validator.format(\"Prašau įvesti ne daugiau kaip {0} simbolių.\"),\n\tminlength: $.validator.format(\"Prašau įvesti bent {0} simbolius.\"),\n\trangelength: $.validator.format(\"Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių.\"),\n\trange: $.validator.format(\"Prašau įvesti reikšmę intervale nuo {0} iki {1}.\"),\n\tmax: $.validator.format(\"Prašau įvesti reikšmę mažesnę arba lygią {0}.\"),\n\tmin: $.validator.format(\"Prašau įvesti reikšmę didesnę arba lygią {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_lv.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: LV (Latvian; latviešu valoda)\n */\n$.extend($.validator.messages, {\n\trequired: \"Šis lauks ir obligāts.\",\n\tremote: \"Lūdzu, pārbaudiet šo lauku.\",\n\temail: \"Lūdzu, ievadiet derīgu e-pasta adresi.\",\n\turl: \"Lūdzu, ievadiet derīgu URL adresi.\",\n\tdate: \"Lūdzu, ievadiet derīgu datumu.\",\n\tdateISO: \"Lūdzu, ievadiet derīgu datumu (ISO).\",\n\tnumber: \"Lūdzu, ievadiet derīgu numuru.\",\n\tdigits: \"Lūdzu, ievadiet tikai ciparus.\",\n\tcreditcard: \"Lūdzu, ievadiet derīgu kredītkartes numuru.\",\n\tequalTo: \"Lūdzu, ievadiet to pašu vēlreiz.\",\n\textension: \"Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.\",\n\tmaxlength: $.validator.format(\"Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes.\"),\n\tminlength: $.validator.format(\"Lūdzu, ievadiet vismaz {0} rakstzīmes.\"),\n\trangelength: $.validator.format(\"Lūdzu ievadiet {0} līdz {1} rakstzīmes.\"),\n\trange: $.validator.format(\"Lūdzu, ievadiet skaitli no {0} līdz {1}.\"),\n\tmax: $.validator.format(\"Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}.\"),\n\tmin: $.validator.format(\"Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_my.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: MY (Malay; Melayu)\n */\n$.extend($.validator.messages, {\n\trequired: \"Medan ini diperlukan.\",\n\tremote: \"Sila betulkan medan ini.\",\n\temail: \"Sila masukkan alamat emel yang betul.\",\n\turl: \"Sila masukkan URL yang betul.\",\n\tdate: \"Sila masukkan tarikh yang betul.\",\n\tdateISO: \"Sila masukkan tarikh(ISO) yang betul.\",\n\tnumber: \"Sila masukkan nombor yang betul.\",\n\tdigits: \"Sila masukkan nilai digit sahaja.\",\n\tcreditcard: \"Sila masukkan nombor kredit kad yang betul.\",\n\tequalTo: \"Sila masukkan nilai yang sama semula.\",\n\textension: \"Sila masukkan nilai yang telah diterima.\",\n\tmaxlength: $.validator.format(\"Sila masukkan nilai tidak lebih dari {0} aksara.\"),\n\tminlength: $.validator.format(\"Sila masukkan nilai sekurang-kurangnya {0} aksara.\"),\n\trangelength: $.validator.format(\"Sila masukkan panjang nilai antara {0} dan {1} aksara.\"),\n\trange: $.validator.format(\"Sila masukkan nilai antara {0} dan {1} aksara.\"),\n\tmax: $.validator.format(\"Sila masukkan nilai yang kurang atau sama dengan {0}.\"),\n\tmin: $.validator.format(\"Sila masukkan nilai yang lebih atau sama dengan {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_nl.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: NL (Dutch; Nederlands, Vlaams)\n */\n$.extend($.validator.messages, {\n\trequired: \"Dit is een verplicht veld.\",\n\tremote: \"Controleer dit veld.\",\n\temail: \"Vul hier een geldig e-mailadres in.\",\n\turl: \"Vul hier een geldige URL in.\",\n\tdate: \"Vul hier een geldige datum in.\",\n\tdateISO: \"Vul hier een geldige datum in (ISO-formaat).\",\n\tnumber: \"Vul hier een geldig getal in.\",\n\tdigits: \"Vul hier alleen getallen in.\",\n\tcreditcard: \"Vul hier een geldig creditcardnummer in.\",\n\tequalTo: \"Vul hier dezelfde waarde in.\",\n\textension: \"Vul hier een waarde in met een geldige extensie.\",\n\tmaxlength: $.validator.format(\"Vul hier maximaal {0} tekens in.\"),\n\tminlength: $.validator.format(\"Vul hier minimaal {0} tekens in.\"),\n\trangelength: $.validator.format(\"Vul hier een waarde in van minimaal {0} en maximaal {1} tekens.\"),\n\trange: $.validator.format(\"Vul hier een waarde in van minimaal {0} en maximaal {1}.\"),\n\tmax: $.validator.format(\"Vul hier een waarde in kleiner dan of gelijk aan {0}.\"),\n\tmin: $.validator.format(\"Vul hier een waarde in groter dan of gelijk aan {0}.\"),\n\n\t// for validations in additional-methods.js\n\tiban: \"Vul hier een geldig IBAN in.\",\n\tdateNL: \"Vul hier een geldige datum in.\",\n\tphoneNL: \"Vul hier een geldig Nederlands telefoonnummer in.\",\n\tmobileNL: \"Vul hier een geldig Nederlands mobiel telefoonnummer in.\",\n\tpostalcodeNL: \"Vul hier een geldige postcode in.\",\n\tbankaccountNL: \"Vul hier een geldig bankrekeningnummer in.\",\n\tgiroaccountNL: \"Vul hier een geldig gironummer in.\",\n\tbankorgiroaccountNL: \"Vul hier een geldig bank- of gironummer in.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_no.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: NO (Norwegian; Norsk)\n */\n$.extend($.validator.messages, {\n\trequired: \"Dette feltet er obligatorisk.\",\n\tmaxlength: $.validator.format(\"Maksimalt {0} tegn.\"),\n\tminlength: $.validator.format(\"Minimum {0} tegn.\"),\n\trangelength: $.validator.format(\"Angi minimum {0} og maksimum {1} tegn.\"),\n\temail: \"Oppgi en gyldig epostadresse.\",\n\turl: \"Angi en gyldig URL.\",\n\tdate: \"Angi en gyldig dato.\",\n\tdateISO: \"Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).\",\n\tdateSE: \"Angi en gyldig dato.\",\n\tnumber: \"Angi et gyldig nummer.\",\n\tnumberSE: \"Angi et gyldig nummer.\",\n\tdigits: \"Skriv kun tall.\",\n\tequalTo: \"Skriv samme verdi igjen.\",\n\trange: $.validator.format(\"Angi en verdi mellom {0} og {1}.\"),\n\tmax: $.validator.format(\"Angi en verdi som er mindre eller lik {0}.\"),\n\tmin: $.validator.format(\"Angi en verdi som er st&oslash;rre eller lik {0}.\"),\n\tcreditcard: \"Angi et gyldig kredittkortnummer.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_pl.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: PL (Polish; język polski, polszczyzna)\n */\n$.extend($.validator.messages, {\n\trequired: \"To pole jest wymagane.\",\n\tremote: \"Proszę o wypełnienie tego pola.\",\n\temail: \"Proszę o podanie prawidłowego adresu email.\",\n\turl: \"Proszę o podanie prawidłowego URL.\",\n\tdate: \"Proszę o podanie prawidłowej daty.\",\n\tdateISO: \"Proszę o podanie prawidłowej daty (ISO).\",\n\tnumber: \"Proszę o podanie prawidłowej liczby.\",\n\tdigits: \"Proszę o podanie samych cyfr.\",\n\tcreditcard: \"Proszę o podanie prawidłowej karty kredytowej.\",\n\tequalTo: \"Proszę o podanie tej samej wartości ponownie.\",\n\textension: \"Proszę o podanie wartości z prawidłowym rozszerzeniem.\",\n\tmaxlength: $.validator.format(\"Proszę o podanie nie więcej niż {0} znaków.\"),\n\tminlength: $.validator.format(\"Proszę o podanie przynajmniej {0} znaków.\"),\n\trangelength: $.validator.format(\"Proszę o podanie wartości o długości od {0} do {1} znaków.\"),\n\trange: $.validator.format(\"Proszę o podanie wartości z przedziału od {0} do {1}.\"),\n\tmax: $.validator.format(\"Proszę o podanie wartości mniejszej bądź równej {0}.\"),\n\tmin: $.validator.format(\"Proszę o podanie wartości większej bądź równej {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_pt_BR.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: PT (Portuguese; português)\n * Region: BR (Brazil)\n */\n$.extend($.validator.messages, {\n\trequired: \"Este campo &eacute; requerido.\",\n\tremote: \"Por favor, corrija este campo.\",\n\temail: \"Por favor, forne&ccedil;a um endere&ccedil;o de email v&aacute;lido.\",\n\turl: \"Por favor, forne&ccedil;a uma URL v&aacute;lida.\",\n\tdate: \"Por favor, forne&ccedil;a uma data v&aacute;lida.\",\n\tdateISO: \"Por favor, forne&ccedil;a uma data v&aacute;lida (ISO).\",\n\tnumber: \"Por favor, forne&ccedil;a um n&uacute;mero v&aacute;lido.\",\n\tdigits: \"Por favor, forne&ccedil;a somente d&iacute;gitos.\",\n\tcreditcard: \"Por favor, forne&ccedil;a um cart&atilde;o de cr&eacute;dito v&aacute;lido.\",\n\tequalTo: \"Por favor, forne&ccedil;a o mesmo valor novamente.\",\n\textension: \"Por favor, forne&ccedil;a um valor com uma extens&atilde;o v&aacute;lida.\",\n\tmaxlength: $.validator.format(\"Por favor, forne&ccedil;a n&atilde;o mais que {0} caracteres.\"),\n\tminlength: $.validator.format(\"Por favor, forne&ccedil;a ao menos {0} caracteres.\"),\n\trangelength: $.validator.format(\"Por favor, forne&ccedil;a um valor entre {0} e {1} caracteres de comprimento.\"),\n\trange: $.validator.format(\"Por favor, forne&ccedil;a um valor entre {0} e {1}.\"),\n\tmax: $.validator.format(\"Por favor, forne&ccedil;a um valor menor ou igual a {0}.\"),\n\tmin: $.validator.format(\"Por favor, forne&ccedil;a um valor maior ou igual a {0}.\"),\n\tnifES: \"Por favor, forne&ccedil;a um NIF v&aacute;lido.\",\n\tnieES: \"Por favor, forne&ccedil;a um NIE v&aacute;lido.\",\n\tcifEE: \"Por favor, forne&ccedil;a um CIF v&aacute;lido.\",\n\tpostalcodeBR: \"Por favor, forne&ccedil;a um CEP v&aacute;lido.\",\n\tcpfBR: \"Por favor, forne&ccedil;a um CPF v&aacute;lido.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_pt_PT.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: PT (Portuguese; português)\n * Region: PT (Portugal)\n */\n$.extend($.validator.messages, {\n\trequired: \"Campo de preenchimento obrigat&oacute;rio.\",\n\tremote: \"Por favor, corrija este campo.\",\n\temail: \"Por favor, introduza um endere&ccedil;o eletr&oacute;nico v&aacute;lido.\",\n\turl: \"Por favor, introduza um URL v&aacute;lido.\",\n\tdate: \"Por favor, introduza uma data v&aacute;lida.\",\n\tdateISO: \"Por favor, introduza uma data v&aacute;lida (ISO).\",\n\tnumber: \"Por favor, introduza um n&uacute;mero v&aacute;lido.\",\n\tdigits: \"Por favor, introduza apenas d&iacute;gitos.\",\n\tcreditcard: \"Por favor, introduza um n&uacute;mero de cart&atilde;o de cr&eacute;dito v&aacute;lido.\",\n\tequalTo: \"Por favor, introduza de novo o mesmo valor.\",\n\textension: \"Por favor, introduza um ficheiro com uma extens&atilde;o v&aacute;lida.\",\n\tmaxlength: $.validator.format(\"Por favor, n&atilde;o introduza mais do que {0} caracteres.\"),\n\tminlength: $.validator.format(\"Por favor, introduza pelo menos {0} caracteres.\"),\n\trangelength: $.validator.format(\"Por favor, introduza entre {0} e {1} caracteres.\"),\n\trange: $.validator.format(\"Por favor, introduza um valor entre {0} e {1}.\"),\n\tmax: $.validator.format(\"Por favor, introduza um valor menor ou igual a {0}.\"),\n\tmin: $.validator.format(\"Por favor, introduza um valor maior ou igual a {0}.\"),\n\tnifES: \"Por favor, introduza um NIF v&aacute;lido.\",\n\tnieES: \"Por favor, introduza um NIE v&aacute;lido.\",\n\tcifES: \"Por favor, introduza um CIF v&aacute;lido.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ro.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: RO (Romanian, limba română)\n */\n$.extend($.validator.messages, {\n\trequired: \"Acest câmp este obligatoriu.\",\n\tremote: \"Te rugăm să completezi acest câmp.\",\n\temail: \"Te rugăm să introduci o adresă de email validă\",\n\turl: \"Te rugăm sa introduci o adresă URL validă.\",\n\tdate: \"Te rugăm să introduci o dată corectă.\",\n\tdateISO: \"Te rugăm să introduci o dată (ISO) corectă.\",\n\tnumber: \"Te rugăm să introduci un număr întreg valid.\",\n\tdigits: \"Te rugăm să introduci doar cifre.\",\n\tcreditcard: \"Te rugăm să introduci un numar de carte de credit valid.\",\n\tequalTo: \"Te rugăm să reintroduci valoarea.\",\n\textension: \"Te rugăm să introduci o valoare cu o extensie validă.\",\n\tmaxlength: $.validator.format(\"Te rugăm să nu introduci mai mult de {0} caractere.\"),\n\tminlength: $.validator.format(\"Te rugăm să introduci cel puțin {0} caractere.\"),\n\trangelength: $.validator.format(\"Te rugăm să introduci o valoare între {0} și {1} caractere.\"),\n\trange: $.validator.format(\"Te rugăm să introduci o valoare între {0} și {1}.\"),\n\tmax: $.validator.format(\"Te rugăm să introduci o valoare egal sau mai mică decât {0}.\"),\n\tmin: $.validator.format(\"Te rugăm să introduci o valoare egal sau mai mare decât {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_ru.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: RU (Russian; русский язык)\n */\n$.extend($.validator.messages, {\n\trequired: \"Это поле необходимо заполнить.\",\n\tremote: \"Пожалуйста, введите правильное значение.\",\n\temail: \"Пожалуйста, введите корректный адрес электронной почты.\",\n\turl: \"Пожалуйста, введите корректный URL.\",\n\tdate: \"Пожалуйста, введите корректную дату.\",\n\tdateISO: \"Пожалуйста, введите корректную дату в формате ISO.\",\n\tnumber: \"Пожалуйста, введите число.\",\n\tdigits: \"Пожалуйста, вводите только цифры.\",\n\tcreditcard: \"Пожалуйста, введите правильный номер кредитной карты.\",\n\tequalTo: \"Пожалуйста, введите такое же значение ещё раз.\",\n\textension: \"Пожалуйста, выберите файл с правильным расширением.\",\n\tmaxlength: $.validator.format(\"Пожалуйста, введите не больше {0} символов.\"),\n\tminlength: $.validator.format(\"Пожалуйста, введите не меньше {0} символов.\"),\n\trangelength: $.validator.format(\"Пожалуйста, введите значение длиной от {0} до {1} символов.\"),\n\trange: $.validator.format(\"Пожалуйста, введите число от {0} до {1}.\"),\n\tmax: $.validator.format(\"Пожалуйста, введите число, меньшее или равное {0}.\"),\n\tmin: $.validator.format(\"Пожалуйста, введите число, большее или равное {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_si.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: SI (Slovenian)\n */\n$.extend($.validator.messages, {\n\trequired: \"To polje je obvezno.\",\n\tremote: \"Vpis v tem polju ni v pravi obliki.\",\n\temail: \"Prosimo, vnesite pravi email naslov.\",\n\turl: \"Prosimo, vnesite pravi URL.\",\n\tdate: \"Prosimo, vnesite pravi datum.\",\n\tdateISO: \"Prosimo, vnesite pravi datum (ISO).\",\n\tnumber: \"Prosimo, vnesite pravo številko.\",\n\tdigits: \"Prosimo, vnesite samo številke.\",\n\tcreditcard: \"Prosimo, vnesite pravo številko kreditne kartice.\",\n\tequalTo: \"Prosimo, ponovno vnesite enako vsebino.\",\n\textension: \"Prosimo, vnesite vsebino z pravo končnico.\",\n\tmaxlength: $.validator.format(\"Prosimo, da ne vnašate več kot {0} znakov.\"),\n\tminlength: $.validator.format(\"Prosimo, vnesite vsaj {0} znakov.\"),\n\trangelength: $.validator.format(\"Prosimo, vnesite od {0} do {1} znakov.\"),\n\trange: $.validator.format(\"Prosimo, vnesite vrednost med {0} in {1}.\"),\n\tmax: $.validator.format(\"Prosimo, vnesite vrednost manjšo ali enako {0}.\"),\n\tmin: $.validator.format(\"Prosimo, vnesite vrednost večjo ali enako {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_sk.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: SK (Slovak; slovenčina, slovenský jazyk)\n */\n$.extend($.validator.messages, {\n\trequired: \"Povinné zadať.\",\n\tmaxlength: $.validator.format(\"Maximálne {0} znakov.\"),\n\tminlength: $.validator.format(\"Minimálne {0} znakov.\"),\n\trangelength: $.validator.format(\"Minimálne {0} a Maximálne {1} znakov.\"),\n\temail: \"E-mailová adresa musí byť platná.\",\n\turl: \"URL musí byť platný.\",\n\tdate: \"Musí byť dátum.\",\n\tnumber: \"Musí byť číslo.\",\n\tdigits: \"Môže obsahovať iba číslice.\",\n\tequalTo: \"Dva hodnoty sa musia rovnať.\",\n\trange: $.validator.format(\"Musí byť medzi {0} a {1}.\"),\n\tmax: $.validator.format(\"Nemôže byť viac ako{0}.\"),\n\tmin: $.validator.format(\"Nemôže byť menej ako{0}.\"),\n\tcreditcard: \"Číslo platobnej karty musí byť platné.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_sl.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Language: SL (Slovenian; slovenski jezik)\n */\n$.extend($.validator.messages, {\n\trequired: \"To polje je obvezno.\",\n\tremote: \"Prosimo popravite to polje.\",\n\temail: \"Prosimo vnesite veljaven email naslov.\",\n\turl: \"Prosimo vnesite veljaven URL naslov.\",\n\tdate: \"Prosimo vnesite veljaven datum.\",\n\tdateISO: \"Prosimo vnesite veljaven ISO datum.\",\n\tnumber: \"Prosimo vnesite veljavno število.\",\n\tdigits: \"Prosimo vnesite samo števila.\",\n\tcreditcard: \"Prosimo vnesite veljavno številko kreditne kartice.\",\n\tequalTo: \"Prosimo ponovno vnesite vrednost.\",\n\textension: \"Prosimo vnesite vrednost z veljavno končnico.\",\n\tmaxlength: $.validator.format(\"Prosimo vnesite največ {0} znakov.\"),\n\tminlength: $.validator.format(\"Prosimo vnesite najmanj {0} znakov.\"),\n\trangelength: $.validator.format(\"Prosimo vnesite najmanj {0} in največ {1} znakov.\"),\n\trange: $.validator.format(\"Prosimo vnesite vrednost med {0} in {1}.\"),\n\tmax: $.validator.format(\"Prosimo vnesite vrednost manjše ali enako {0}.\"),\n\tmin: $.validator.format(\"Prosimo vnesite vrednost večje ali enako {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_sr.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: SR (Serbian; српски језик)\n */\n$.extend($.validator.messages, {\n\trequired: \"Поље је обавезно.\",\n\tremote: \"Средите ово поље.\",\n\temail: \"Унесите исправну и-мејл адресу.\",\n\turl: \"Унесите исправан URL.\",\n\tdate: \"Унесите исправан датум.\",\n\tdateISO: \"Унесите исправан датум (ISO).\",\n\tnumber: \"Унесите исправан број.\",\n\tdigits: \"Унесите само цифе.\",\n\tcreditcard: \"Унесите исправан број кредитне картице.\",\n\tequalTo: \"Унесите исту вредност поново.\",\n\textension: \"Унесите вредност са одговарајућом екстензијом.\",\n\tmaxlength: $.validator.format(\"Унесите мање од {0} карактера.\"),\n\tminlength: $.validator.format(\"Унесите барем {0} карактера.\"),\n\trangelength: $.validator.format(\"Унесите вредност дугачку између {0} и {1} карактера.\"),\n\trange: $.validator.format(\"Унесите вредност између {0} и {1}.\"),\n\tmax: $.validator.format(\"Унесите вредност мању или једнаку {0}.\"),\n\tmin: $.validator.format(\"Унесите вредност већу или једнаку {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_sr_lat.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: SR (Serbian - Latin alphabet; srpski jezik - latinica)\n */\n$.extend($.validator.messages, {\n\trequired: \"Polje je obavezno.\",\n\tremote: \"Sredite ovo polje.\",\n\temail: \"Unesite ispravnu e-mail adresu\",\n\turl: \"Unesite ispravan URL.\",\n\tdate: \"Unesite ispravan datum.\",\n\tdateISO: \"Unesite ispravan datum (ISO).\",\n\tnumber: \"Unesite ispravan broj.\",\n\tdigits: \"Unesite samo cifre.\",\n\tcreditcard: \"Unesite ispravan broj kreditne kartice.\",\n\tequalTo: \"Unesite istu vrednost ponovo.\",\n\textension: \"Unesite vrednost sa odgovarajućom ekstenzijom.\",\n\tmaxlength: $.validator.format(\"Unesite manje od {0} karaktera.\"),\n\tminlength: $.validator.format(\"Unesite barem {0} karaktera.\"),\n\trangelength: $.validator.format(\"Unesite vrednost dugačku između {0} i {1} karaktera.\"),\n\trange: $.validator.format(\"Unesite vrednost između {0} i {1}.\"),\n\tmax: $.validator.format(\"Unesite vrednost manju ili jednaku {0}.\"),\n\tmin: $.validator.format(\"Unesite vrednost veću ili jednaku {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_sv.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: SV (Swedish; Svenska)\n */\n$.extend($.validator.messages, {\n\trequired: \"Detta f&auml;lt &auml;r obligatoriskt.\",\n\tmaxlength: $.validator.format(\"Du f&aring;r ange h&ouml;gst {0} tecken.\"),\n\tminlength: $.validator.format(\"Du m&aring;ste ange minst {0} tecken.\"),\n\trangelength: $.validator.format(\"Ange minst {0} och max {1} tecken.\"),\n\temail: \"Ange en korrekt e-postadress.\",\n\turl: \"Ange en korrekt URL.\",\n\tdate: \"Ange ett korrekt datum.\",\n\tdateISO: \"Ange ett korrekt datum (&Aring;&Aring;&Aring;&Aring;-MM-DD).\",\n\tnumber: \"Ange ett korrekt nummer.\",\n\tdigits: \"Ange endast siffror.\",\n\tequalTo: \"Ange samma v&auml;rde igen.\",\n\trange: $.validator.format(\"Ange ett v&auml;rde mellan {0} och {1}.\"),\n\tmax: $.validator.format(\"Ange ett v&auml;rde som &auml;r mindre eller lika med {0}.\"),\n\tmin: $.validator.format(\"Ange ett v&auml;rde som &auml;r st&ouml;rre eller lika med {0}.\"),\n\tcreditcard: \"Ange ett korrekt kreditkortsnummer.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_th.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: TH (Thai; ไทย)\n */\n$.extend($.validator.messages, {\n\trequired: \"โปรดระบุ\",\n\tremote: \"โปรดแก้ไขให้ถูกต้อง\",\n\temail: \"โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง\",\n\turl: \"โปรดระบุ URL ที่ถูกต้อง\",\n\tdate: \"โปรดระบุวันที่ ที่ถูกต้อง\",\n\tdateISO: \"โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).\",\n\tnumber: \"โปรดระบุทศนิยมที่ถูกต้อง\",\n\tdigits: \"โปรดระบุจำนวนเต็มที่ถูกต้อง\",\n\tcreditcard: \"โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง\",\n\tequalTo: \"โปรดระบุค่าเดิมอีกครั้ง\",\n\textension: \"โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง\",\n\tmaxlength: $.validator.format(\"โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ\"),\n\tminlength: $.validator.format(\"โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ\"),\n\trangelength: $.validator.format(\"โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ\"),\n\trange: $.validator.format(\"โปรดระบุค่าระหว่าง {0} และ {1}\"),\n\tmax: $.validator.format(\"โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}\"),\n\tmin: $.validator.format(\"โปรดระบุค่ามากกว่าหรือเท่ากับ {0}\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_tj.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: TJ (Tajikistan; Забони тоҷикӣ)\n */\n$.extend($.validator.messages, {\n\trequired: \"Ворид кардани ин филд маҷбури аст.\",\n\tremote: \"Илтимос, маълумоти саҳеҳ ворид кунед.\",\n\temail: \"Илтимос, почтаи электронии саҳеҳ ворид кунед.\",\n\turl: \"Илтимос, URL адреси саҳеҳ ворид кунед.\",\n\tdate: \"Илтимос, таърихи саҳеҳ ворид кунед.\",\n\tdateISO: \"Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.\",\n\tnumber: \"Илтимос, рақамҳои саҳеҳ ворид кунед.\",\n\tdigits: \"Илтимос, танҳо рақам ворид кунед.\",\n\tcreditcard: \"Илтимос, кредит карди саҳеҳ ворид кунед.\",\n\tequalTo: \"Илтимос, миқдори баробар ворид кунед.\",\n\textension: \"Илтимос, қофияи файлро дуруст интихоб кунед\",\n\tmaxlength: $.validator.format(\"Илтимос, бештар аз {0} рамз ворид накунед.\"),\n\tminlength: $.validator.format(\"Илтимос, камтар аз {0} рамз ворид накунед.\"),\n\trangelength: $.validator.format(\"Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед.\"),\n\trange: $.validator.format(\"Илтимос, аз {0} то {1} рақам зиёд ворид кунед.\"),\n\tmax: $.validator.format(\"Илтимос, бештар аз {0} рақам ворид накунед.\"),\n\tmin: $.validator.format(\"Илтимос, камтар аз {0} рақам ворид накунед.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_tr.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: TR (Turkish; Türkçe)\n */\n$.extend($.validator.messages, {\n\trequired: \"Bu alanın doldurulması zorunludur.\",\n\tremote: \"Lütfen bu alanı düzeltin.\",\n\temail: \"Lütfen geçerli bir e-posta adresi giriniz.\",\n\turl: \"Lütfen geçerli bir web adresi (URL) giriniz.\",\n\tdate: \"Lütfen geçerli bir tarih giriniz.\",\n\tdateISO: \"Lütfen geçerli bir tarih giriniz(ISO formatında)\",\n\tnumber: \"Lütfen geçerli bir sayı giriniz.\",\n\tdigits: \"Lütfen sadece sayısal karakterler giriniz.\",\n\tcreditcard: \"Lütfen geçerli bir kredi kartı giriniz.\",\n\tequalTo: \"Lütfen aynı değeri tekrar giriniz.\",\n\textension: \"Lütfen geçerli uzantıya sahip bir değer giriniz.\",\n\tmaxlength: $.validator.format(\"Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz.\"),\n\tminlength: $.validator.format(\"Lütfen en az {0} karakter uzunluğunda bir değer giriniz.\"),\n\trangelength: $.validator.format(\"Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz.\"),\n\trange: $.validator.format(\"Lütfen {0} ile {1} arasında bir değer giriniz.\"),\n\tmax: $.validator.format(\"Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz.\"),\n\tmin: $.validator.format(\"Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz.\"),\n\trequire_from_group: \"Lütfen bu alanların en az {0} tanesini doldurunuz.\"\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_uk.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: UK (Ukrainian; українська мова)\n */\n$.extend($.validator.messages, {\n\trequired: \"Це поле необхідно заповнити.\",\n\tremote: \"Будь ласка, введіть правильне значення.\",\n\temail: \"Будь ласка, введіть коректну адресу електронної пошти.\",\n\turl: \"Будь ласка, введіть коректний URL.\",\n\tdate: \"Будь ласка, введіть коректну дату.\",\n\tdateISO: \"Будь ласка, введіть коректну дату у форматі ISO.\",\n\tnumber: \"Будь ласка, введіть число.\",\n\tdigits: \"Вводите потрібно лише цифри.\",\n\tcreditcard: \"Будь ласка, введіть правильний номер кредитної карти.\",\n\tequalTo: \"Будь ласка, введіть таке ж значення ще раз.\",\n\textension: \"Будь ласка, виберіть файл з правильним розширенням.\",\n\tmaxlength: $.validator.format(\"Будь ласка, введіть не більше {0} символів.\"),\n\tminlength: $.validator.format(\"Будь ласка, введіть не менше {0} символів.\"),\n\trangelength: $.validator.format(\"Будь ласка, введіть значення довжиною від {0} до {1} символів.\"),\n\trange: $.validator.format(\"Будь ласка, введіть число від {0} до {1}.\"),\n\tmax: $.validator.format(\"Будь ласка, введіть число, менше або рівно {0}.\"),\n\tmin: $.validator.format(\"Будь ласка, введіть число, більше або рівно {0}.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_vi.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: VI (Vietnamese; Tiếng Việt)\n */\n$.extend($.validator.messages, {\n\trequired: \"Hãy nhập.\",\n\tremote: \"Hãy sửa cho đúng.\",\n\temail: \"Hãy nhập email.\",\n\turl: \"Hãy nhập URL.\",\n\tdate: \"Hãy nhập ngày.\",\n\tdateISO: \"Hãy nhập ngày (ISO).\",\n\tnumber: \"Hãy nhập số.\",\n\tdigits: \"Hãy nhập chữ số.\",\n\tcreditcard: \"Hãy nhập số thẻ tín dụng.\",\n\tequalTo: \"Hãy nhập thêm lần nữa.\",\n\textension: \"Phần mở rộng không đúng.\",\n\tmaxlength: $.validator.format(\"Hãy nhập từ {0} kí tự trở xuống.\"),\n\tminlength: $.validator.format(\"Hãy nhập từ {0} kí tự trở lên.\"),\n\trangelength: $.validator.format(\"Hãy nhập từ {0} đến {1} kí tự.\"),\n\trange: $.validator.format(\"Hãy nhập từ {0} đến {1}.\"),\n\tmax: $.validator.format(\"Hãy nhập từ {0} trở xuống.\"),\n\tmin: $.validator.format(\"Hãy nhập từ {1} trở lên.\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_zh.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ZH (Chinese, 中文 (Zhōngwén), 汉语, 漢語)\n */\n$.extend($.validator.messages, {\n\trequired: \"这是必填字段\",\n\tremote: \"请修正此字段\",\n\temail: \"请输入有效的电子邮件地址\",\n\turl: \"请输入有效的网址\",\n\tdate: \"请输入有效的日期\",\n\tdateISO: \"请输入有效的日期 (YYYY-MM-DD)\",\n\tnumber: \"请输入有效的数字\",\n\tdigits: \"只能输入数字\",\n\tcreditcard: \"请输入有效的信用卡号码\",\n\tequalTo: \"你的输入不相同\",\n\textension: \"请输入有效的后缀\",\n\tmaxlength: $.validator.format(\"最多可以输入 {0} 个字符\"),\n\tminlength: $.validator.format(\"最少要输入 {0} 个字符\"),\n\trangelength: $.validator.format(\"请输入长度在 {0} 到 {1} 之间的字符串\"),\n\trange: $.validator.format(\"请输入范围在 {0} 到 {1} 之间的数值\"),\n\tmax: $.validator.format(\"请输入不大于 {0} 的数值\"),\n\tmin: $.validator.format(\"请输入不小于 {0} 的数值\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/messages_zh_TW.js",
    "content": "/*\n * Translated default messages for the jQuery validation plugin.\n * Locale: ZH (Chinese; 中文 (Zhōngwén), 汉语, 漢語)\n * Region: TW (Taiwan)\n */\n$.extend($.validator.messages, {\n\trequired: \"必須填寫\",\n\tremote: \"請修正此欄位\",\n\temail: \"請輸入有效的電子郵件\",\n\turl: \"請輸入有效的網址\",\n\tdate: \"請輸入有效的日期\",\n\tdateISO: \"請輸入有效的日期 (YYYY-MM-DD)\",\n\tnumber: \"請輸入正確的數值\",\n\tdigits: \"只可輸入數字\",\n\tcreditcard: \"請輸入有效的信用卡號碼\",\n\tequalTo: \"請重複輸入一次\",\n\textension: \"請輸入有效的後綴\",\n\tmaxlength: $.validator.format(\"最多 {0} 個字\"),\n\tminlength: $.validator.format(\"最少 {0} 個字\"),\n\trangelength: $.validator.format(\"請輸入長度為 {0} 至 {1} 之間的字串\"),\n\trange: $.validator.format(\"請輸入 {0} 至 {1} 之間的數值\"),\n\tmax: $.validator.format(\"請輸入不大於 {0} 的數值\"),\n\tmin: $.validator.format(\"請輸入不小於 {0} 的數值\")\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/methods_de.js",
    "content": "/*\n * Localized default methods for the jQuery validation plugin.\n * Locale: DE\n */\n$.extend($.validator.methods, {\n\tdate: function(value, element) {\n\t\treturn this.optional(element) || /^\\d\\d?\\.\\d\\d?\\.\\d\\d\\d?\\d?$/.test(value);\n\t},\n\tnumber: function(value, element) {\n\t\treturn this.optional(element) || /^-?(?:\\d+|\\d{1,3}(?:\\.\\d{3})+)(?:,\\d+)?$/.test(value);\n\t}\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/methods_es_CL.js",
    "content": "/*\n * Localized default methods for the jQuery validation plugin.\n * Locale: ES_CL\n */\n$.extend($.validator.methods, {\n\tdate: function(value, element) {\n\t\treturn this.optional(element) || /^\\d\\d?\\-\\d\\d?\\-\\d\\d\\d?\\d?$/.test(value);\n\t},\n\tnumber: function(value, element) {\n\t\treturn this.optional(element) || /^-?(?:\\d+|\\d{1,3}(?:\\.\\d{3})+)(?:,\\d+)?$/.test(value);\n\t}\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/methods_fi.js",
    "content": "/*\n * Localized default methods for the jQuery validation plugin.\n * Locale: FI\n */\n$.extend($.validator.methods, {\n\tdate: function(value, element) {\n\t\treturn this.optional(element) || /^\\d{1,2}\\.\\d{1,2}\\.\\d{4}$/.test(value);\n\t},\n\tnumber: function(value, element) {\n\t\treturn this.optional(element) || /^-?(?:\\d+)(?:,\\d+)?$/.test(value);\n\t}\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/methods_nl.js",
    "content": "/*\n * Localized default methods for the jQuery validation plugin.\n * Locale: NL\n */\n$.extend($.validator.methods, {\n\tdate: function(value, element) {\n\t\treturn this.optional(element) || /^\\d\\d?[\\.\\/\\-]\\d\\d?[\\.\\/\\-]\\d\\d\\d?\\d?$/.test(value);\n\t}\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/src/localization/methods_pt.js",
    "content": "/*\n * Localized default methods for the jQuery validation plugin.\n * Locale: PT_BR\n */\n$.extend($.validator.methods, {\n\tdate: function(value, element) {\n\t\treturn this.optional(element) || /^\\d\\d?\\/\\d\\d?\\/\\d\\d\\d?\\d?$/.test(value);\n\t}\n});\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation/validation.jquery.json",
    "content": "{\n\t\"name\": \"validation\",\n\t\"title\": \"jQuery Validation\",\n\t\"description\": \"Form validation made easy. Validate a simple comment form with inline rules, or a complex signup form with powerful remote checks.\",\n\t\"keywords\": [\n\t\t\"forms\",\n\t\t\"validation\",\n\t\t\"validate\"\n\t],\n\t\"author\": {\n\t\t\"name\": \"Jörn Zaefferer\",\n\t\t\"email\": \"joern.zaefferer@gmail.com\",\n\t\t\"url\": \"http://bassistance.de\"\n\t},\n\t\"licenses\": [\n\t\t{\n\t\t\t\"type\": \"MIT\",\n\t\t\t\"url\": \"http://www.opensource.org/licenses/MIT\"\n\t\t}\n\t],\n\t\"bugs\": \"https://github.com/jzaefferer/jquery-validation/issues\",\n\t\"homepage\": \"https://github.com/jzaefferer/jquery-validation\",\n\t\"docs\": \"http://jqueryvalidation.org/documentation/\",\n\t\"download\": \"https://github.com/jzaefferer/jquery-validation/releases\",\n\t\"dependencies\": {\n\t\t\"jquery\": \">=1.4.4\"\n\t},\n\t\"version\": \"1.14.0\"\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/.bower.json",
    "content": "{\n  \"name\": \"jquery-validation-unobtrusive\",\n  \"version\": \"3.2.6\",\n  \"homepage\": \"https://github.com/aspnet/jquery-validation-unobtrusive\",\n  \"description\": \"Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.\",\n  \"main\": [\n    \"jquery.validate.unobtrusive.js\"\n  ],\n  \"ignore\": [\n    \"**/.*\",\n    \"*.json\",\n    \"*.md\",\n    \"*.txt\",\n    \"!LICENSE.txt\",\n    \"gulpfile.js\"\n  ],\n  \"keywords\": [\n    \"jquery\",\n    \"asp.net\",\n    \"mvc\",\n    \"validation\",\n    \"unobtrusive\"\n  ],\n  \"authors\": [\n    \"Microsoft\"\n  ],\n  \"license\": \"http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/aspnet/jquery-validation-unobtrusive.git\"\n  },\n  \"dependencies\": {\n    \"jquery-validation\": \">=1.8\",\n    \"jquery\": \">=1.8\"\n  },\n  \"_release\": \"3.2.6\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v3.2.6\",\n    \"commit\": \"47e82bc6cb86a05247f8c3846192228038572783\"\n  },\n  \"_source\": \"https://github.com/aspnet/jquery-validation-unobtrusive.git\",\n  \"_target\": \"3.2.6\",\n  \"_originalSource\": \"jquery-validation-unobtrusive\"\n}"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
    "content": "Copyright (c) .NET Foundation. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthese files except in compliance with the License. You may obtain a copy of the\nLicense at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed\nunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\nCONDITIONS OF ANY KIND, either express or implied. See the License for the\nspecific language governing permissions and limitations under the License.\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/bower.json",
    "content": "{\n    \"name\": \"jquery-validation-unobtrusive\",\n    \"version\": \"3.2.6\",\n    \"homepage\": \"https://github.com/aspnet/jquery-validation-unobtrusive\",\n    \"description\": \"Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.\",\n    \"main\": [\n        \"jquery.validate.unobtrusive.js\"\n    ],\n    \"ignore\": [\n        \"**/.*\",\n        \"*.json\",\n        \"*.md\",\n        \"*.txt\",\n        \"!LICENSE.txt\",\n        \"gulpfile.js\"\n    ],\n    \"keywords\": [\n        \"jquery\",\n        \"asp.net\",\n        \"mvc\",\n        \"validation\",\n        \"unobtrusive\"\n    ],\n    \"authors\": [\n        \"Microsoft\"\n    ],\n    \"license\": \"http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"git://github.com/aspnet/jquery-validation-unobtrusive.git\"\n    },\n    \"dependencies\": {\n        \"jquery-validation\": \">=1.8\",\n        \"jquery\": \">=1.8\"\n    }\n}\n"
  },
  {
    "path": "Blog.IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
    "content": "/*!\n** Unobtrusive validation support library for jQuery and jQuery Validate\n** Copyright (C) Microsoft Corporation. All rights reserved.\n*/\n\n/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */\n/*global document: false, jQuery: false */\n\n(function ($) {\n    var $jQval = $.validator,\n        adapters,\n        data_validation = \"unobtrusiveValidation\";\n\n    function setValidationValues(options, ruleName, value) {\n        options.rules[ruleName] = value;\n        if (options.message) {\n            options.messages[ruleName] = options.message;\n        }\n    }\n\n    function splitAndTrim(value) {\n        return value.replace(/^\\s+|\\s+$/g, \"\").split(/\\s*,\\s*/g);\n    }\n\n    function escapeAttributeValue(value) {\n        // As mentioned on http://api.jquery.com/category/selectors/\n        return value.replace(/([!\"#$%&'()*+,./:;<=>?@\\[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n    }\n\n    function getModelPrefix(fieldName) {\n        return fieldName.substr(0, fieldName.lastIndexOf(\".\") + 1);\n    }\n\n    function appendModelPrefix(value, prefix) {\n        if (value.indexOf(\"*.\") === 0) {\n            value = value.replace(\"*.\", prefix);\n        }\n        return value;\n    }\n\n    function onError(error, inputElement) {  // 'this' is the form element\n        var container = $(this).find(\"[data-valmsg-for='\" + escapeAttributeValue(inputElement[0].name) + \"']\"),\n            replaceAttrValue = container.attr(\"data-valmsg-replace\"),\n            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;\n\n        container.removeClass(\"field-validation-valid\").addClass(\"field-validation-error\");\n        error.data(\"unobtrusiveContainer\", container);\n\n        if (replace) {\n            container.empty();\n            error.removeClass(\"input-validation-error\").appendTo(container);\n        }\n        else {\n            error.hide();\n        }\n    }\n\n    function onErrors(event, validator) {  // 'this' is the form element\n        var container = $(this).find(\"[data-valmsg-summary=true]\"),\n            list = container.find(\"ul\");\n\n        if (list && list.length && validator.errorList.length) {\n            list.empty();\n            container.addClass(\"validation-summary-errors\").removeClass(\"validation-summary-valid\");\n\n            $.each(validator.errorList, function () {\n                $(\"<li />\").html(this.message).appendTo(list);\n            });\n        }\n    }\n\n    function onSuccess(error) {  // 'this' is the form element\n        var container = error.data(\"unobtrusiveContainer\");\n\n        if (container) {\n            var replaceAttrValue = container.attr(\"data-valmsg-replace\"),\n                replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;\n\n            container.addClass(\"field-validation-valid\").removeClass(\"field-validation-error\");\n            error.removeData(\"unobtrusiveContainer\");\n\n            if (replace) {\n                container.empty();\n            }\n        }\n    }\n\n    function onReset(event) {  // 'this' is the form element\n        var $form = $(this),\n            key = '__jquery_unobtrusive_validation_form_reset';\n        if ($form.data(key)) {\n            return;\n        }\n        // Set a flag that indicates we're currently resetting the form.\n        $form.data(key, true);\n        try {\n            $form.data(\"validator\").resetForm();\n        } finally {\n            $form.removeData(key);\n        }\n\n        $form.find(\".validation-summary-errors\")\n            .addClass(\"validation-summary-valid\")\n            .removeClass(\"validation-summary-errors\");\n        $form.find(\".field-validation-error\")\n            .addClass(\"field-validation-valid\")\n            .removeClass(\"field-validation-error\")\n            .removeData(\"unobtrusiveContainer\")\n            .find(\">*\")  // If we were using valmsg-replace, get the underlying error\n                .removeData(\"unobtrusiveContainer\");\n    }\n\n    function validationInfo(form) {\n        var $form = $(form),\n            result = $form.data(data_validation),\n            onResetProxy = $.proxy(onReset, form),\n            defaultOptions = $jQval.unobtrusive.options || {},\n            execInContext = function (name, args) {\n                var func = defaultOptions[name];\n                func && $.isFunction(func) && func.apply(form, args);\n            }\n\n        if (!result) {\n            result = {\n                options: {  // options structure passed to jQuery Validate's validate() method\n                    errorClass: defaultOptions.errorClass || \"input-validation-error\",\n                    errorElement: defaultOptions.errorElement || \"span\",\n                    errorPlacement: function () {\n                        onError.apply(form, arguments);\n                        execInContext(\"errorPlacement\", arguments);\n                    },\n                    invalidHandler: function () {\n                        onErrors.apply(form, arguments);\n                        execInContext(\"invalidHandler\", arguments);\n                    },\n                    messages: {},\n                    rules: {},\n                    success: function () {\n                        onSuccess.apply(form, arguments);\n                        execInContext(\"success\", arguments);\n                    }\n                },\n                attachValidation: function () {\n                    $form\n                        .off(\"reset.\" + data_validation, onResetProxy)\n                        .on(\"reset.\" + data_validation, onResetProxy)\n                        .validate(this.options);\n                },\n                validate: function () {  // a validation function that is called by unobtrusive Ajax\n                    $form.validate();\n                    return $form.valid();\n                }\n            };\n            $form.data(data_validation, result);\n        }\n\n        return result;\n    }\n\n    $jQval.unobtrusive = {\n        adapters: [],\n\n        parseElement: function (element, skipAttach) {\n            /// <summary>\n            /// Parses a single HTML element for unobtrusive validation attributes.\n            /// </summary>\n            /// <param name=\"element\" domElement=\"true\">The HTML element to be parsed.</param>\n            /// <param name=\"skipAttach\" type=\"Boolean\">[Optional] true to skip attaching the\n            /// validation to the form. If parsing just this single element, you should specify true.\n            /// If parsing several elements, you should specify false, and manually attach the validation\n            /// to the form when you are finished. The default is false.</param>\n            var $element = $(element),\n                form = $element.parents(\"form\")[0],\n                valInfo, rules, messages;\n\n            if (!form) {  // Cannot do client-side validation without a form\n                return;\n            }\n\n            valInfo = validationInfo(form);\n            valInfo.options.rules[element.name] = rules = {};\n            valInfo.options.messages[element.name] = messages = {};\n\n            $.each(this.adapters, function () {\n                var prefix = \"data-val-\" + this.name,\n                    message = $element.attr(prefix),\n                    paramValues = {};\n\n                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)\n                    prefix += \"-\";\n\n                    $.each(this.params, function () {\n                        paramValues[this] = $element.attr(prefix + this);\n                    });\n\n                    this.adapt({\n                        element: element,\n                        form: form,\n                        message: message,\n                        params: paramValues,\n                        rules: rules,\n                        messages: messages\n                    });\n                }\n            });\n\n            $.extend(rules, { \"__dummy__\": true });\n\n            if (!skipAttach) {\n                valInfo.attachValidation();\n            }\n        },\n\n        parse: function (selector) {\n            /// <summary>\n            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated\n            /// with the [data-val=true] attribute value and enables validation according to the data-val-*\n            /// attribute values.\n            /// </summary>\n            /// <param name=\"selector\" type=\"String\">Any valid jQuery selector.</param>\n\n            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one\n            // element with data-val=true\n            var $selector = $(selector),\n                $forms = $selector.parents()\n                                  .addBack()\n                                  .filter(\"form\")\n                                  .add($selector.find(\"form\"))\n                                  .has(\"[data-val=true]\");\n\n            $selector.find(\"[data-val=true]\").each(function () {\n                $jQval.unobtrusive.parseElement(this, true);\n            });\n\n            $forms.each(function () {\n                var info = validationInfo(this);\n                if (info) {\n                    info.attachValidation();\n                }\n            });\n        }\n    };\n\n    adapters = $jQval.unobtrusive.adapters;\n\n    adapters.add = function (adapterName, params, fn) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"params\" type=\"Array\" optional=\"true\">[Optional] An array of parameter names (strings) that will\n        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and\n        /// mmmm is the parameter name).</param>\n        /// <param name=\"fn\" type=\"Function\">The function to call, which adapts the values from the HTML\n        /// attributes into jQuery Validate rules and/or messages.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        if (!fn) {  // Called with no params, just a function\n            fn = params;\n            params = [];\n        }\n        this.push({ name: adapterName, params: params, adapt: fn });\n        return this;\n    };\n\n    adapters.addBool = function (adapterName, ruleName) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation rule has no parameter values.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"ruleName\" type=\"String\" optional=\"true\">[Optional] The name of the jQuery Validate rule. If not provided, the value\n        /// of adapterName will be used instead.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, function (options) {\n            setValidationValues(options, ruleName || adapterName, true);\n        });\n    };\n\n    adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and\n        /// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"minRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you only\n        /// have a minimum value.</param>\n        /// <param name=\"maxRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you only\n        /// have a maximum value.</param>\n        /// <param name=\"minMaxRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you\n        /// have both a minimum and maximum value.</param>\n        /// <param name=\"minAttribute\" type=\"String\" optional=\"true\">[Optional] The name of the HTML attribute that\n        /// contains the minimum value. The default is \"min\".</param>\n        /// <param name=\"maxAttribute\" type=\"String\" optional=\"true\">[Optional] The name of the HTML attribute that\n        /// contains the maximum value. The default is \"max\".</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, [minAttribute || \"min\", maxAttribute || \"max\"], function (options) {\n            var min = options.params.min,\n                max = options.params.max;\n\n            if (min && max) {\n                setValidationValues(options, minMaxRuleName, [min, max]);\n            }\n            else if (min) {\n                setValidationValues(options, minRuleName, min);\n            }\n            else if (max) {\n                setValidationValues(options, maxRuleName, max);\n            }\n        });\n    };\n\n    adapters.addSingleVal = function (adapterName, attribute, ruleName) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation rule has a single value.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>\n        /// <param name=\"attribute\" type=\"String\">[Optional] The name of the HTML attribute that contains the value.\n        /// The default is \"val\".</param>\n        /// <param name=\"ruleName\" type=\"String\" optional=\"true\">[Optional] The name of the jQuery Validate rule. If not provided, the value\n        /// of adapterName will be used instead.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, [attribute || \"val\"], function (options) {\n            setValidationValues(options, ruleName || adapterName, options.params[attribute]);\n        });\n    };\n\n    $jQval.addMethod(\"__dummy__\", function (value, element, params) {\n        return true;\n    });\n\n    $jQval.addMethod(\"regex\", function (value, element, params) {\n        var match;\n        if (this.optional(element)) {\n            return true;\n        }\n\n        match = new RegExp(params).exec(value);\n        return (match && (match.index === 0) && (match[0].length === value.length));\n    });\n\n    $jQval.addMethod(\"nonalphamin\", function (value, element, nonalphamin) {\n        var match;\n        if (nonalphamin) {\n            match = value.match(/\\W/g);\n            match = match && match.length >= nonalphamin;\n        }\n        return match;\n    });\n\n    if ($jQval.methods.extension) {\n        adapters.addSingleVal(\"accept\", \"mimtype\");\n        adapters.addSingleVal(\"extension\", \"extension\");\n    } else {\n        // for backward compatibility, when the 'extension' validation method does not exist, such as with versions\n        // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for\n        // validating the extension, and ignore mime-type validations as they are not supported.\n        adapters.addSingleVal(\"extension\", \"extension\", \"accept\");\n    }\n\n    adapters.addSingleVal(\"regex\", \"pattern\");\n    adapters.addBool(\"creditcard\").addBool(\"date\").addBool(\"digits\").addBool(\"email\").addBool(\"number\").addBool(\"url\");\n    adapters.addMinMax(\"length\", \"minlength\", \"maxlength\", \"rangelength\").addMinMax(\"range\", \"min\", \"max\", \"range\");\n    adapters.addMinMax(\"minlength\", \"minlength\").addMinMax(\"maxlength\", \"minlength\", \"maxlength\");\n    adapters.add(\"equalto\", [\"other\"], function (options) {\n        var prefix = getModelPrefix(options.element.name),\n            other = options.params.other,\n            fullOtherName = appendModelPrefix(other, prefix),\n            element = $(options.form).find(\":input\").filter(\"[name='\" + escapeAttributeValue(fullOtherName) + \"']\")[0];\n\n        setValidationValues(options, \"equalTo\", element);\n    });\n    adapters.add(\"required\", function (options) {\n        // jQuery Validate equates \"required\" with \"mandatory\" for checkbox elements\n        if (options.element.tagName.toUpperCase() !== \"INPUT\" || options.element.type.toUpperCase() !== \"CHECKBOX\") {\n            setValidationValues(options, \"required\", true);\n        }\n    });\n    adapters.add(\"remote\", [\"url\", \"type\", \"additionalfields\"], function (options) {\n        var value = {\n            url: options.params.url,\n            type: options.params.type || \"GET\",\n            data: {}\n        },\n            prefix = getModelPrefix(options.element.name);\n\n        $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {\n            var paramName = appendModelPrefix(fieldName, prefix);\n            value.data[paramName] = function () {\n                var field = $(options.form).find(\":input\").filter(\"[name='\" + escapeAttributeValue(paramName) + \"']\");\n                // For checkboxes and radio buttons, only pick up values from checked fields.\n                if (field.is(\":checkbox\")) {\n                    return field.filter(\":checked\").val() || field.filter(\":hidden\").val() || '';\n                }\n                else if (field.is(\":radio\")) {\n                    return field.filter(\":checked\").val() || '';\n                }\n                return field.val();\n            };\n        });\n\n        setValidationValues(options, \"remote\", value);\n    });\n    adapters.add(\"password\", [\"min\", \"nonalphamin\", \"regex\"], function (options) {\n        if (options.params.min) {\n            setValidationValues(options, \"minlength\", options.params.min);\n        }\n        if (options.params.nonalphamin) {\n            setValidationValues(options, \"nonalphamin\", options.params.nonalphamin);\n        }\n        if (options.params.regex) {\n            setValidationValues(options, \"regex\", options.params.regex);\n        }\n    });\n\n    $(function () {\n        $jQval.unobtrusive.parse(document);\n    });\n}(jQuery));"
  },
  {
    "path": "Blog.IdentityServer.Publish.Docker.sh",
    "content": "﻿# 停止容器\ndocker stop idscontainer\n# 删除容器\ndocker rm idscontainer\n# 删除镜像\ndocker rmi laozhangisphi/idsimg\n# 切换目录\ncd /home/Blog.IdentityServer\n# 发布项目\n./Blog.IdentityServer.Publish.Linux.sh\n# 进入目录\ncd /home/Blog.IdentityServer/.PublishFiles/\n# 编译镜像\ndocker build -t laozhangisphi/idsimg .\n# 生成容器\ndocker run --name=idscontainer -v /etc/localtime:/etc/localtime -it -p 5004:5004 laozhangisphi/idsimg\n# 启动容器\ndocker start idscontainer\n"
  },
  {
    "path": "Blog.IdentityServer.Publish.Linux.sh",
    "content": "git pull;\nrm -rf .PublishFiles;\ndotnet build;\ndotnet publish -o /home/Blog.IdentityServer/Blog.IdentityServer/bin/Debug/netcoreapp3.1;\ncp -r /home/Blog.IdentityServer/Blog.IdentityServer/bin/Debug/netcoreapp3.1 .PublishFiles;\necho \"Successfully!!!! ^ please see the file .PublishFiles\";"
  },
  {
    "path": "Blog.IdentityServer.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.30427.197\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Blog.IdentityServer\", \"Blog.IdentityServer\\Blog.IdentityServer.csproj\", \"{1DB65298-136C-41BC-B2CD-BA5BBA3D7A23}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{1DB65298-136C-41BC-B2CD-BA5BBA3D7A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1DB65298-136C-41BC-B2CD-BA5BBA3D7A23}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1DB65298-136C-41BC-B2CD-BA5BBA3D7A23}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1DB65298-136C-41BC-B2CD-BA5BBA3D7A23}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {F8CF5BB1-9EC8-44D8-94A3-0A5215DAE293}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Build.bat",
    "content": "git pull\n\n\ndotnet build\n\ncd Blog.IdentityServer\n\n\n\ndotnet run\n\ncmd"
  },
  {
    "path": "Dockerfile",
    "content": "#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.\n\nFROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base\nWORKDIR /app\nEXPOSE 5004\n\nFROM mcr.microsoft.com/dotnet/sdk:3.1 AS build\nWORKDIR /src\nCOPY [\"Blog.IdentityServer/Blog.IdentityServer.csproj\", \"Blog.IdentityServer/\"]\nRUN dotnet restore \"Blog.IdentityServer/Blog.IdentityServer.csproj\"\nCOPY . .\nWORKDIR \"/src/Blog.IdentityServer\"\nRUN dotnet build \"Blog.IdentityServer.csproj\" -c Release -o /app/build\n\nFROM build AS publish\nRUN dotnet publish \"Blog.IdentityServer.csproj\" -c Release -o /app/publish\n\nFROM base AS final\nWORKDIR /app\nCOPY --from=publish /app/publish .\nENTRYPOINT [\"dotnet\", \"Blog.IdentityServer.dll\"]"
  },
  {
    "path": "README.md",
    "content": "﻿\n![Logo](https://github.com/anjoy8/Blog.IdentityServer/blob/master/Blog.IdentityServer/wwwroot/logofull.png)\n\n&nbsp;\n&nbsp;\n\n## Info \n1、项目支持SqlServer和Mysql，默认Mysql，在配置文件中可以设置：\"IsMysql\": true,  \n2、如果用mysql，直接执行update-database即可，迁移文件在data下的MigrationsMySql文件夹；    \n3、如果不想用自带的迁移文件，先删掉data下的MigrationsMySql文件夹，然后执行（具体步骤在SeedData.cs中）；  \n\n## 给个星星! ⭐️\n如果你喜欢这个项目或者它帮助你, 请给 Star~（辛苦星咯）\n\n*********************************************************\n\n  \n## 售后服务与支持  \n\n鼓励作者，简单打赏，入微信群，随时随地解答我框架中（NetCore、Vue、DDD、IdentityServer4等）的疑难杂症。     \n注意主要是帮忙解决bug和思路，不会远程授课，但是可以适当发我代码，我帮忙调试，       \n打赏的时候，备注自己的微信号，我拉你进群，两天内没回应，QQ私聊我（3143422472）；   \n\n[赞赏列表](http://apk.neters.club/.doc/Contribution/)  \n\n \n<img src=\"http://apk.neters.club/laozhangisphigood.jpg\" alt=\"赞赏码\" width=\"300\" >\n[图片若加载不出来，点这里](http://apk.neters.club/laozhangisphigood.jpg)\n\n  <ul>\n<li></li>\n<li><a id=\"post_title_link_10529982\" href=\"https://www.bilibili.com/video/BV1vC4y1p7Za?p=14\">前端Blog.Admin-后端Blog.Core-认证中心(本项目) 快速启动 </a></li>\n<li></li>\n</ul>\n\n## Tips：\n```\n /*\n  * 本项目同时支持Mysql和Sqlserver，我一直使用的是Mysql，所以Mysql的迁移文件已经配置好，在Data文件夹下，\n  * 直接执行update-database xxxx,那三步即可。如果你使用sqlserver，可以先从迁移开始，下边有步骤\n  * \n  * 当然你也可以把Data文件夹除了ApplicationDbContext.cs文件外都删掉，自己重新做迁移。\n  * 迁移完成后，执行dotnet run /seed\n  *  1、PM> add-migration InitialIdentityServerPersistedGrantDbMigrationMysql -c PersistedGrantDbContext -o Data/MigrationsMySql/IdentityServer/PersistedGrantDb \n     Build started...\n     Build succeeded.\n     To undo this action, use Remove-Migration.\n     2、PM> update-database -c PersistedGrantDbContext\n     Build started...\n     Build succeeded.\n     Applying migration '20200509165052_InitialIdentityServerPersistedGrantDbMigrationMysql'.\n     Done.\n     3、PM> add-migration InitialIdentityServerConfigurationDbMigrationMysql -c ConfigurationDbContext -o Data/MigrationsMySql/IdentityServer/ConfigurationDb\n     Build started...\n     Build succeeded.\n     To undo this action, use Remove-Migration.\n     4、PM> update-database -c ConfigurationDbContext\n     Build started...\n     Build succeeded.\n     Applying migration '20200509165153_InitialIdentityServerConfigurationDbMigrationMysql'.\n     Done.\n     5、PM> add-migration AppDbMigration -c ApplicationDbContext -o Data/MigrationsMySql\n     Build started...\n     Build succeeded.\n     To undo this action, use Remove-Migration.\n     6、PM> update-database -c ApplicationDbContext\n     Build started...\n     Build succeeded.\n     Applying migration '20200509165505_AppDbMigration'.\n     Done.\n  * \n  */\n\n\n\n```\n\n\n*****************************************************\n### 跟踪教程\n\n\n博客园：https://www.cnblogs.com/laozhang-is-phi/  \n视频：https://www.bilibili.com/video/av76828468  \n\n<ul>\n<li><a id=\"post_title_link_10483922\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/10483922.html\">01 ║ 授权服务器 IdentityServer4 开篇讲&amp;计划书</a></li>\n<li><a id=\"post_title_link_10529982\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/10529982.html\">02 ║ 基础知识集合 &amp; 项目搭建一</a></li>\n<li><a id=\"post_title_link_10660403\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/10660403.html\">03 ║ 详解授权持久化 &amp; 用户数据迁移</a></li>\n<li><a id=\"post_title_link_10911438\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/10911438.html\">04 ║ 用户数据管理 &amp; 前后端授权联调</a></li>\n<li><a class=\"entry\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/11844395.html\" target=\"_blank\">05 ║ 多项目集成统一认证中心的思考</a></li>\n<li><a class=\"entry\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/rolemanager-one.html\" target=\"_blank\">06 ║ 统一角色管理（上）</a>&nbsp;</li>\n<li><a class=\"entry\" href=\"https://www.cnblogs.com/laozhang-is-phi/p/vue-core-ids.html\" target=\"_blank\">07 ║ 客户端、服务端、授权中心全线打通</a>&nbsp;</li>\n<li></li>\n</ul>\n\n\n\n微信公众号：https://mvp.neters.club/MVP_ids4_2020/2020  \n\n<ul>\n<li><a id=\"post_title_link_10483922\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=133\">【Ids4实战】分模块保护资源API</a></li>\n<li><a id=\"post_title_link_10529982\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=130\">【Ids4实战】最全的 v4 版本升级指南</a></li>\n<li><a id=\"post_title_link_10660403\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=74\">【Ids4实战】深究配置——用户信息操作篇</a></li>\n<li><a id=\"post_title_link_10911438\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=73\">【实战 Ids4】║ 认证中心之内部加权</a></li>\n<li><a class=\"entry\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=72\" target=\"_blank\">【实战 Ids4】║ 控制台密码模式搭配Ocelot网关</a></li>\n<li><a class=\"entry\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=71\" target=\"_blank\">【实战 Ids4】║ 在Swagger中调试认证授权中心</a>&nbsp;</li>\n<li><a class=\"entry\" href=\"http://apk.neters.club/api/Blog/GoUrl?id=70\" target=\"_blank\">【实战 Ids4】║ 又一个项目迁移完成（MVC）</a>&nbsp;</li>\n<li></li>\n</ul>\n\n```\n```\n\n\n\n**************************************************************\n\n  技术：\n\n      * .Net Core 3.1 MVC\n      \n      * EntityFramework Core\n      \n      * SqlServer/Mysql\n\n      * IdentityServer4\n\n      * Authentication and Authorization\n\n      * OAuth2 and OpenId Connect\n\n      * GrantTypes.Implicit\n\n      * oidc-client\n      \n      \n\n\n\n \n"
  }
]