initial commit
This commit is contained in:
commit
1d222736fc
|
@ -0,0 +1,5 @@
|
|||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using pwt_0x01_ng.Models;
|
||||
|
||||
namespace pwt_0x01_ng.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult About()
|
||||
{
|
||||
ViewData["Message"] = "Your application description page.";
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Contact()
|
||||
{
|
||||
ViewData["Message"] = "Your contact page.";
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace pwt_0x01_ng.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace pwt_0x01_ng
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:47798",
|
||||
"sslPort": 44311
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"pwt_0x01_ng": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# pwt-0x01-ng
|
||||
|
||||
this repo holds *sawce* for PWT .netcore mvc project 0x01-ng
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace pwt_0x01_ng
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||
options.CheckConsentNeeded = context => true;
|
||||
options.MinimumSameSitePolicy = SameSiteMode.None;
|
||||
});
|
||||
|
||||
|
||||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@{
|
||||
ViewData["Title"] = "About";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>Use this area to provide additional information.</p>
|
|
@ -0,0 +1,17 @@
|
|||
@{
|
||||
ViewData["Title"] = "Contact";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<address>
|
||||
One Microsoft Way<br/>
|
||||
Redmond, WA 98052-6399<br/>
|
||||
<abbr title="Phone">P:</abbr>
|
||||
425.555.0100
|
||||
</address>
|
||||
|
||||
<address>
|
||||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br/>
|
||||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
|
||||
</address>
|
|
@ -0,0 +1,105 @@
|
|||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item active">
|
||||
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how to build ASP.NET apps that can run anywhere.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
There are powerful new features in Visual Studio for building modern web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner3.svg" alt="Microsoft Azure" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<h2>Application uses</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
|
||||
<p>Use this page to detail your site's privacy policy.</p>
|
|
@ -0,0 +1,22 @@
|
|||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
|
@ -0,0 +1,43 @@
|
|||
@using Microsoft.AspNetCore.Http.Features
|
||||
|
||||
@{
|
||||
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
|
||||
var showBanner = !consentFeature?.CanTrack ?? false;
|
||||
var cookieString = consentFeature?.CreateConsentCookie();
|
||||
}
|
||||
|
||||
@if (showBanner)
|
||||
{
|
||||
<nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
|
||||
<span class="sr-only">Toggle cookie consent banner</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="navbar-brand">
|
||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse">
|
||||
<p class="navbar-text">
|
||||
Use this space to summarize your privacy and cookie use policy.
|
||||
</p>
|
||||
<div class="navbar-right">
|
||||
<a asp-controller="Home" asp-action="Privacy" class="btn btn-info navbar-btn">Learn More</a>
|
||||
<button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<script>
|
||||
(function () {
|
||||
document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
|
||||
document.cookie = el.target.dataset.cookieString;
|
||||
document.querySelector("#cookieConsent").classList.add("hidden");
|
||||
}, false);
|
||||
})();
|
||||
</script>
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>@ViewData["Title"] - pwt_0x02</title>
|
||||
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css"/>
|
||||
<link rel="stylesheet" href="~/css/site.css"/>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
|
||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"/>
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">pwt_0x02</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a asp-area="" asp-controller="Home" asp-action="Index">Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a asp-area="" asp-controller="Home" asp-action="About">About</a>
|
||||
</li>
|
||||
<li>
|
||||
<a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<partial name="_CookieConsentPartial"/>
|
||||
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr/>
|
||||
<footer>
|
||||
<p>© 2020 - pwt_0x02</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<environment include="Development">
|
||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
|
||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||
asp-fallback-test="window.jQuery"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
|
||||
</script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
|
||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd">
|
||||
</script>
|
||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<environment include="Development">
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-rZfj/ogBloos6wzLGpPkkOr/gpkBNLZ6b6yLy4o+ok+t/SAKlL5mvXLr0OXNi1Hp">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds">
|
||||
</script>
|
||||
</environment>
|
|
@ -0,0 +1,3 @@
|
|||
@using pwt_0x01_ng
|
||||
@using pwt_0x01_ng.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "2.1.519"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pwt-0x01-ng", "pwt-0x01-ng.csproj", "{F08770D5-6E89-458A-BE85-BA945D0BB9DD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F08770D5-6E89-458A-BE85-BA945D0BB9DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F08770D5-6E89-458A-BE85-BA945D0BB9DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F08770D5-6E89-458A-BE85-BA945D0BB9DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F08770D5-6E89-458A-BE85-BA945D0BB9DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,37 @@
|
|||
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\
|
||||
for details on configuring this project to bundle and minify static web assets. */
|
||||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Wrapping element */
|
||||
/* Set some basic padding to keep content from hitting the edges */
|
||||
.body-content {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* Carousel */
|
||||
.carousel-caption p {
|
||||
font-size: 20px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* Make .svg files in the carousel display properly in older browsers */
|
||||
.carousel-inner .item img[src$=".svg"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* QR code generator */
|
||||
#qrCode {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
/* Hide/rearrange for smaller screens */
|
||||
@media screen and (max-width: 767px) {
|
||||
/* Hide captions */
|
||||
.carousel-caption {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}}
|
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.5 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.2 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,4 @@
|
|||
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "bootstrap",
|
||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
||||
"keywords": [
|
||||
"css",
|
||||
"js",
|
||||
"less",
|
||||
"mobile-first",
|
||||
"responsive",
|
||||
"front-end",
|
||||
"framework",
|
||||
"web"
|
||||
],
|
||||
"homepage": "http://getbootstrap.com",
|
||||
"license": "MIT",
|
||||
"moduleType": "globals",
|
||||
"main": [
|
||||
"less/bootstrap.less",
|
||||
"dist/js/bootstrap.js"
|
||||
],
|
||||
"ignore": [
|
||||
"/.*",
|
||||
"_config.yml",
|
||||
"CNAME",
|
||||
"composer.json",
|
||||
"CONTRIBUTING.md",
|
||||
"docs",
|
||||
"js/tests",
|
||||
"test-infra"
|
||||
],
|
||||
"dependencies": {
|
||||
"jquery": "1.9.1 - 3"
|
||||
},
|
||||
"version": "3.3.7",
|
||||
"_release": "3.3.7",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v3.3.7",
|
||||
"commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
|
||||
},
|
||||
"_source": "https://github.com/twbs/bootstrap.git",
|
||||
"_target": "v3.3.7",
|
||||
"_originalSource": "bootstrap",
|
||||
"_direct": true
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2016 Twitter, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,587 @@
|
|||
/*!
|
||||
* Bootstrap v3.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
background-color: #2e6da4;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,2580 @@
|
|||
/*!
|
||||
* Bootstrap v3.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
|
||||
if (typeof jQuery === 'undefined') {
|
||||
throw new Error('Bootstrap\'s JavaScript requires jQuery')
|
||||
}
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
var version = $.fn.jquery.split(' ')[0].split('.')
|
||||
if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
|
||||
throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
|
||||
}
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: transition.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#transitions
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)
|
||||
// ============================================================
|
||||
|
||||
function transitionEnd() {
|
||||
var el = document.createElement('bootstrap')
|
||||
|
||||
var transEndEventNames = {
|
||||
WebkitTransition : 'webkitTransitionEnd',
|
||||
MozTransition : 'transitionend',
|
||||
OTransition : 'oTransitionEnd otransitionend',
|
||||
transition : 'transitionend'
|
||||
}
|
||||
|
||||
for (var name in transEndEventNames) {
|
||||
if (el.style[name] !== undefined) {
|
||||
return { end: transEndEventNames[name] }
|
||||
}
|
||||
}
|
||||
|
||||
return false // explicit for ie8 ( ._.)
|
||||
}
|
||||
|
||||
// https://blog.alexmaccaw.com/css-transitions
|
||||
$.fn.emulateTransitionEnd = function (duration) {
|
||||
var called = false
|
||||
var $el = this
|
||||
$(this).one('bsTransitionEnd', function () { called = true })
|
||||
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
|
||||
setTimeout(callback, duration)
|
||||
return this
|
||||
}
|
||||
|
||||
$(function () {
|
||||
$.support.transition = transitionEnd()
|
||||
|
||||
if (!$.support.transition) return
|
||||
|
||||
$.event.special.bsTransitionEnd = {
|
||||
bindType: $.support.transition.end,
|
||||
delegateType: $.support.transition.end,
|
||||
handle: function (e) {
|
||||
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: alert.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#alerts
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// ALERT CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var dismiss = '[data-dismiss="alert"]'
|
||||
var Alert = function (el) {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.VERSION = '3.4.1'
|
||||
|
||||
Alert.TRANSITION_DURATION = 150
|
||||
|
||||
Alert.prototype.close = function (e) {
|
||||
var $this = $(this)
|
||||
var selector = $this.attr('data-target')
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
selector = selector === '#' ? [] : selector
|
||||
var $parent = $(document).find(selector)
|
||||
|
||||
if (e) e.preventDefault()
|
||||
|
||||
if (!$parent.length) {
|
||||
$parent = $this.closest('.alert')
|
||||
}
|
||||
|
||||
$parent.trigger(e = $.Event('close.bs.alert'))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$parent.removeClass('in')
|
||||
|
||||
function removeElement() {
|
||||
// detach from parent, fire event then clean up data
|
||||
$parent.detach().trigger('closed.bs.alert').remove()
|
||||
}
|
||||
|
||||
$.support.transition && $parent.hasClass('fade') ?
|
||||
$parent
|
||||
.one('bsTransitionEnd', removeElement)
|
||||
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
|
||||
removeElement()
|
||||
}
|
||||
|
||||
|
||||
// ALERT PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.alert')
|
||||
|
||||
if (!data) $this.data('bs.alert', (data = new Alert(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.alert
|
||||
|
||||
$.fn.alert = Plugin
|
||||
$.fn.alert.Constructor = Alert
|
||||
|
||||
|
||||
// ALERT NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.alert.noConflict = function () {
|
||||
$.fn.alert = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// ALERT DATA-API
|
||||
// ==============
|
||||
|
||||
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: button.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#buttons
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// BUTTON PUBLIC CLASS DEFINITION
|
||||
// ==============================
|
||||
|
||||
var Button = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Button.DEFAULTS, options)
|
||||
this.isLoading = false
|
||||
}
|
||||
|
||||
Button.VERSION = '3.4.1'
|
||||
|
||||
Button.DEFAULTS = {
|
||||
loadingText: 'loading...'
|
||||
}
|
||||
|
||||
Button.prototype.setState = function (state) {
|
||||
var d = 'disabled'
|
||||
var $el = this.$element
|
||||
var val = $el.is('input') ? 'val' : 'html'
|
||||
var data = $el.data()
|
||||
|
||||
state += 'Text'
|
||||
|
||||
if (data.resetText == null) $el.data('resetText', $el[val]())
|
||||
|
||||
// push to event loop to allow forms to submit
|
||||
setTimeout($.proxy(function () {
|
||||
$el[val](data[state] == null ? this.options[state] : data[state])
|
||||
|
||||
if (state == 'loadingText') {
|
||||
this.isLoading = true
|
||||
$el.addClass(d).attr(d, d).prop(d, true)
|
||||
} else if (this.isLoading) {
|
||||
this.isLoading = false
|
||||
$el.removeClass(d).removeAttr(d).prop(d, false)
|
||||
}
|
||||
}, this), 0)
|
||||
}
|
||||
|
||||
Button.prototype.toggle = function () {
|
||||
var changed = true
|
||||
var $parent = this.$element.closest('[data-toggle="buttons"]')
|
||||
|
||||
if ($parent.length) {
|
||||
var $input = this.$element.find('input')
|
||||
if ($input.prop('type') == 'radio') {
|
||||
if ($input.prop('checked')) changed = false
|
||||
$parent.find('.active').removeClass('active')
|
||||
this.$element.addClass('active')
|
||||
} else if ($input.prop('type') == 'checkbox') {
|
||||
if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
$input.prop('checked', this.$element.hasClass('active'))
|
||||
if (changed) $input.trigger('change')
|
||||
} else {
|
||||
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BUTTON PLUGIN DEFINITION
|
||||
// ========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.button')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.button', (data = new Button(this, options)))
|
||||
|
||||
if (option == 'toggle') data.toggle()
|
||||
else if (option) data.setState(option)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.button
|
||||
|
||||
$.fn.button = Plugin
|
||||
$.fn.button.Constructor = Button
|
||||
|
||||
|
||||
// BUTTON NO CONFLICT
|
||||
// ==================
|
||||
|
||||
$.fn.button.noConflict = function () {
|
||||
$.fn.button = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// BUTTON DATA-API
|
||||
// ===============
|
||||
|
||||
$(document)
|
||||
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
var $btn = $(e.target).closest('.btn')
|
||||
Plugin.call($btn, 'toggle')
|
||||
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
|
||||
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
|
||||
e.preventDefault()
|
||||
// The target component still receive the focus
|
||||
if ($btn.is('input,button')) $btn.trigger('focus')
|
||||
else $btn.find('input:visible,button:visible').first().trigger('focus')
|
||||
}
|
||||
})
|
||||
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: carousel.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#carousel
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// CAROUSEL CLASS DEFINITION
|
||||
// =========================
|
||||
|
||||
var Carousel = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.$indicators = this.$element.find('.carousel-indicators')
|
||||
this.options = options
|
||||
this.paused = null
|
||||
this.sliding = null
|
||||
this.interval = null
|
||||
this.$active = null
|
||||
this.$items = null
|
||||
|
||||
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
||||
|
||||
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
|
||||
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
|
||||
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
||||
}
|
||||
|
||||
Carousel.VERSION = '3.4.1'
|
||||
|
||||
Carousel.TRANSITION_DURATION = 600
|
||||
|
||||
Carousel.DEFAULTS = {
|
||||
interval: 5000,
|
||||
pause: 'hover',
|
||||
wrap: true,
|
||||
keyboard: true
|
||||
}
|
||||
|
||||
Carousel.prototype.keydown = function (e) {
|
||||
if (/input|textarea/i.test(e.target.tagName)) return
|
||||
switch (e.which) {
|
||||
case 37: this.prev(); break
|
||||
case 39: this.next(); break
|
||||
default: return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
Carousel.prototype.cycle = function (e) {
|
||||
e || (this.paused = false)
|
||||
|
||||
this.interval && clearInterval(this.interval)
|
||||
|
||||
this.options.interval
|
||||
&& !this.paused
|
||||
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Carousel.prototype.getItemIndex = function (item) {
|
||||
this.$items = item.parent().children('.item')
|
||||
return this.$items.index(item || this.$active)
|
||||
}
|
||||
|
||||
Carousel.prototype.getItemForDirection = function (direction, active) {
|
||||
var activeIndex = this.getItemIndex(active)
|
||||
var willWrap = (direction == 'prev' && activeIndex === 0)
|
||||
|| (direction == 'next' && activeIndex == (this.$items.length - 1))
|
||||
if (willWrap && !this.options.wrap) return active
|
||||
var delta = direction == 'prev' ? -1 : 1
|
||||
var itemIndex = (activeIndex + delta) % this.$items.length
|
||||
return this.$items.eq(itemIndex)
|
||||
}
|
||||
|
||||
Carousel.prototype.to = function (pos) {
|
||||
var that = this
|
||||
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
|
||||
|
||||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
|
||||
if (activeIndex == pos) return this.pause().cycle()
|
||||
|
||||
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
|
||||
}
|
||||
|
||||
Carousel.prototype.pause = function (e) {
|
||||
e || (this.paused = true)
|
||||
|
||||
if (this.$element.find('.next, .prev').length && $.support.transition) {
|
||||
this.$element.trigger($.support.transition.end)
|
||||
this.cycle(true)
|
||||
}
|
||||
|
||||
this.interval = clearInterval(this.interval)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Carousel.prototype.next = function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('next')
|
||||
}
|
||||
|
||||
Carousel.prototype.prev = function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('prev')
|
||||
}
|
||||
|
||||
Carousel.prototype.slide = function (type, next) {
|
||||
var $active = this.$element.find('.item.active')
|
||||
var $next = next || this.getItemForDirection(type, $active)
|
||||
var isCycling = this.interval
|
||||
var direction = type == 'next' ? 'left' : 'right'
|
||||
var that = this
|
||||
|
||||
if ($next.hasClass('active')) return (this.sliding = false)
|
||||
|
||||
var relatedTarget = $next[0]
|
||||
var slideEvent = $.Event('slide.bs.carousel', {
|
||||
relatedTarget: relatedTarget,
|
||||
direction: direction
|
||||
})
|
||||
this.$element.trigger(slideEvent)
|
||||
if (slideEvent.isDefaultPrevented()) return
|
||||
|
||||
this.sliding = true
|
||||
|
||||
isCycling && this.pause()
|
||||
|
||||
if (this.$indicators.length) {
|
||||
this.$indicators.find('.active').removeClass('active')
|
||||
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
|
||||
$nextIndicator && $nextIndicator.addClass('active')
|
||||
}
|
||||
|
||||
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
|
||||
if ($.support.transition && this.$element.hasClass('slide')) {
|
||||
$next.addClass(type)
|
||||
if (typeof $next === 'object' && $next.length) {
|
||||
$next[0].offsetWidth // force reflow
|
||||
}
|
||||
$active.addClass(direction)
|
||||
$next.addClass(direction)
|
||||
$active
|
||||
.one('bsTransitionEnd', function () {
|
||||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () {
|
||||
that.$element.trigger(slidEvent)
|
||||
}, 0)
|
||||
})
|
||||
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
|
||||
} else {
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger(slidEvent)
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// CAROUSEL PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.carousel')
|
||||
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
var action = typeof option == 'string' ? option : options.slide
|
||||
|
||||
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
|
||||
if (typeof option == 'number') data.to(option)
|
||||
else if (action) data[action]()
|
||||
else if (options.interval) data.pause().cycle()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.carousel
|
||||
|
||||
$.fn.carousel = Plugin
|
||||
$.fn.carousel.Constructor = Carousel
|
||||
|
||||
|
||||
// CAROUSEL NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.carousel.noConflict = function () {
|
||||
$.fn.carousel = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// CAROUSEL DATA-API
|
||||
// =================
|
||||
|
||||
var clickHandler = function (e) {
|
||||
var $this = $(this)
|
||||
var href = $this.attr('href')
|
||||
if (href) {
|
||||
href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
var target = $this.attr('data-target') || href
|
||||
var $target = $(document).find(target)
|
||||
|
||||
if (!$target.hasClass('carousel')) return
|
||||
|
||||
var options = $.extend({}, $target.data(), $this.data())
|
||||
var slideIndex = $this.attr('data-slide-to')
|
||||
if (slideIndex) options.interval = false
|
||||
|
||||
Plugin.call($target, options)
|
||||
|
||||
if (slideIndex) {
|
||||
$target.data('bs.carousel').to(slideIndex)
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
$(document)
|
||||
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
|
||||
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-ride="carousel"]').each(function () {
|
||||
var $carousel = $(this)
|
||||
Plugin.call($carousel, $carousel.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: collapse.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#collapse
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
/* jshint latedef: false */
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// COLLAPSE PUBLIC CLASS DEFINITION
|
||||
// ================================
|
||||
|
||||
var Collapse = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||||
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||||
this.transitioning = null
|
||||
|
||||
if (this.options.parent) {
|
||||
this.$parent = this.getParent()
|
||||
} else {
|
||||
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||||
}
|
||||
|
||||
if (this.options.toggle) this.toggle()
|
||||
}
|
||||
|
||||
Collapse.VERSION = '3.4.1'
|
||||
|
||||
Collapse.TRANSITION_DURATION = 350
|
||||
|
||||
Collapse.DEFAULTS = {
|
||||
toggle: true
|
||||
}
|
||||
|
||||
Collapse.prototype.dimension = function () {
|
||||
var hasWidth = this.$element.hasClass('width')
|
||||
return hasWidth ? 'width' : 'height'
|
||||
}
|
||||
|
||||
Collapse.prototype.show = function () {
|
||||
if (this.transitioning || this.$element.hasClass('in')) return
|
||||
|
||||
var activesData
|
||||
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
||||
|
||||
if (actives && actives.length) {
|
||||
activesData = actives.data('bs.collapse')
|
||||
if (activesData && activesData.transitioning) return
|
||||
}
|
||||
|
||||
var startEvent = $.Event('show.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
if (actives && actives.length) {
|
||||
Plugin.call(actives, 'hide')
|
||||
activesData || actives.data('bs.collapse', null)
|
||||
}
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
.addClass('collapsing')[dimension](0)
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.$trigger
|
||||
.removeClass('collapsed')
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse in')[dimension]('')
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.trigger('shown.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
|
||||
|
||||
this.$element
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
||||
}
|
||||
|
||||
Collapse.prototype.hide = function () {
|
||||
if (this.transitioning || !this.$element.hasClass('in')) return
|
||||
|
||||
var startEvent = $.Event('hide.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||
|
||||
this.$element
|
||||
.addClass('collapsing')
|
||||
.removeClass('collapse in')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.$trigger
|
||||
.addClass('collapsed')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse')
|
||||
.trigger('hidden.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
this.$element
|
||||
[dimension](0)
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
||||
}
|
||||
|
||||
Collapse.prototype.toggle = function () {
|
||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
Collapse.prototype.getParent = function () {
|
||||
return $(document).find(this.options.parent)
|
||||
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||||
.each($.proxy(function (i, element) {
|
||||
var $element = $(element)
|
||||
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||||
}, this))
|
||||
.end()
|
||||
}
|
||||
|
||||
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||||
var isOpen = $element.hasClass('in')
|
||||
|
||||
$element.attr('aria-expanded', isOpen)
|
||||
$trigger
|
||||
.toggleClass('collapsed', !isOpen)
|
||||
.attr('aria-expanded', isOpen)
|
||||
}
|
||||
|
||||
function getTargetFromTrigger($trigger) {
|
||||
var href
|
||||
var target = $trigger.attr('data-target')
|
||||
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||
|
||||
return $(document).find(target)
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.collapse')
|
||||
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||||
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.collapse
|
||||
|
||||
$.fn.collapse = Plugin
|
||||
$.fn.collapse.Constructor = Collapse
|
||||
|
||||
|
||||
// COLLAPSE NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.collapse.noConflict = function () {
|
||||
$.fn.collapse = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE DATA-API
|
||||
// =================
|
||||
|
||||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
if (!$this.attr('data-target')) e.preventDefault()
|
||||
|
||||
var $target = getTargetFromTrigger($this)
|
||||
var data = $target.data('bs.collapse')
|
||||
var option = data ? 'toggle' : $this.data()
|
||||
|
||||
Plugin.call($target, option)
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: dropdown.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#dropdowns
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// DROPDOWN CLASS DEFINITION
|
||||
// =========================
|
||||
|
||||
var backdrop = '.dropdown-backdrop'
|
||||
var toggle = '[data-toggle="dropdown"]'
|
||||
var Dropdown = function (element) {
|
||||
$(element).on('click.bs.dropdown', this.toggle)
|
||||
}
|
||||
|
||||
Dropdown.VERSION = '3.4.1'
|
||||
|
||||
function getParent($this) {
|
||||
var selector = $this.attr('data-target')
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
var $parent = selector !== '#' ? $(document).find(selector) : null
|
||||
|
||||
return $parent && $parent.length ? $parent : $this.parent()
|
||||
}
|
||||
|
||||
function clearMenus(e) {
|
||||
if (e && e.which === 3) return
|
||||
$(backdrop).remove()
|
||||
$(toggle).each(function () {
|
||||
var $this = $(this)
|
||||
var $parent = getParent($this)
|
||||
var relatedTarget = { relatedTarget: this }
|
||||
|
||||
if (!$parent.hasClass('open')) return
|
||||
|
||||
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
|
||||
|
||||
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$this.attr('aria-expanded', 'false')
|
||||
$parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
|
||||
})
|
||||
}
|
||||
|
||||
Dropdown.prototype.toggle = function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
clearMenus()
|
||||
|
||||
if (!isActive) {
|
||||
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
||||
// if mobile we use a backdrop because click events don't delegate
|
||||
$(document.createElement('div'))
|
||||
.addClass('dropdown-backdrop')
|
||||
.insertAfter($(this))
|
||||
.on('click', clearMenus)
|
||||
}
|
||||
|
||||
var relatedTarget = { relatedTarget: this }
|
||||
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$this
|
||||
.trigger('focus')
|
||||
.attr('aria-expanded', 'true')
|
||||
|
||||
$parent
|
||||
.toggleClass('open')
|
||||
.trigger($.Event('shown.bs.dropdown', relatedTarget))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Dropdown.prototype.keydown = function (e) {
|
||||
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
|
||||
|
||||
var $this = $(this)
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
if (!isActive && e.which != 27 || isActive && e.which == 27) {
|
||||
if (e.which == 27) $parent.find(toggle).trigger('focus')
|
||||
return $this.trigger('click')
|
||||
}
|
||||
|
||||
var desc = ' li:not(.disabled):visible a'
|
||||
var $items = $parent.find('.dropdown-menu' + desc)
|
||||
|
||||
if (!$items.length) return
|
||||
|
||||
var index = $items.index(e.target)
|
||||
|
||||
if (e.which == 38 && index > 0) index-- // up
|
||||
if (e.which == 40 && index < $items.length - 1) index++ // down
|
||||
if (!~index) index = 0
|
||||
|
||||
$items.eq(index).trigger('focus')
|
||||
}
|
||||
|
||||
|
||||
// DROPDOWN PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.dropdown')
|
||||
|
||||
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.dropdown
|
||||
|
||||
$.fn.dropdown = Plugin
|
||||
$.fn.dropdown.Constructor = Dropdown
|
||||
|
||||
|
||||
// DROPDOWN NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.dropdown.noConflict = function () {
|
||||
$.fn.dropdown = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
// ===================================
|
||||
|
||||
$(document)
|
||||
.on('click.bs.dropdown.data-api', clearMenus)
|
||||
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||||
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
|
||||
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
|
||||
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: modal.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#modals
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// MODAL CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$dialog = this.$element.find('.modal-dialog')
|
||||
this.$backdrop = null
|
||||
this.isShown = null
|
||||
this.originalBodyPad = null
|
||||
this.scrollbarWidth = 0
|
||||
this.ignoreBackdropClick = false
|
||||
this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom'
|
||||
|
||||
if (this.options.remote) {
|
||||
this.$element
|
||||
.find('.modal-content')
|
||||
.load(this.options.remote, $.proxy(function () {
|
||||
this.$element.trigger('loaded.bs.modal')
|
||||
}, this))
|
||||
}
|
||||
}
|
||||
|
||||
Modal.VERSION = '3.4.1'
|
||||
|
||||
Modal.TRANSITION_DURATION = 300
|
||||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
||||
|
||||
Modal.DEFAULTS = {
|
||||
backdrop: true,
|
||||
keyboard: true,
|
||||
show: true
|
||||
}
|
||||
|
||||
Modal.prototype.toggle = function (_relatedTarget) {
|
||||
return this.isShown ? this.hide() : this.show(_relatedTarget)
|
||||
}
|
||||
|
||||
Modal.prototype.show = function (_relatedTarget) {
|
||||
var that = this
|
||||
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = true
|
||||
|
||||
this.checkScrollbar()
|
||||
this.setScrollbar()
|
||||
this.$body.addClass('modal-open')
|
||||
|
||||
this.escape()
|
||||
this.resize()
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
|
||||
|
||||
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
|
||||
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
|
||||
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
|
||||
})
|
||||
})
|
||||
|
||||
this.backdrop(function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
if (!that.$element.parent().length) {
|
||||
that.$element.appendTo(that.$body) // don't move modals dom position
|
||||
}
|
||||
|
||||
that.$element
|
||||
.show()
|
||||
.scrollTop(0)
|
||||
|
||||
that.adjustDialog()
|
||||
|
||||
if (transition) {
|
||||
that.$element[0].offsetWidth // force reflow
|
||||
}
|
||||
|
||||
that.$element.addClass('in')
|
||||
|
||||
that.enforceFocus()
|
||||
|
||||
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
|
||||
|
||||
transition ?
|
||||
that.$dialog // wait for modal to slide in
|
||||
.one('bsTransitionEnd', function () {
|
||||
that.$element.trigger('focus').trigger(e)
|
||||
})
|
||||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||||
that.$element.trigger('focus').trigger(e)
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.hide = function (e) {
|
||||
if (e) e.preventDefault()
|
||||
|
||||
e = $.Event('hide.bs.modal')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (!this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = false
|
||||
|
||||
this.escape()
|
||||
this.resize()
|
||||
|
||||
$(document).off('focusin.bs.modal')
|
||||
|
||||
this.$element
|
||||
.removeClass('in')
|
||||
.off('click.dismiss.bs.modal')
|
||||
.off('mouseup.dismiss.bs.modal')
|
||||
|
||||
this.$dialog.off('mousedown.dismiss.bs.modal')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.$element
|
||||
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
|
||||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||||
this.hideModal()
|
||||
}
|
||||
|
||||
Modal.prototype.enforceFocus = function () {
|
||||
$(document)
|
||||
.off('focusin.bs.modal') // guard against infinite focus loop
|
||||
.on('focusin.bs.modal', $.proxy(function (e) {
|
||||
if (document !== e.target &&
|
||||
this.$element[0] !== e.target &&
|
||||
!this.$element.has(e.target).length) {
|
||||
this.$element.trigger('focus')
|
||||
}
|
||||
}, this))
|
||||
}
|
||||
|
||||
Modal.prototype.escape = function () {
|
||||
if (this.isShown && this.options.keyboard) {
|
||||
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
|
||||
e.which == 27 && this.hide()
|
||||
}, this))
|
||||
} else if (!this.isShown) {
|
||||
this.$element.off('keydown.dismiss.bs.modal')
|
||||
}
|
||||
}
|
||||
|
||||
Modal.prototype.resize = function () {
|
||||
if (this.isShown) {
|
||||
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
|
||||
} else {
|
||||
$(window).off('resize.bs.modal')
|
||||
}
|
||||
}
|
||||
|
||||
Modal.prototype.hideModal = function () {
|
||||
var that = this
|
||||
this.$element.hide()
|
||||
this.backdrop(function () {
|
||||
that.$body.removeClass('modal-open')
|
||||
that.resetAdjustments()
|
||||
that.resetScrollbar()
|
||||
that.$element.trigger('hidden.bs.modal')
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.removeBackdrop = function () {
|
||||
this.$backdrop && this.$backdrop.remove()
|
||||
this.$backdrop = null
|
||||
}
|
||||
|
||||
Modal.prototype.backdrop = function (callback) {
|
||||
var that = this
|
||||
var animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||||
|
||||
if (this.isShown && this.options.backdrop) {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $(document.createElement('div'))
|
||||
.addClass('modal-backdrop ' + animate)
|
||||
.appendTo(this.$body)
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
|
||||
if (this.ignoreBackdropClick) {
|
||||
this.ignoreBackdropClick = false
|
||||
return
|
||||
}
|
||||
if (e.target !== e.currentTarget) return
|
||||
this.options.backdrop == 'static'
|
||||
? this.$element[0].focus()
|
||||
: this.hide()
|
||||
}, this))
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
this.$backdrop.addClass('in')
|
||||
|
||||
if (!callback) return
|
||||
|
||||
doAnimate ?
|
||||
this.$backdrop
|
||||
.one('bsTransitionEnd', callback)
|
||||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||||
callback()
|
||||
|
||||
} else if (!this.isShown && this.$backdrop) {
|
||||
this.$backdrop.removeClass('in')
|
||||
|
||||
var callbackRemove = function () {
|
||||
that.removeBackdrop()
|
||||
callback && callback()
|
||||
}
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.$backdrop
|
||||
.one('bsTransitionEnd', callbackRemove)
|
||||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||||
callbackRemove()
|
||||
|
||||
} else if (callback) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// these following methods are used to handle overflowing modals
|
||||
|
||||
Modal.prototype.handleUpdate = function () {
|
||||
this.adjustDialog()
|
||||
}
|
||||
|
||||
Modal.prototype.adjustDialog = function () {
|
||||
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
|
||||
|
||||
this.$element.css({
|
||||
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
|
||||
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.resetAdjustments = function () {
|
||||
this.$element.css({
|
||||
paddingLeft: '',
|
||||
paddingRight: ''
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.checkScrollbar = function () {
|
||||
var fullWindowWidth = window.innerWidth
|
||||
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
|
||||
var documentElementRect = document.documentElement.getBoundingClientRect()
|
||||
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
|
||||
}
|
||||
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
|
||||
this.scrollbarWidth = this.measureScrollbar()
|
||||
}
|
||||
|
||||
Modal.prototype.setScrollbar = function () {
|
||||
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
|
||||
this.originalBodyPad = document.body.style.paddingRight || ''
|
||||
var scrollbarWidth = this.scrollbarWidth
|
||||
if (this.bodyIsOverflowing) {
|
||||
this.$body.css('padding-right', bodyPad + scrollbarWidth)
|
||||
$(this.fixedContent).each(function (index, element) {
|
||||
var actualPadding = element.style.paddingRight
|
||||
var calculatedPadding = $(element).css('padding-right')
|
||||
$(element)
|
||||
.data('padding-right', actualPadding)
|
||||
.css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Modal.prototype.resetScrollbar = function () {
|
||||
this.$body.css('padding-right', this.originalBodyPad)
|
||||
$(this.fixedContent).each(function (index, element) {
|
||||
var padding = $(element).data('padding-right')
|
||||
$(element).removeData('padding-right')
|
||||
element.style.paddingRight = padding ? padding : ''
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.measureScrollbar = function () { // thx walsh
|
||||
var scrollDiv = document.createElement('div')
|
||||
scrollDiv.className = 'modal-scrollbar-measure'
|
||||
this.$body.append(scrollDiv)
|
||||
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
|
||||
this.$body[0].removeChild(scrollDiv)
|
||||
return scrollbarWidth
|
||||
}
|
||||
|
||||
|
||||
// MODAL PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option, _relatedTarget) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.modal')
|
||||
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
|
||||
if (typeof option == 'string') data[option](_relatedTarget)
|
||||
else if (options.show) data.show(_relatedTarget)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.modal
|
||||
|
||||
$.fn.modal = Plugin
|
||||
$.fn.modal.Constructor = Modal
|
||||
|
||||
|
||||
// MODAL NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.modal.noConflict = function () {
|
||||
$.fn.modal = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// MODAL DATA-API
|
||||
// ==============
|
||||
|
||||
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
|
||||
var $this = $(this)
|
||||
var href = $this.attr('href')
|
||||
var target = $this.attr('data-target') ||
|
||||
(href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
|
||||
|
||||
var $target = $(document).find(target)
|
||||
var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
|
||||
|
||||
if ($this.is('a')) e.preventDefault()
|
||||
|
||||
$target.one('show.bs.modal', function (showEvent) {
|
||||
if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
|
||||
$target.one('hidden.bs.modal', function () {
|
||||
$this.is(':visible') && $this.trigger('focus')
|
||||
})
|
||||
})
|
||||
Plugin.call($target, option, this)
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: tooltip.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#tooltip
|
||||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
|
||||
|
||||
var uriAttrs = [
|
||||
'background',
|
||||
'cite',
|
||||
'href',
|
||||
'itemtype',
|
||||
'longdesc',
|
||||
'poster',
|
||||
'src',
|
||||
'xlink:href'
|
||||
]
|
||||
|
||||
var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
|
||||
|
||||
var DefaultWhitelist = {
|
||||
// Global attributes allowed on any supplied element below.
|
||||
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
|
||||
a: ['target', 'href', 'title', 'rel'],
|
||||
area: [],
|
||||
b: [],
|
||||
br: [],
|
||||
col: [],
|
||||
code: [],
|
||||
div: [],
|
||||
em: [],
|
||||
hr: [],
|
||||
h1: [],
|
||||
h2: [],
|
||||
h3: [],
|
||||
h4: [],
|
||||
h5: [],
|
||||
h6: [],
|
||||
i: [],
|
||||
img: ['src', 'alt', 'title', 'width', 'height'],
|
||||
li: [],
|
||||
ol: [],
|
||||
p: [],
|
||||
pre: [],
|
||||
s: [],
|
||||
small: [],
|
||||
span: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
strong: [],
|
||||
u: [],
|
||||
ul: []
|
||||
}
|
||||
|
||||
/**
|
||||
* A pattern that recognizes a commonly useful subset of URLs that are safe.
|
||||
*
|
||||
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
|
||||
*/
|
||||
var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi
|
||||
|
||||
/**
|
||||
* A pattern that matches safe data URLs. Only matches image, video and audio types.
|
||||
*
|
||||
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
|
||||
*/
|
||||
var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i
|
||||
|
||||
function allowedAttribute(attr, allowedAttributeList) {
|
||||
var attrName = attr.nodeName.toLowerCase()
|
||||
|
||||
if ($.inArray(attrName, allowedAttributeList) !== -1) {
|
||||
if ($.inArray(attrName, uriAttrs) !== -1) {
|
||||
return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var regExp = $(allowedAttributeList).filter(function (index, value) {
|
||||
return value instanceof RegExp
|
||||
})
|
||||
|
||||
// Check if a regular expression validates the attribute.
|
||||
for (var i = 0, l = regExp.length; i < l; i++) {
|
||||
if (attrName.match(regExp[i])) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
|
||||
if (unsafeHtml.length === 0) {
|
||||
return unsafeHtml
|
||||
}
|
||||
|
||||
if (sanitizeFn && typeof sanitizeFn === 'function') {
|
||||
return sanitizeFn(unsafeHtml)
|
||||
}
|
||||
|
||||
// IE 8 and below don't support createHTMLDocument
|
||||
if (!document.implementation || !document.implementation.createHTMLDocument) {
|
||||
return unsafeHtml
|
||||
}
|
||||
|
||||
var createdDocument = document.implementation.createHTMLDocument('sanitization')
|
||||
createdDocument.body.innerHTML = unsafeHtml
|
||||
|
||||
var whitelistKeys = $.map(whiteList, function (el, i) { return i })
|
||||
var elements = $(createdDocument.body).find('*')
|
||||
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
var el = elements[i]
|
||||
var elName = el.nodeName.toLowerCase()
|
||||
|
||||
if ($.inArray(elName, whitelistKeys) === -1) {
|
||||
el.parentNode.removeChild(el)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
var attributeList = $.map(el.attributes, function (el) { return el })
|
||||
var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])
|
||||
|
||||
for (var j = 0, len2 = attributeList.length; j < len2; j++) {
|
||||
if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {
|
||||
el.removeAttribute(attributeList[j].nodeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return createdDocument.body.innerHTML
|
||||
}
|
||||
|
||||
// TOOLTIP PUBLIC CLASS DEFINITION
|
||||
// ===============================
|
||||
|
||||
var Tooltip = function (element, options) {
|
||||
this.type = null
|
||||
this.options = null
|
||||
this.enabled = null
|
||||
this.timeout = null
|
||||
this.hoverState = null
|
||||
this.$element = null
|
||||
this.inState = null
|
||||
|
||||
this.init('tooltip', element, options)
|
||||
}
|
||||
|
||||
Tooltip.VERSION = '3.4.1'
|
||||
|
||||
Tooltip.TRANSITION_DURATION = 150
|
||||
|
||||
Tooltip.DEFAULTS = {
|
||||
animation: true,
|
||||
placement: 'top',
|
||||
selector: false,
|
||||
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
|
||||
trigger: 'hover focus',
|
||||
title: '',
|
||||
delay: 0,
|
||||
html: false,
|
||||
container: false,
|
||||
viewport: {
|
||||
selector: 'body',
|
||||
padding: 0
|
||||
},
|
||||
sanitize : true,
|
||||
sanitizeFn : null,
|
||||
whiteList : DefaultWhitelist
|
||||
}
|
||||
|
||||
Tooltip.prototype.init = function (type, element, options) {
|
||||
this.enabled = true
|
||||
this.type = type
|
||||
this.$element = $(element)
|
||||
this.options = this.getOptions(options)
|
||||
this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
|
||||
this.inState = { click: false, hover: false, focus: false }
|
||||
|
||||
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
|
||||
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
|
||||
}
|
||||
|
||||
var triggers = this.options.trigger.split(' ')
|
||||
|
||||
for (var i = triggers.length; i--;) {
|
||||
var trigger = triggers[i]
|
||||
|
||||
if (trigger == 'click') {
|
||||
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
|
||||
} else if (trigger != 'manual') {
|
||||
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
|
||||
var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
|
||||
|
||||
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
|
||||
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
|
||||
}
|
||||
}
|
||||
|
||||
this.options.selector ?
|
||||
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
|
||||
this.fixTitle()
|
||||
}
|
||||
|
||||
Tooltip.prototype.getDefaults = function () {
|
||||
return Tooltip.DEFAULTS
|
||||
}
|
||||
|
||||
Tooltip.prototype.getOptions = function (options) {
|
||||
var dataAttributes = this.$element.data()
|
||||
|
||||
for (var dataAttr in dataAttributes) {
|
||||
if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
|
||||
delete dataAttributes[dataAttr]
|
||||
}
|
||||
}
|
||||
|
||||
options = $.extend({}, this.getDefaults(), dataAttributes, options)
|
||||
|
||||
if (options.delay && typeof options.delay == 'number') {
|
||||
options.delay = {
|
||||
show: options.delay,
|
||||
hide: options.delay
|
||||
}
|
||||
}
|
||||
|
||||
if (options.sanitize) {
|
||||
options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
Tooltip.prototype.getDelegateOptions = function () {
|
||||
var options = {}
|
||||
var defaults = this.getDefaults()
|
||||
|
||||
this._options && $.each(this._options, function (key, value) {
|
||||
if (defaults[key] != value) options[key] = value
|
||||
})
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
Tooltip.prototype.enter = function (obj) {
|
||||
var self = obj instanceof this.constructor ?
|
||||
obj : $(obj.currentTarget).data('bs.' + this.type)
|
||||
|
||||
if (!self) {
|
||||
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
|
||||
$(obj.currentTarget).data('bs.' + this.type, self)
|
||||
}
|
||||
|
||||
if (obj instanceof $.Event) {
|
||||
self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
|
||||
}
|
||||
|
||||
if (self.tip().hasClass('in') || self.hoverState == 'in') {
|
||||
self.hoverState = 'in'
|
||||
return
|
||||
}
|
||||
|
||||
clearTimeout(self.timeout)
|
||||
|
||||
self.hoverState = 'in'
|
||||
|
||||
if (!self.options.delay || !self.options.delay.show) return self.show()
|
||||
|
||||
self.timeout = setTimeout(function () {
|
||||
if (self.hoverState == 'in') self.show()
|
||||
}, self.options.delay.show)
|
||||
}
|
||||
|
||||
Tooltip.prototype.isInStateTrue = function () {
|
||||
for (var key in this.inState) {
|
||||
if (this.inState[key]) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Tooltip.prototype.leave = function (obj) {
|
||||
var self = obj instanceof this.constructor ?
|
||||
obj : $(obj.currentTarget).data('bs.' + this.type)
|
||||
|
||||
if (!self) {
|
||||
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
|
||||
$(obj.currentTarget).data('bs.' + this.type, self)
|
||||
}
|
||||
|
||||
if (obj instanceof $.Event) {
|
||||
self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
|
||||
}
|
||||
|
||||
if (self.isInStateTrue()) return
|
||||
|
||||
clearTimeout(self.timeout)
|
||||
|
||||
self.hoverState = 'out'
|
||||
|
||||
if (!self.options.delay || !self.options.delay.hide) return self.hide()
|
||||
|
||||
self.timeout = setTimeout(function () {
|
||||
if (self.hoverState == 'out') self.hide()
|
||||
}, self.options.delay.hide)
|
||||
}
|
||||
|
||||
Tooltip.prototype.show = function () {
|
||||
var e = $.Event('show.bs.' + this.type)
|
||||
|
||||
if (this.hasContent() && this.enabled) {
|
||||
this.$element.trigger(e)
|
||||
|
||||
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
|
||||
if (e.isDefaultPrevented() || !inDom) return
|
||||
var that = this
|
||||
|
||||
var $tip = this.tip()
|
||||
|
||||
var tipId = this.getUID(this.type)
|
||||
|
||||
this.setContent()
|
||||
$tip.attr('id', tipId)
|
||||
this.$element.attr('aria-describedby', tipId)
|
||||
|
||||
if (this.options.animation) $tip.addClass('fade')
|
||||
|
||||
var placement = typeof this.options.placement == 'function' ?
|
||||
this.options.placement.call(this, $tip[0], this.$element[0]) :
|
||||
this.options.placement
|
||||
|
||||
var autoToken = /\s?auto?\s?/i
|
||||
var autoPlace = autoToken.test(placement)
|
||||
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
|
||||
|
||||
$tip
|
||||
.detach()
|
||||
.css({ top: 0, left: 0, display: 'block' })
|
||||
.addClass(placement)
|
||||
.data('bs.' + this.type, this)
|
||||
|
||||
this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
|
||||
this.$element.trigger('inserted.bs.' + this.type)
|
||||
|
||||
var pos = this.getPosition()
|
||||
var actualWidth = $tip[0].offsetWidth
|
||||
var actualHeight = $tip[0].offsetHeight
|
||||
|
||||
if (autoPlace) {
|
||||
var orgPlacement = placement
|
||||
var viewportDim = this.getPosition(this.$viewport)
|
||||
|
||||
placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
|
||||
placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
|
||||
placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
|
||||
placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
|
||||
placement
|
||||
|
||||
$tip
|
||||
.removeClass(orgPlacement)
|
||||
.addClass(placement)
|
||||
}
|
||||
|
||||
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
|
||||
|
||||
this.applyPlacement(calculatedOffset, placement)
|
||||
|
||||
var complete = function () {
|
||||
var prevHoverState = that.hoverState
|
||||
that.$element.trigger('shown.bs.' + that.type)
|
||||
that.hoverState = null
|
||||
|
||||
if (prevHoverState == 'out') that.leave(that)
|
||||
}
|
||||
|
||||
$.support.transition && this.$tip.hasClass('fade') ?
|
||||
$tip
|
||||
.one('bsTransitionEnd', complete)
|
||||
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
|
||||
complete()
|
||||
}
|
||||
}
|
||||
|
||||
Tooltip.prototype.applyPlacement = function (offset, placement) {
|
||||
var $tip = this.tip()
|
||||
var width = $tip[0].offsetWidth
|
||||
var height = $tip[0].offsetHeight
|
||||
|
||||
// manually read margins because getBoundingClientRect includes difference
|
||||
var marginTop = parseInt($tip.css('margin-top'), 10)
|
||||
var marginLeft = parseInt($tip.css('margin-left'), 10)
|
||||
|
||||
// we must check for NaN for ie 8/9
|
||||
if (isNaN(marginTop)) marginTop = 0
|
||||
if (isNaN(marginLeft)) marginLeft = 0
|
||||
|
||||
offset.top += marginTop
|
||||
offset.left += marginLeft
|
||||
|
||||
// $.fn.offset doesn't round pixel values
|
||||
// so we use setOffset directly with our own function B-0
|
||||
$.offset.setOffset($tip[0], $.extend({
|
||||
using: function (props) {
|
||||
$tip.css({
|
||||
top: Math.round(props.top),
|
||||
left: Math.round(props.left)
|
||||
})
|
||||
}
|
||||
}, offset), 0)
|
||||
|
||||
$tip.addClass('in')
|
||||
|
||||
// check to see if placing tip in new offset caused the tip to resize itself
|
||||
var actualWidth = $tip[0].offsetWidth
|
||||
var actualHeight = $tip[0].offsetHeight
|
||||
|
||||
if (placement == 'top' && actualHeight != height) {
|
||||
offset.top = offset.top + height - actualHeight
|
||||
}
|
||||
|
||||
var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
|
||||
|
||||
if (delta.left) offset.left += delta.left
|
||||
else offset.top += delta.top
|
||||
|
||||
var isVertical = /top|bottom/.test(placement)
|
||||
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
|
||||
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
|
||||
|
||||
$tip.offset(offset)
|
||||
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
|
||||
}
|
||||
|
||||
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
|
||||
this.arrow()
|
||||
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
|
||||
.css(isVertical ? 'top' : 'left', '')
|
||||
}
|
||||
|
||||
Tooltip.prototype.setContent = function () {
|
||||
var $tip = this.tip()
|
||||
var title = this.getTitle()
|
||||
|
||||
if (this.options.html) {
|
||||
if (this.options.sanitize) {
|
||||
title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)
|
||||
}
|
||||
|
||||
$tip.find('.tooltip-inner').html(title)
|
||||
} else {
|
||||
$tip.find('.tooltip-inner').text(title)
|
||||
}
|
||||
|
||||
$tip.removeClass('fade in top bottom left right')
|
||||
}
|
||||
|
||||
Tooltip.prototype.hide = function (callback) {
|
||||
var that = this
|
||||
var $tip = $(this.$tip)
|
||||
var e = $.Event('hide.bs.' + this.type)
|
||||
|
||||
function complete() {
|
||||
if (that.hoverState != 'in') $tip.detach()
|
||||
if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
|
||||
that.$element
|
||||
.removeAttr('aria-describedby')
|
||||
.trigger('hidden.bs.' + that.type)
|
||||
}
|
||||
callback && callback()
|
||||
}
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$tip.removeClass('in')
|
||||
|
||||
$.support.transition && $tip.hasClass('fade') ?
|
||||
$tip
|
||||
.one('bsTransitionEnd', complete)
|
||||
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
|
||||
complete()
|
||||
|
||||
this.hoverState = null
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Tooltip.prototype.fixTitle = function () {
|
||||
var $e = this.$element
|
||||
if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
|
||||
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
|
||||
}
|
||||
}
|
||||
|
||||
Tooltip.prototype.hasContent = function () {
|
||||
return this.getTitle()
|
||||
}
|
||||
|
||||
Tooltip.prototype.getPosition = function ($element) {
|
||||
$element = $element || this.$element
|
||||
|
||||
var el = $element[0]
|
||||
var isBody = el.tagName == 'BODY'
|
||||
|
||||
var elRect = el.getBoundingClientRect()
|
||||
if (elRect.width == null) {
|
||||
// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
|
||||
elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
|
||||
}
|
||||
var isSvg = window.SVGElement && el instanceof window.SVGElement
|
||||
// Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
|
||||
// See https://github.com/twbs/bootstrap/issues/20280
|
||||
var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
|
||||
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
|
||||
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
|
||||
|
||||
return $.extend({}, elRect, scroll, outerDims, elOffset)
|
||||
}
|
||||
|
||||
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
|
||||
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
|
||||
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
|
||||
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
|
||||
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
|
||||
|
||||
}
|
||||
|
||||
Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
|
||||
var delta = { top: 0, left: 0 }
|
||||
if (!this.$viewport) return delta
|
||||
|
||||
var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
|
||||
var viewportDimensions = this.getPosition(this.$viewport)
|
||||
|
||||
if (/right|left/.test(placement)) {
|
||||
var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
|
||||
var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
|
||||
if (topEdgeOffset < viewportDimensions.top) { // top overflow
|
||||
delta.top = viewportDimensions.top - topEdgeOffset
|
||||
} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
|
||||
delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
|
||||
}
|
||||
} else {
|
||||
var leftEdgeOffset = pos.left - viewportPadding
|
||||
var rightEdgeOffset = pos.left + viewportPadding + actualWidth
|
||||
if (leftEdgeOffset < viewportDimensions.left) { // left overflow
|
||||
delta.left = viewportDimensions.left - leftEdgeOffset
|
||||
} else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
|
||||
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
|
||||
}
|
||||
}
|
||||
|
||||
return delta
|
||||
}
|
||||
|
||||
Tooltip.prototype.getTitle = function () {
|
||||
var title
|
||||
var $e = this.$element
|
||||
var o = this.options
|
||||
|
||||
title = $e.attr('data-original-title')
|
||||
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|
||||
|
||||
return title
|
||||
}
|
||||
|
||||
Tooltip.prototype.getUID = function (prefix) {
|
||||
do prefix += ~~(Math.random() * 1000000)
|
||||
while (document.getElementById(prefix))
|
||||
return prefix
|
||||
}
|
||||
|
||||
Tooltip.prototype.tip = function () {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $(this.options.template)
|
||||
if (this.$tip.length != 1) {
|
||||
throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
|
||||
}
|
||||
}
|
||||
return this.$tip
|
||||
}
|
||||
|
||||
Tooltip.prototype.arrow = function () {
|
||||
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
|
||||
}
|
||||
|
||||
Tooltip.prototype.enable = function () {
|
||||
this.enabled = true
|
||||
}
|
||||
|
||||
Tooltip.prototype.disable = function () {
|
||||
this.enabled = false
|
||||
}
|
||||
|
||||
Tooltip.prototype.toggleEnabled = function () {
|
||||
this.enabled = !this.enabled
|
||||
}
|
||||
|
||||
Tooltip.prototype.toggle = function (e) {
|
||||
var self = this
|
||||
if (e) {
|
||||
self = $(e.currentTarget).data('bs.' + this.type)
|
||||
if (!self) {
|
||||
self = new this.constructor(e.currentTarget, this.getDelegateOptions())
|
||||
$(e.currentTarget).data('bs.' + this.type, self)
|
||||
}
|
||||
}
|
||||
|
||||
if (e) {
|
||||
self.inState.click = !self.inState.click
|
||||
if (self.isInStateTrue()) self.enter(self)
|
||||
else self.leave(self)
|
||||
} else {
|
||||
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
|
||||
}
|
||||
}
|
||||
|
||||
Tooltip.prototype.destroy = function () {
|
||||
var that = this
|
||||
clearTimeout(this.timeout)
|
||||
this.hide(function () {
|
||||
that.$element.off('.' + that.type).removeData('bs.' + that.type)
|
||||
if (that.$tip) {
|
||||
that.$tip.detach()
|
||||
}
|
||||
that.$tip = null
|
||||
that.$arrow = null
|
||||
that.$viewport = null
|
||||
that.$element = null
|
||||
})
|
||||
}
|
||||
|
||||
Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {
|
||||
return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)
|
||||
}
|
||||
|
||||
// TOOLTIP PLUGIN DEFINITION
|
||||
// =========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.tooltip')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data && /destroy|hide/.test(option)) return
|
||||
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.tooltip
|
||||
|
||||
$.fn.tooltip = Plugin
|
||||
$.fn.tooltip.Constructor = Tooltip
|
||||
|
||||
|
||||
// TOOLTIP NO CONFLICT
|
||||
// ===================
|
||||
|
||||
$.fn.tooltip.noConflict = function () {
|
||||
$.fn.tooltip = old
|
||||
return this
|
||||
}
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: popover.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#popovers
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// POPOVER PUBLIC CLASS DEFINITION
|
||||
// ===============================
|
||||
|
||||
var Popover = function (element, options) {
|
||||
this.init('popover', element, options)
|
||||
}
|
||||
|
||||
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
||||
|
||||
Popover.VERSION = '3.4.1'
|
||||
|
||||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
||||
placement: 'right',
|
||||
trigger: 'click',
|
||||
content: '',
|
||||
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||||
})
|
||||
|
||||
|
||||
// NOTE: POPOVER EXTENDS tooltip.js
|
||||
// ================================
|
||||
|
||||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
|
||||
|
||||
Popover.prototype.constructor = Popover
|
||||
|
||||
Popover.prototype.getDefaults = function () {
|
||||
return Popover.DEFAULTS
|
||||
}
|
||||
|
||||
Popover.prototype.setContent = function () {
|
||||
var $tip = this.tip()
|
||||
var title = this.getTitle()
|
||||
var content = this.getContent()
|
||||
|
||||
if (this.options.html) {
|
||||
var typeContent = typeof content
|
||||
|
||||
if (this.options.sanitize) {
|
||||
title = this.sanitizeHtml(title)
|
||||
|
||||
if (typeContent === 'string') {
|
||||
content = this.sanitizeHtml(content)
|
||||
}
|
||||
}
|
||||
|
||||
$tip.find('.popover-title').html(title)
|
||||
$tip.find('.popover-content').children().detach().end()[
|
||||
typeContent === 'string' ? 'html' : 'append'
|
||||
](content)
|
||||
} else {
|
||||
$tip.find('.popover-title').text(title)
|
||||
$tip.find('.popover-content').children().detach().end().text(content)
|
||||
}
|
||||
|
||||
$tip.removeClass('fade top bottom left right in')
|
||||
|
||||
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
|
||||
// this manually by checking the contents.
|
||||
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
|
||||
}
|
||||
|
||||
Popover.prototype.hasContent = function () {
|
||||
return this.getTitle() || this.getContent()
|
||||
}
|
||||
|
||||
Popover.prototype.getContent = function () {
|
||||
var $e = this.$element
|
||||
var o = this.options
|
||||
|
||||
return $e.attr('data-content')
|
||||
|| (typeof o.content == 'function' ?
|
||||
o.content.call($e[0]) :
|
||||
o.content)
|
||||
}
|
||||
|
||||
Popover.prototype.arrow = function () {
|
||||
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
|
||||
}
|
||||
|
||||
|
||||
// POPOVER PLUGIN DEFINITION
|
||||
// =========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.popover')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data && /destroy|hide/.test(option)) return
|
||||
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.popover
|
||||
|
||||
$.fn.popover = Plugin
|
||||
$.fn.popover.Constructor = Popover
|
||||
|
||||
|
||||
// POPOVER NO CONFLICT
|
||||
// ===================
|
||||
|
||||
$.fn.popover.noConflict = function () {
|
||||
$.fn.popover = old
|
||||
return this
|
||||
}
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: scrollspy.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#scrollspy
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// SCROLLSPY CLASS DEFINITION
|
||||
// ==========================
|
||||
|
||||
function ScrollSpy(element, options) {
|
||||
this.$body = $(document.body)
|
||||
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
|
||||
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
|
||||
this.selector = (this.options.target || '') + ' .nav li > a'
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.activeTarget = null
|
||||
this.scrollHeight = 0
|
||||
|
||||
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
|
||||
this.refresh()
|
||||
this.process()
|
||||
}
|
||||
|
||||
ScrollSpy.VERSION = '3.4.1'
|
||||
|
||||
ScrollSpy.DEFAULTS = {
|
||||
offset: 10
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.getScrollHeight = function () {
|
||||
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.refresh = function () {
|
||||
var that = this
|
||||
var offsetMethod = 'offset'
|
||||
var offsetBase = 0
|
||||
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.scrollHeight = this.getScrollHeight()
|
||||
|
||||
if (!$.isWindow(this.$scrollElement[0])) {
|
||||
offsetMethod = 'position'
|
||||
offsetBase = this.$scrollElement.scrollTop()
|
||||
}
|
||||
|
||||
this.$body
|
||||
.find(this.selector)
|
||||
.map(function () {
|
||||
var $el = $(this)
|
||||
var href = $el.data('target') || $el.attr('href')
|
||||
var $href = /^#./.test(href) && $(href)
|
||||
|
||||
return ($href
|
||||
&& $href.length
|
||||
&& $href.is(':visible')
|
||||
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null
|
||||
})
|
||||
.sort(function (a, b) { return a[0] - b[0] })
|
||||
.each(function () {
|
||||
that.offsets.push(this[0])
|
||||
that.targets.push(this[1])
|
||||
})
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.process = function () {
|
||||
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
|
||||
var scrollHeight = this.getScrollHeight()
|
||||
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
|
||||
var offsets = this.offsets
|
||||
var targets = this.targets
|
||||
var activeTarget = this.activeTarget
|
||||
var i
|
||||
|
||||
if (this.scrollHeight != scrollHeight) {
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
if (scrollTop >= maxScroll) {
|
||||
return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
|
||||
}
|
||||
|
||||
if (activeTarget && scrollTop < offsets[0]) {
|
||||
this.activeTarget = null
|
||||
return this.clear()
|
||||
}
|
||||
|
||||
for (i = offsets.length; i--;) {
|
||||
activeTarget != targets[i]
|
||||
&& scrollTop >= offsets[i]
|
||||
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
|
||||
&& this.activate(targets[i])
|
||||
}
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.activate = function (target) {
|
||||
this.activeTarget = target
|
||||
|
||||
this.clear()
|
||||
|
||||
var selector = this.selector +
|
||||
'[data-target="' + target + '"],' +
|
||||
this.selector + '[href="' + target + '"]'
|
||||
|
||||
var active = $(selector)
|
||||
.parents('li')
|
||||
.addClass('active')
|
||||
|
||||
if (active.parent('.dropdown-menu').length) {
|
||||
active = active
|
||||
.closest('li.dropdown')
|
||||
.addClass('active')
|
||||
}
|
||||
|
||||
active.trigger('activate.bs.scrollspy')
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.clear = function () {
|
||||
$(this.selector)
|
||||
.parentsUntil(this.options.target, '.active')
|
||||
.removeClass('active')
|
||||
}
|
||||
|
||||
|
||||
// SCROLLSPY PLUGIN DEFINITION
|
||||
// ===========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.scrollspy')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.scrollspy
|
||||
|
||||
$.fn.scrollspy = Plugin
|
||||
$.fn.scrollspy.Constructor = ScrollSpy
|
||||
|
||||
|
||||
// SCROLLSPY NO CONFLICT
|
||||
// =====================
|
||||
|
||||
$.fn.scrollspy.noConflict = function () {
|
||||
$.fn.scrollspy = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// SCROLLSPY DATA-API
|
||||
// ==================
|
||||
|
||||
$(window).on('load.bs.scrollspy.data-api', function () {
|
||||
$('[data-spy="scroll"]').each(function () {
|
||||
var $spy = $(this)
|
||||
Plugin.call($spy, $spy.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: tab.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#tabs
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// TAB CLASS DEFINITION
|
||||
// ====================
|
||||
|
||||
var Tab = function (element) {
|
||||
// jscs:disable requireDollarBeforejQueryAssignment
|
||||
this.element = $(element)
|
||||
// jscs:enable requireDollarBeforejQueryAssignment
|
||||
}
|
||||
|
||||
Tab.VERSION = '3.4.1'
|
||||
|
||||
Tab.TRANSITION_DURATION = 150
|
||||
|
||||
Tab.prototype.show = function () {
|
||||
var $this = this.element
|
||||
var $ul = $this.closest('ul:not(.dropdown-menu)')
|
||||
var selector = $this.data('target')
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
if ($this.parent('li').hasClass('active')) return
|
||||
|
||||
var $previous = $ul.find('.active:last a')
|
||||
var hideEvent = $.Event('hide.bs.tab', {
|
||||
relatedTarget: $this[0]
|
||||
})
|
||||
var showEvent = $.Event('show.bs.tab', {
|
||||
relatedTarget: $previous[0]
|
||||
})
|
||||
|
||||
$previous.trigger(hideEvent)
|
||||
$this.trigger(showEvent)
|
||||
|
||||
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
|
||||
|
||||
var $target = $(document).find(selector)
|
||||
|
||||
this.activate($this.closest('li'), $ul)
|
||||
this.activate($target, $target.parent(), function () {
|
||||
$previous.trigger({
|
||||
type: 'hidden.bs.tab',
|
||||
relatedTarget: $this[0]
|
||||
})
|
||||
$this.trigger({
|
||||
type: 'shown.bs.tab',
|
||||
relatedTarget: $previous[0]
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Tab.prototype.activate = function (element, container, callback) {
|
||||
var $active = container.find('> .active')
|
||||
var transition = callback
|
||||
&& $.support.transition
|
||||
&& ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
|
||||
|
||||
function next() {
|
||||
$active
|
||||
.removeClass('active')
|
||||
.find('> .dropdown-menu > .active')
|
||||
.removeClass('active')
|
||||
.end()
|
||||
.find('[data-toggle="tab"]')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
element
|
||||
.addClass('active')
|
||||
.find('[data-toggle="tab"]')
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
if (transition) {
|
||||
element[0].offsetWidth // reflow for transition
|
||||
element.addClass('in')
|
||||
} else {
|
||||
element.removeClass('fade')
|
||||
}
|
||||
|
||||
if (element.parent('.dropdown-menu').length) {
|
||||
element
|
||||
.closest('li.dropdown')
|
||||
.addClass('active')
|
||||
.end()
|
||||
.find('[data-toggle="tab"]')
|
||||
.attr('aria-expanded', true)
|
||||
}
|
||||
|
||||
callback && callback()
|
||||
}
|
||||
|
||||
$active.length && transition ?
|
||||
$active
|
||||
.one('bsTransitionEnd', next)
|
||||
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
|
||||
next()
|
||||
|
||||
$active.removeClass('in')
|
||||
}
|
||||
|
||||
|
||||
// TAB PLUGIN DEFINITION
|
||||
// =====================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.tab')
|
||||
|
||||
if (!data) $this.data('bs.tab', (data = new Tab(this)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.tab
|
||||
|
||||
$.fn.tab = Plugin
|
||||
$.fn.tab.Constructor = Tab
|
||||
|
||||
|
||||
// TAB NO CONFLICT
|
||||
// ===============
|
||||
|
||||
$.fn.tab.noConflict = function () {
|
||||
$.fn.tab = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// TAB DATA-API
|
||||
// ============
|
||||
|
||||
var clickHandler = function (e) {
|
||||
e.preventDefault()
|
||||
Plugin.call($(this), 'show')
|
||||
}
|
||||
|
||||
$(document)
|
||||
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
|
||||
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
|
||||
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: affix.js v3.4.1
|
||||
* https://getbootstrap.com/docs/3.4/javascript/#affix
|
||||
* ========================================================================
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// AFFIX CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var Affix = function (element, options) {
|
||||
this.options = $.extend({}, Affix.DEFAULTS, options)
|
||||
|
||||
var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)
|
||||
|
||||
this.$target = target
|
||||
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
|
||||
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
|
||||
|
||||
this.$element = $(element)
|
||||
this.affixed = null
|
||||
this.unpin = null
|
||||
this.pinnedOffset = null
|
||||
|
||||
this.checkPosition()
|
||||
}
|
||||
|
||||
Affix.VERSION = '3.4.1'
|
||||
|
||||
Affix.RESET = 'affix affix-top affix-bottom'
|
||||
|
||||
Affix.DEFAULTS = {
|
||||
offset: 0,
|
||||
target: window
|
||||
}
|
||||
|
||||
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
|
||||
var scrollTop = this.$target.scrollTop()
|
||||
var position = this.$element.offset()
|
||||
var targetHeight = this.$target.height()
|
||||
|
||||
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
|
||||
|
||||
if (this.affixed == 'bottom') {
|
||||
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
|
||||
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
|
||||
}
|
||||
|
||||
var initializing = this.affixed == null
|
||||
var colliderTop = initializing ? scrollTop : position.top
|
||||
var colliderHeight = initializing ? targetHeight : height
|
||||
|
||||
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
|
||||
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Affix.prototype.getPinnedOffset = function () {
|
||||
if (this.pinnedOffset) return this.pinnedOffset
|
||||
this.$element.removeClass(Affix.RESET).addClass('affix')
|
||||
var scrollTop = this.$target.scrollTop()
|
||||
var position = this.$element.offset()
|
||||
return (this.pinnedOffset = position.top - scrollTop)
|
||||
}
|
||||
|
||||
Affix.prototype.checkPositionWithEventLoop = function () {
|
||||
setTimeout($.proxy(this.checkPosition, this), 1)
|
||||
}
|
||||
|
||||
Affix.prototype.checkPosition = function () {
|
||||
if (!this.$element.is(':visible')) return
|
||||
|
||||
var height = this.$element.height()
|
||||
var offset = this.options.offset
|
||||
var offsetTop = offset.top
|
||||
var offsetBottom = offset.bottom
|
||||
var scrollHeight = Math.max($(document).height(), $(document.body).height())
|
||||
|
||||
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
||||
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
|
||||
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
|
||||
|
||||
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
|
||||
|
||||
if (this.affixed != affix) {
|
||||
if (this.unpin != null) this.$element.css('top', '')
|
||||
|
||||
var affixType = 'affix' + (affix ? '-' + affix : '')
|
||||
var e = $.Event(affixType + '.bs.affix')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
this.affixed = affix
|
||||
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
|
||||
|
||||
this.$element
|
||||
.removeClass(Affix.RESET)
|
||||
.addClass(affixType)
|
||||
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
|
||||
}
|
||||
|
||||
if (affix == 'bottom') {
|
||||
this.$element.offset({
|
||||
top: scrollHeight - height - offsetBottom
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AFFIX PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.affix')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.affix
|
||||
|
||||
$.fn.affix = Plugin
|
||||
$.fn.affix.Constructor = Affix
|
||||
|
||||
|
||||
// AFFIX NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.affix.noConflict = function () {
|
||||
$.fn.affix = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// AFFIX DATA-API
|
||||
// ==============
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-spy="affix"]').each(function () {
|
||||
var $spy = $(this)
|
||||
var data = $spy.data()
|
||||
|
||||
data.offset = data.offset || {}
|
||||
|
||||
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
|
||||
if (data.offsetTop != null) data.offset.top = data.offsetTop
|
||||
|
||||
Plugin.call($spy, data)
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
|||
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
|
||||
require('../../js/transition.js')
|
||||
require('../../js/alert.js')
|
||||
require('../../js/button.js')
|
||||
require('../../js/carousel.js')
|
||||
require('../../js/collapse.js')
|
||||
require('../../js/dropdown.js')
|
||||
require('../../js/modal.js')
|
||||
require('../../js/tooltip.js')
|
||||
require('../../js/popover.js')
|
||||
require('../../js/scrollspy.js')
|
||||
require('../../js/tab.js')
|
||||
require('../../js/affix.js')
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "jquery-validation-unobtrusive",
|
||||
"homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
|
||||
"version": "3.2.9",
|
||||
"_release": "3.2.9",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v3.2.9",
|
||||
"commit": "a91f5401898e125f10771c5f5f0909d8c4c82396"
|
||||
},
|
||||
"_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git",
|
||||
"_target": "^3.2.9",
|
||||
"_originalSource": "jquery-validation-unobtrusive",
|
||||
"_direct": true
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
Copyright (c) .NET Foundation. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
these files except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
|
@ -0,0 +1,431 @@
|
|||
// Unobtrusive validation support library for jQuery and jQuery Validate
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
// @version v3.2.9
|
||||
|
||||
/*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 */
|
||||
/*global document: false, jQuery: false */
|
||||
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define("jquery.validate.unobtrusive", ['jquery.validation'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// CommonJS-like environments that support module.exports
|
||||
module.exports = factory(require('jquery-validation'));
|
||||
} else {
|
||||
// Browser global
|
||||
jQuery.validator.unobtrusive = factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
var $jQval = $.validator,
|
||||
adapters,
|
||||
data_validation = "unobtrusiveValidation";
|
||||
|
||||
function setValidationValues(options, ruleName, value) {
|
||||
options.rules[ruleName] = value;
|
||||
if (options.message) {
|
||||
options.messages[ruleName] = options.message;
|
||||
}
|
||||
}
|
||||
|
||||
function splitAndTrim(value) {
|
||||
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
|
||||
}
|
||||
|
||||
function escapeAttributeValue(value) {
|
||||
// As mentioned on http://api.jquery.com/category/selectors/
|
||||
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
|
||||
}
|
||||
|
||||
function getModelPrefix(fieldName) {
|
||||
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
function appendModelPrefix(value, prefix) {
|
||||
if (value.indexOf("*.") === 0) {
|
||||
value = value.replace("*.", prefix);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function onError(error, inputElement) { // 'this' is the form element
|
||||
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
|
||||
replaceAttrValue = container.attr("data-valmsg-replace"),
|
||||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
|
||||
|
||||
container.removeClass("field-validation-valid").addClass("field-validation-error");
|
||||
error.data("unobtrusiveContainer", container);
|
||||
|
||||
if (replace) {
|
||||
container.empty();
|
||||
error.removeClass("input-validation-error").appendTo(container);
|
||||
}
|
||||
else {
|
||||
error.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onErrors(event, validator) { // 'this' is the form element
|
||||
var container = $(this).find("[data-valmsg-summary=true]"),
|
||||
list = container.find("ul");
|
||||
|
||||
if (list && list.length && validator.errorList.length) {
|
||||
list.empty();
|
||||
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
|
||||
|
||||
$.each(validator.errorList, function () {
|
||||
$("<li />").html(this.message).appendTo(list);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onSuccess(error) { // 'this' is the form element
|
||||
var container = error.data("unobtrusiveContainer");
|
||||
|
||||
if (container) {
|
||||
var replaceAttrValue = container.attr("data-valmsg-replace"),
|
||||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
|
||||
|
||||
container.addClass("field-validation-valid").removeClass("field-validation-error");
|
||||
error.removeData("unobtrusiveContainer");
|
||||
|
||||
if (replace) {
|
||||
container.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onReset(event) { // 'this' is the form element
|
||||
var $form = $(this),
|
||||
key = '__jquery_unobtrusive_validation_form_reset';
|
||||
if ($form.data(key)) {
|
||||
return;
|
||||
}
|
||||
// Set a flag that indicates we're currently resetting the form.
|
||||
$form.data(key, true);
|
||||
try {
|
||||
$form.data("validator").resetForm();
|
||||
} finally {
|
||||
$form.removeData(key);
|
||||
}
|
||||
|
||||
$form.find(".validation-summary-errors")
|
||||
.addClass("validation-summary-valid")
|
||||
.removeClass("validation-summary-errors");
|
||||
$form.find(".field-validation-error")
|
||||
.addClass("field-validation-valid")
|
||||
.removeClass("field-validation-error")
|
||||
.removeData("unobtrusiveContainer")
|
||||
.find(">*") // If we were using valmsg-replace, get the underlying error
|
||||
.removeData("unobtrusiveContainer");
|
||||
}
|
||||
|
||||
function validationInfo(form) {
|
||||
var $form = $(form),
|
||||
result = $form.data(data_validation),
|
||||
onResetProxy = $.proxy(onReset, form),
|
||||
defaultOptions = $jQval.unobtrusive.options || {},
|
||||
execInContext = function (name, args) {
|
||||
var func = defaultOptions[name];
|
||||
func && $.isFunction(func) && func.apply(form, args);
|
||||
};
|
||||
|
||||
if (!result) {
|
||||
result = {
|
||||
options: { // options structure passed to jQuery Validate's validate() method
|
||||
errorClass: defaultOptions.errorClass || "input-validation-error",
|
||||
errorElement: defaultOptions.errorElement || "span",
|
||||
errorPlacement: function () {
|
||||
onError.apply(form, arguments);
|
||||
execInContext("errorPlacement", arguments);
|
||||
},
|
||||
invalidHandler: function () {
|
||||
onErrors.apply(form, arguments);
|
||||
execInContext("invalidHandler", arguments);
|
||||
},
|
||||
messages: {},
|
||||
rules: {},
|
||||
success: function () {
|
||||
onSuccess.apply(form, arguments);
|
||||
execInContext("success", arguments);
|
||||
}
|
||||
},
|
||||
attachValidation: function () {
|
||||
$form
|
||||
.off("reset." + data_validation, onResetProxy)
|
||||
.on("reset." + data_validation, onResetProxy)
|
||||
.validate(this.options);
|
||||
},
|
||||
validate: function () { // a validation function that is called by unobtrusive Ajax
|
||||
$form.validate();
|
||||
return $form.valid();
|
||||
}
|
||||
};
|
||||
$form.data(data_validation, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
$jQval.unobtrusive = {
|
||||
adapters: [],
|
||||
|
||||
parseElement: function (element, skipAttach) {
|
||||
/// <summary>
|
||||
/// Parses a single HTML element for unobtrusive validation attributes.
|
||||
/// </summary>
|
||||
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
|
||||
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
|
||||
/// validation to the form. If parsing just this single element, you should specify true.
|
||||
/// If parsing several elements, you should specify false, and manually attach the validation
|
||||
/// to the form when you are finished. The default is false.</param>
|
||||
var $element = $(element),
|
||||
form = $element.parents("form")[0],
|
||||
valInfo, rules, messages;
|
||||
|
||||
if (!form) { // Cannot do client-side validation without a form
|
||||
return;
|
||||
}
|
||||
|
||||
valInfo = validationInfo(form);
|
||||
valInfo.options.rules[element.name] = rules = {};
|
||||
valInfo.options.messages[element.name] = messages = {};
|
||||
|
||||
$.each(this.adapters, function () {
|
||||
var prefix = "data-val-" + this.name,
|
||||
message = $element.attr(prefix),
|
||||
paramValues = {};
|
||||
|
||||
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
|
||||
prefix += "-";
|
||||
|
||||
$.each(this.params, function () {
|
||||
paramValues[this] = $element.attr(prefix + this);
|
||||
});
|
||||
|
||||
this.adapt({
|
||||
element: element,
|
||||
form: form,
|
||||
message: message,
|
||||
params: paramValues,
|
||||
rules: rules,
|
||||
messages: messages
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(rules, { "__dummy__": true });
|
||||
|
||||
if (!skipAttach) {
|
||||
valInfo.attachValidation();
|
||||
}
|
||||
},
|
||||
|
||||
parse: function (selector) {
|
||||
/// <summary>
|
||||
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
|
||||
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
|
||||
/// attribute values.
|
||||
/// </summary>
|
||||
/// <param name="selector" type="String">Any valid jQuery selector.</param>
|
||||
|
||||
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
|
||||
// element with data-val=true
|
||||
var $selector = $(selector),
|
||||
$forms = $selector.parents()
|
||||
.addBack()
|
||||
.filter("form")
|
||||
.add($selector.find("form"))
|
||||
.has("[data-val=true]");
|
||||
|
||||
$selector.find("[data-val=true]").each(function () {
|
||||
$jQval.unobtrusive.parseElement(this, true);
|
||||
});
|
||||
|
||||
$forms.each(function () {
|
||||
var info = validationInfo(this);
|
||||
if (info) {
|
||||
info.attachValidation();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
adapters = $jQval.unobtrusive.adapters;
|
||||
|
||||
adapters.add = function (adapterName, params, fn) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
|
||||
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
|
||||
/// mmmm is the parameter name).</param>
|
||||
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
|
||||
/// attributes into jQuery Validate rules and/or messages.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
if (!fn) { // Called with no params, just a function
|
||||
fn = params;
|
||||
params = [];
|
||||
}
|
||||
this.push({ name: adapterName, params: params, adapt: fn });
|
||||
return this;
|
||||
};
|
||||
|
||||
adapters.addBool = function (adapterName, ruleName) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation rule has no parameter values.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
||||
/// of adapterName will be used instead.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, function (options) {
|
||||
setValidationValues(options, ruleName || adapterName, true);
|
||||
});
|
||||
};
|
||||
|
||||
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
|
||||
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
||||
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
||||
/// have a minimum value.</param>
|
||||
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
||||
/// have a maximum value.</param>
|
||||
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
|
||||
/// have both a minimum and maximum value.</param>
|
||||
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
||||
/// contains the minimum value. The default is "min".</param>
|
||||
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
||||
/// contains the maximum value. The default is "max".</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
|
||||
var min = options.params.min,
|
||||
max = options.params.max;
|
||||
|
||||
if (min && max) {
|
||||
setValidationValues(options, minMaxRuleName, [min, max]);
|
||||
}
|
||||
else if (min) {
|
||||
setValidationValues(options, minRuleName, min);
|
||||
}
|
||||
else if (max) {
|
||||
setValidationValues(options, maxRuleName, max);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
|
||||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
||||
/// the jQuery Validate validation rule has a single value.</summary>
|
||||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
||||
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
|
||||
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
|
||||
/// The default is "val".</param>
|
||||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
||||
/// of adapterName will be used instead.</param>
|
||||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
||||
return this.add(adapterName, [attribute || "val"], function (options) {
|
||||
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
|
||||
});
|
||||
};
|
||||
|
||||
$jQval.addMethod("__dummy__", function (value, element, params) {
|
||||
return true;
|
||||
});
|
||||
|
||||
$jQval.addMethod("regex", function (value, element, params) {
|
||||
var match;
|
||||
if (this.optional(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
match = new RegExp(params).exec(value);
|
||||
return (match && (match.index === 0) && (match[0].length === value.length));
|
||||
});
|
||||
|
||||
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
|
||||
var match;
|
||||
if (nonalphamin) {
|
||||
match = value.match(/\W/g);
|
||||
match = match && match.length >= nonalphamin;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
if ($jQval.methods.extension) {
|
||||
adapters.addSingleVal("accept", "mimtype");
|
||||
adapters.addSingleVal("extension", "extension");
|
||||
} else {
|
||||
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
|
||||
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
|
||||
// validating the extension, and ignore mime-type validations as they are not supported.
|
||||
adapters.addSingleVal("extension", "extension", "accept");
|
||||
}
|
||||
|
||||
adapters.addSingleVal("regex", "pattern");
|
||||
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
|
||||
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
|
||||
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
|
||||
adapters.add("equalto", ["other"], function (options) {
|
||||
var prefix = getModelPrefix(options.element.name),
|
||||
other = options.params.other,
|
||||
fullOtherName = appendModelPrefix(other, prefix),
|
||||
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
|
||||
|
||||
setValidationValues(options, "equalTo", element);
|
||||
});
|
||||
adapters.add("required", function (options) {
|
||||
// jQuery Validate equates "required" with "mandatory" for checkbox elements
|
||||
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
|
||||
setValidationValues(options, "required", true);
|
||||
}
|
||||
});
|
||||
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
|
||||
var value = {
|
||||
url: options.params.url,
|
||||
type: options.params.type || "GET",
|
||||
data: {}
|
||||
},
|
||||
prefix = getModelPrefix(options.element.name);
|
||||
|
||||
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
|
||||
var paramName = appendModelPrefix(fieldName, prefix);
|
||||
value.data[paramName] = function () {
|
||||
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
|
||||
// For checkboxes and radio buttons, only pick up values from checked fields.
|
||||
if (field.is(":checkbox")) {
|
||||
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
|
||||
}
|
||||
else if (field.is(":radio")) {
|
||||
return field.filter(":checked").val() || '';
|
||||
}
|
||||
return field.val();
|
||||
};
|
||||
});
|
||||
|
||||
setValidationValues(options, "remote", value);
|
||||
});
|
||||
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
|
||||
if (options.params.min) {
|
||||
setValidationValues(options, "minlength", options.params.min);
|
||||
}
|
||||
if (options.params.nonalphamin) {
|
||||
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
|
||||
}
|
||||
if (options.params.regex) {
|
||||
setValidationValues(options, "regex", options.params.regex);
|
||||
}
|
||||
});
|
||||
adapters.add("fileextensions", ["extensions"], function (options) {
|
||||
setValidationValues(options, "extension", options.params.extensions);
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$jQval.unobtrusive.parse(document);
|
||||
});
|
||||
|
||||
return $jQval.unobtrusive;
|
||||
}));
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "jquery-validation",
|
||||
"homepage": "https://jqueryvalidation.org/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jquery-validation/jquery-validation.git"
|
||||
},
|
||||
"authors": [
|
||||
"Jörn Zaefferer <joern.zaefferer@gmail.com>"
|
||||
],
|
||||
"description": "Form validation made easy",
|
||||
"main": "dist/jquery.validate.js",
|
||||
"keywords": [
|
||||
"forms",
|
||||
"validation",
|
||||
"validate"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"demo",
|
||||
"lib"
|
||||
],
|
||||
"dependencies": {
|
||||
"jquery": ">= 1.7.2"
|
||||
},
|
||||
"version": "1.17.0",
|
||||
"_release": "1.17.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.17.0",
|
||||
"commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772"
|
||||
},
|
||||
"_source": "https://github.com/jzaefferer/jquery-validation.git",
|
||||
"_target": "^1.17.0",
|
||||
"_originalSource": "jquery-validation",
|
||||
"_direct": true
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright Jörn Zaefferer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,1601 @@
|
|||
/*!
|
||||
* jQuery Validation Plugin v1.17.0
|
||||
*
|
||||
* https://jqueryvalidation.org/
|
||||
*
|
||||
* Copyright (c) 2017 Jörn Zaefferer
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function( factory ) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
define( ["jquery"], factory );
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
module.exports = factory( require( "jquery" ) );
|
||||
} else {
|
||||
factory( jQuery );
|
||||
}
|
||||
}(function( $ ) {
|
||||
|
||||
$.extend( $.fn, {
|
||||
|
||||
// https://jqueryvalidation.org/validate/
|
||||
validate: function( options ) {
|
||||
|
||||
// If nothing is selected, return nothing; can't chain anyway
|
||||
if ( !this.length ) {
|
||||
if ( options && options.debug && window.console ) {
|
||||
console.warn( "Nothing selected, can't validate, returning nothing." );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if a validator for this form was already created
|
||||
var validator = $.data( this[ 0 ], "validator" );
|
||||
if ( validator ) {
|
||||
return validator;
|
||||
}
|
||||
|
||||
// Add novalidate tag if HTML5.
|
||||
this.attr( "novalidate", "novalidate" );
|
||||
|
||||
validator = new $.validator( options, this[ 0 ] );
|
||||
$.data( this[ 0 ], "validator", validator );
|
||||
|
||||
if ( validator.settings.onsubmit ) {
|
||||
|
||||
this.on( "click.validate", ":submit", function( event ) {
|
||||
|
||||
// Track the used submit button to properly handle scripted
|
||||
// submits later.
|
||||
validator.submitButton = event.currentTarget;
|
||||
|
||||
// Allow suppressing validation by adding a cancel class to the submit button
|
||||
if ( $( this ).hasClass( "cancel" ) ) {
|
||||
validator.cancelSubmit = true;
|
||||
}
|
||||
|
||||
// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
|
||||
if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
|
||||
validator.cancelSubmit = true;
|
||||
}
|
||||
} );
|
||||
|
||||
// Validate the form on submit
|
||||
this.on( "submit.validate", function( event ) {
|
||||
if ( validator.settings.debug ) {
|
||||
|
||||
// Prevent form submit to be able to see console output
|
||||
event.preventDefault();
|
||||
}
|
||||
function handle() {
|
||||
var hidden, result;
|
||||
|
||||
// Insert a hidden input as a replacement for the missing submit button
|
||||
// The hidden input is inserted in two cases:
|
||||
// - A user defined a `submitHandler`
|
||||
// - There was a pending request due to `remote` method and `stopRequest()`
|
||||
// was called to submit the form in case it's valid
|
||||
if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
|
||||
hidden = $( "<input type='hidden'/>" )
|
||||
.attr( "name", validator.submitButton.name )
|
||||
.val( $( validator.submitButton ).val() )
|
||||
.appendTo( validator.currentForm );
|
||||
}
|
||||
|
||||
if ( validator.settings.submitHandler ) {
|
||||
result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
|
||||
if ( hidden ) {
|
||||
|
||||
// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
|
||||
hidden.remove();
|
||||
}
|
||||
if ( result !== undefined ) {
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prevent submit for invalid forms or custom submit handlers
|
||||
if ( validator.cancelSubmit ) {
|
||||
validator.cancelSubmit = false;
|
||||
return handle();
|
||||
}
|
||||
if ( validator.form() ) {
|
||||
if ( validator.pendingRequest ) {
|
||||
validator.formSubmitted = true;
|
||||
return false;
|
||||
}
|
||||
return handle();
|
||||
} else {
|
||||
validator.focusInvalid();
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return validator;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/valid/
|
||||
valid: function() {
|
||||
var valid, validator, errorList;
|
||||
|
||||
if ( $( this[ 0 ] ).is( "form" ) ) {
|
||||
valid = this.validate().form();
|
||||
} else {
|
||||
errorList = [];
|
||||
valid = true;
|
||||
validator = $( this[ 0 ].form ).validate();
|
||||
this.each( function() {
|
||||
valid = validator.element( this ) && valid;
|
||||
if ( !valid ) {
|
||||
errorList = errorList.concat( validator.errorList );
|
||||
}
|
||||
} );
|
||||
validator.errorList = errorList;
|
||||
}
|
||||
return valid;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/rules/
|
||||
rules: function( command, argument ) {
|
||||
var element = this[ 0 ],
|
||||
settings, staticRules, existingRules, data, param, filtered;
|
||||
|
||||
// If nothing is selected, return empty object; can't chain anyway
|
||||
if ( element == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !element.form && element.hasAttribute( "contenteditable" ) ) {
|
||||
element.form = this.closest( "form" )[ 0 ];
|
||||
element.name = this.attr( "name" );
|
||||
}
|
||||
|
||||
if ( element.form == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( command ) {
|
||||
settings = $.data( element.form, "validator" ).settings;
|
||||
staticRules = settings.rules;
|
||||
existingRules = $.validator.staticRules( element );
|
||||
switch ( command ) {
|
||||
case "add":
|
||||
$.extend( existingRules, $.validator.normalizeRule( argument ) );
|
||||
|
||||
// Remove messages from rules, but allow them to be set separately
|
||||
delete existingRules.messages;
|
||||
staticRules[ element.name ] = existingRules;
|
||||
if ( argument.messages ) {
|
||||
settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
if ( !argument ) {
|
||||
delete staticRules[ element.name ];
|
||||
return existingRules;
|
||||
}
|
||||
filtered = {};
|
||||
$.each( argument.split( /\s/ ), function( index, method ) {
|
||||
filtered[ method ] = existingRules[ method ];
|
||||
delete existingRules[ method ];
|
||||
} );
|
||||
return filtered;
|
||||
}
|
||||
}
|
||||
|
||||
data = $.validator.normalizeRules(
|
||||
$.extend(
|
||||
{},
|
||||
$.validator.classRules( element ),
|
||||
$.validator.attributeRules( element ),
|
||||
$.validator.dataRules( element ),
|
||||
$.validator.staticRules( element )
|
||||
), element );
|
||||
|
||||
// Make sure required is at front
|
||||
if ( data.required ) {
|
||||
param = data.required;
|
||||
delete data.required;
|
||||
data = $.extend( { required: param }, data );
|
||||
}
|
||||
|
||||
// Make sure remote is at back
|
||||
if ( data.remote ) {
|
||||
param = data.remote;
|
||||
delete data.remote;
|
||||
data = $.extend( data, { remote: param } );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
} );
|
||||
|
||||
// Custom selectors
|
||||
$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
|
||||
|
||||
// https://jqueryvalidation.org/blank-selector/
|
||||
blank: function( a ) {
|
||||
return !$.trim( "" + $( a ).val() );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/filled-selector/
|
||||
filled: function( a ) {
|
||||
var val = $( a ).val();
|
||||
return val !== null && !!$.trim( "" + val );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/unchecked-selector/
|
||||
unchecked: function( a ) {
|
||||
return !$( a ).prop( "checked" );
|
||||
}
|
||||
} );
|
||||
|
||||
// Constructor for validator
|
||||
$.validator = function( options, form ) {
|
||||
this.settings = $.extend( true, {}, $.validator.defaults, options );
|
||||
this.currentForm = form;
|
||||
this.init();
|
||||
};
|
||||
|
||||
// https://jqueryvalidation.org/jQuery.validator.format/
|
||||
$.validator.format = function( source, params ) {
|
||||
if ( arguments.length === 1 ) {
|
||||
return function() {
|
||||
var args = $.makeArray( arguments );
|
||||
args.unshift( source );
|
||||
return $.validator.format.apply( this, args );
|
||||
};
|
||||
}
|
||||
if ( params === undefined ) {
|
||||
return source;
|
||||
}
|
||||
if ( arguments.length > 2 && params.constructor !== Array ) {
|
||||
params = $.makeArray( arguments ).slice( 1 );
|
||||
}
|
||||
if ( params.constructor !== Array ) {
|
||||
params = [ params ];
|
||||
}
|
||||
$.each( params, function( i, n ) {
|
||||
source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
|
||||
return n;
|
||||
} );
|
||||
} );
|
||||
return source;
|
||||
};
|
||||
|
||||
$.extend( $.validator, {
|
||||
|
||||
defaults: {
|
||||
messages: {},
|
||||
groups: {},
|
||||
rules: {},
|
||||
errorClass: "error",
|
||||
pendingClass: "pending",
|
||||
validClass: "valid",
|
||||
errorElement: "label",
|
||||
focusCleanup: false,
|
||||
focusInvalid: true,
|
||||
errorContainer: $( [] ),
|
||||
errorLabelContainer: $( [] ),
|
||||
onsubmit: true,
|
||||
ignore: ":hidden",
|
||||
ignoreTitle: false,
|
||||
onfocusin: function( element ) {
|
||||
this.lastActive = element;
|
||||
|
||||
// Hide error label and remove error class on focus if enabled
|
||||
if ( this.settings.focusCleanup ) {
|
||||
if ( this.settings.unhighlight ) {
|
||||
this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
|
||||
}
|
||||
this.hideThese( this.errorsFor( element ) );
|
||||
}
|
||||
},
|
||||
onfocusout: function( element ) {
|
||||
if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
|
||||
this.element( element );
|
||||
}
|
||||
},
|
||||
onkeyup: function( element, event ) {
|
||||
|
||||
// Avoid revalidate the field when pressing one of the following keys
|
||||
// Shift => 16
|
||||
// Ctrl => 17
|
||||
// Alt => 18
|
||||
// Caps lock => 20
|
||||
// End => 35
|
||||
// Home => 36
|
||||
// Left arrow => 37
|
||||
// Up arrow => 38
|
||||
// Right arrow => 39
|
||||
// Down arrow => 40
|
||||
// Insert => 45
|
||||
// Num lock => 144
|
||||
// AltGr key => 225
|
||||
var excludedKeys = [
|
||||
16, 17, 18, 20, 35, 36, 37,
|
||||
38, 39, 40, 45, 144, 225
|
||||
];
|
||||
|
||||
if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
|
||||
return;
|
||||
} else if ( element.name in this.submitted || element.name in this.invalid ) {
|
||||
this.element( element );
|
||||
}
|
||||
},
|
||||
onclick: function( element ) {
|
||||
|
||||
// Click on selects, radiobuttons and checkboxes
|
||||
if ( element.name in this.submitted ) {
|
||||
this.element( element );
|
||||
|
||||
// Or option elements, check parent select in that case
|
||||
} else if ( element.parentNode.name in this.submitted ) {
|
||||
this.element( element.parentNode );
|
||||
}
|
||||
},
|
||||
highlight: function( element, errorClass, validClass ) {
|
||||
if ( element.type === "radio" ) {
|
||||
this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
|
||||
} else {
|
||||
$( element ).addClass( errorClass ).removeClass( validClass );
|
||||
}
|
||||
},
|
||||
unhighlight: function( element, errorClass, validClass ) {
|
||||
if ( element.type === "radio" ) {
|
||||
this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
|
||||
} else {
|
||||
$( element ).removeClass( errorClass ).addClass( validClass );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/jQuery.validator.setDefaults/
|
||||
setDefaults: function( settings ) {
|
||||
$.extend( $.validator.defaults, settings );
|
||||
},
|
||||
|
||||
messages: {
|
||||
required: "This field is required.",
|
||||
remote: "Please fix this field.",
|
||||
email: "Please enter a valid email address.",
|
||||
url: "Please enter a valid URL.",
|
||||
date: "Please enter a valid date.",
|
||||
dateISO: "Please enter a valid date (ISO).",
|
||||
number: "Please enter a valid number.",
|
||||
digits: "Please enter only digits.",
|
||||
equalTo: "Please enter the same value again.",
|
||||
maxlength: $.validator.format( "Please enter no more than {0} characters." ),
|
||||
minlength: $.validator.format( "Please enter at least {0} characters." ),
|
||||
rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
|
||||
range: $.validator.format( "Please enter a value between {0} and {1}." ),
|
||||
max: $.validator.format( "Please enter a value less than or equal to {0}." ),
|
||||
min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
|
||||
step: $.validator.format( "Please enter a multiple of {0}." )
|
||||
},
|
||||
|
||||
autoCreateRanges: false,
|
||||
|
||||
prototype: {
|
||||
|
||||
init: function() {
|
||||
this.labelContainer = $( this.settings.errorLabelContainer );
|
||||
this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
|
||||
this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
|
||||
this.submitted = {};
|
||||
this.valueCache = {};
|
||||
this.pendingRequest = 0;
|
||||
this.pending = {};
|
||||
this.invalid = {};
|
||||
this.reset();
|
||||
|
||||
var groups = ( this.groups = {} ),
|
||||
rules;
|
||||
$.each( this.settings.groups, function( key, value ) {
|
||||
if ( typeof value === "string" ) {
|
||||
value = value.split( /\s/ );
|
||||
}
|
||||
$.each( value, function( index, name ) {
|
||||
groups[ name ] = key;
|
||||
} );
|
||||
} );
|
||||
rules = this.settings.rules;
|
||||
$.each( rules, function( key, value ) {
|
||||
rules[ key ] = $.validator.normalizeRule( value );
|
||||
} );
|
||||
|
||||
function delegate( event ) {
|
||||
|
||||
// Set form expando on contenteditable
|
||||
if ( !this.form && this.hasAttribute( "contenteditable" ) ) {
|
||||
this.form = $( this ).closest( "form" )[ 0 ];
|
||||
this.name = $( this ).attr( "name" );
|
||||
}
|
||||
|
||||
var validator = $.data( this.form, "validator" ),
|
||||
eventType = "on" + event.type.replace( /^validate/, "" ),
|
||||
settings = validator.settings;
|
||||
if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
|
||||
settings[ eventType ].call( validator, this, event );
|
||||
}
|
||||
}
|
||||
|
||||
$( this.currentForm )
|
||||
.on( "focusin.validate focusout.validate keyup.validate",
|
||||
":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
|
||||
"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
|
||||
"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
|
||||
"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
|
||||
|
||||
// Support: Chrome, oldIE
|
||||
// "select" is provided as event.target when clicking a option
|
||||
.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
|
||||
|
||||
if ( this.settings.invalidHandler ) {
|
||||
$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
|
||||
}
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/Validator.form/
|
||||
form: function() {
|
||||
this.checkForm();
|
||||
$.extend( this.submitted, this.errorMap );
|
||||
this.invalid = $.extend( {}, this.errorMap );
|
||||
if ( !this.valid() ) {
|
||||
$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
|
||||
}
|
||||
this.showErrors();
|
||||
return this.valid();
|
||||
},
|
||||
|
||||
checkForm: function() {
|
||||
this.prepareForm();
|
||||
for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
|
||||
this.check( elements[ i ] );
|
||||
}
|
||||
return this.valid();
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/Validator.element/
|
||||
element: function( element ) {
|
||||
var cleanElement = this.clean( element ),
|
||||
checkElement = this.validationTargetFor( cleanElement ),
|
||||
v = this,
|
||||
result = true,
|
||||
rs, group;
|
||||
|
||||
if ( checkElement === undefined ) {
|
||||
delete this.invalid[ cleanElement.name ];
|
||||
} else {
|
||||
this.prepareElement( checkElement );
|
||||
this.currentElements = $( checkElement );
|
||||
|
||||
// If this element is grouped, then validate all group elements already
|
||||
// containing a value
|
||||
group = this.groups[ checkElement.name ];
|
||||
if ( group ) {
|
||||
$.each( this.groups, function( name, testgroup ) {
|
||||
if ( testgroup === group && name !== checkElement.name ) {
|
||||
cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
|
||||
if ( cleanElement && cleanElement.name in v.invalid ) {
|
||||
v.currentElements.push( cleanElement );
|
||||
result = v.check( cleanElement ) && result;
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
rs = this.check( checkElement ) !== false;
|
||||
result = result && rs;
|
||||
if ( rs ) {
|
||||
this.invalid[ checkElement.name ] = false;
|
||||
} else {
|
||||
this.invalid[ checkElement.name ] = true;
|
||||
}
|
||||
|
||||
if ( !this.numberOfInvalids() ) {
|
||||
|
||||
// Hide error containers on last error
|
||||
this.toHide = this.toHide.add( this.containers );
|
||||
}
|
||||
this.showErrors();
|
||||
|
||||
// Add aria-invalid status for screen readers
|
||||
$( element ).attr( "aria-invalid", !rs );
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/Validator.showErrors/
|
||||
showErrors: function( errors ) {
|
||||
if ( errors ) {
|
||||
var validator = this;
|
||||
|
||||
// Add items to error list and map
|
||||
$.extend( this.errorMap, errors );
|
||||
this.errorList = $.map( this.errorMap, function( message, name ) {
|
||||
return {
|
||||
message: message,
|
||||
element: validator.findByName( name )[ 0 ]
|
||||
};
|
||||
} );
|
||||
|
||||
// Remove items from success list
|
||||
this.successList = $.grep( this.successList, function( element ) {
|
||||
return !( element.name in errors );
|
||||
} );
|
||||
}
|
||||
if ( this.settings.showErrors ) {
|
||||
this.settings.showErrors.call( this, this.errorMap, this.errorList );
|
||||
} else {
|
||||
this.defaultShowErrors();
|
||||
}
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/Validator.resetForm/
|
||||
resetForm: function() {
|
||||
if ( $.fn.resetForm ) {
|
||||
$( this.currentForm ).resetForm();
|
||||
}
|
||||
this.invalid = {};
|
||||
this.submitted = {};
|
||||
this.prepareForm();
|
||||
this.hideErrors();
|
||||
var elements = this.elements()
|
||||
.removeData( "previousValue" )
|
||||
.removeAttr( "aria-invalid" );
|
||||
|
||||
this.resetElements( elements );
|
||||
},
|
||||
|
||||
resetElements: function( elements ) {
|
||||
var i;
|
||||
|
||||
if ( this.settings.unhighlight ) {
|
||||
for ( i = 0; elements[ i ]; i++ ) {
|
||||
this.settings.unhighlight.call( this, elements[ i ],
|
||||
this.settings.errorClass, "" );
|
||||
this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
|
||||
}
|
||||
} else {
|
||||
elements
|
||||
.removeClass( this.settings.errorClass )
|
||||
.removeClass( this.settings.validClass );
|
||||
}
|
||||
},
|
||||
|
||||
numberOfInvalids: function() {
|
||||
return this.objectLength( this.invalid );
|
||||
},
|
||||
|
||||
objectLength: function( obj ) {
|
||||
/* jshint unused: false */
|
||||
var count = 0,
|
||||
i;
|
||||
for ( i in obj ) {
|
||||
|
||||
// This check allows counting elements with empty error
|
||||
// message as invalid elements
|
||||
if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
hideErrors: function() {
|
||||
this.hideThese( this.toHide );
|
||||
},
|
||||
|
||||
hideThese: function( errors ) {
|
||||
errors.not( this.containers ).text( "" );
|
||||
this.addWrapper( errors ).hide();
|
||||
},
|
||||
|
||||
valid: function() {
|
||||
return this.size() === 0;
|
||||
},
|
||||
|
||||
size: function() {
|
||||
return this.errorList.length;
|
||||
},
|
||||
|
||||
focusInvalid: function() {
|
||||
if ( this.settings.focusInvalid ) {
|
||||
try {
|
||||
$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
|
||||
.filter( ":visible" )
|
||||
.focus()
|
||||
|
||||
// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
|
||||
.trigger( "focusin" );
|
||||
} catch ( e ) {
|
||||
|
||||
// Ignore IE throwing errors when focusing hidden elements
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
findLastActive: function() {
|
||||
var lastActive = this.lastActive;
|
||||
return lastActive && $.grep( this.errorList, function( n ) {
|
||||
return n.element.name === lastActive.name;
|
||||
} ).length === 1 && lastActive;
|
||||
},
|
||||
|
||||
elements: function() {
|
||||
var validator = this,
|
||||
rulesCache = {};
|
||||
|
||||
// Select all valid inputs inside the form (no submit or reset buttons)
|
||||
return $( this.currentForm )
|
||||
.find( "input, select, textarea, [contenteditable]" )
|
||||
.not( ":submit, :reset, :image, :disabled" )
|
||||
.not( this.settings.ignore )
|
||||
.filter( function() {
|
||||
var name = this.name || $( this ).attr( "name" ); // For contenteditable
|
||||
if ( !name && validator.settings.debug && window.console ) {
|
||||
console.error( "%o has no name assigned", this );
|
||||
}
|
||||
|
||||
// Set form expando on contenteditable
|
||||
if ( this.hasAttribute( "contenteditable" ) ) {
|
||||
this.form = $( this ).closest( "form" )[ 0 ];
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// Select only the first element for each name, and only those with rules specified
|
||||
if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rulesCache[ name ] = true;
|
||||
return true;
|
||||
} );
|
||||
},
|
||||
|
||||
clean: function( selector ) {
|
||||
return $( selector )[ 0 ];
|
||||
},
|
||||
|
||||
errors: function() {
|
||||
var errorClass = this.settings.errorClass.split( " " ).join( "." );
|
||||
return $( this.settings.errorElement + "." + errorClass, this.errorContext );
|
||||
},
|
||||
|
||||
resetInternals: function() {
|
||||
this.successList = [];
|
||||
this.errorList = [];
|
||||
this.errorMap = {};
|
||||
this.toShow = $( [] );
|
||||
this.toHide = $( [] );
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this.resetInternals();
|
||||
this.currentElements = $( [] );
|
||||
},
|
||||
|
||||
prepareForm: function() {
|
||||
this.reset();
|
||||
this.toHide = this.errors().add( this.containers );
|
||||
},
|
||||
|
||||
prepareElement: function( element ) {
|
||||
this.reset();
|
||||
this.toHide = this.errorsFor( element );
|
||||
},
|
||||
|
||||
elementValue: function( element ) {
|
||||
var $element = $( element ),
|
||||
type = element.type,
|
||||
val, idx;
|
||||
|
||||
if ( type === "radio" || type === "checkbox" ) {
|
||||
return this.findByName( element.name ).filter( ":checked" ).val();
|
||||
} else if ( type === "number" && typeof element.validity !== "undefined" ) {
|
||||
return element.validity.badInput ? "NaN" : $element.val();
|
||||
}
|
||||
|
||||
if ( element.hasAttribute( "contenteditable" ) ) {
|
||||
val = $element.text();
|
||||
} else {
|
||||
val = $element.val();
|
||||
}
|
||||
|
||||
if ( type === "file" ) {
|
||||
|
||||
// Modern browser (chrome & safari)
|
||||
if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
|
||||
return val.substr( 12 );
|
||||
}
|
||||
|
||||
// Legacy browsers
|
||||
// Unix-based path
|
||||
idx = val.lastIndexOf( "/" );
|
||||
if ( idx >= 0 ) {
|
||||
return val.substr( idx + 1 );
|
||||
}
|
||||
|
||||
// Windows-based path
|
||||
idx = val.lastIndexOf( "\\" );
|
||||
if ( idx >= 0 ) {
|
||||
return val.substr( idx + 1 );
|
||||
}
|
||||
|
||||
// Just the file name
|
||||
return val;
|
||||
}
|
||||
|
||||
if ( typeof val === "string" ) {
|
||||
return val.replace( /\r/g, "" );
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
check: function( element ) {
|
||||
element = this.validationTargetFor( this.clean( element ) );
|
||||
|
||||
var rules = $( element ).rules(),
|
||||
rulesCount = $.map( rules, function( n, i ) {
|
||||
return i;
|
||||
} ).length,
|
||||
dependencyMismatch = false,
|
||||
val = this.elementValue( element ),
|
||||
result, method, rule, normalizer;
|
||||
|
||||
// Prioritize the local normalizer defined for this element over the global one
|
||||
// if the former exists, otherwise user the global one in case it exists.
|
||||
if ( typeof rules.normalizer === "function" ) {
|
||||
normalizer = rules.normalizer;
|
||||
} else if ( typeof this.settings.normalizer === "function" ) {
|
||||
normalizer = this.settings.normalizer;
|
||||
}
|
||||
|
||||
// If normalizer is defined, then call it to retreive the changed value instead
|
||||
// of using the real one.
|
||||
// Note that `this` in the normalizer is `element`.
|
||||
if ( normalizer ) {
|
||||
val = normalizer.call( element, val );
|
||||
|
||||
if ( typeof val !== "string" ) {
|
||||
throw new TypeError( "The normalizer should return a string value." );
|
||||
}
|
||||
|
||||
// Delete the normalizer from rules to avoid treating it as a pre-defined method.
|
||||
delete rules.normalizer;
|
||||
}
|
||||
|
||||
for ( method in rules ) {
|
||||
rule = { method: method, parameters: rules[ method ] };
|
||||
try {
|
||||
result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
|
||||
|
||||
// If a method indicates that the field is optional and therefore valid,
|
||||
// don't mark it as valid when there are no other rules
|
||||
if ( result === "dependency-mismatch" && rulesCount === 1 ) {
|
||||
dependencyMismatch = true;
|
||||
continue;
|
||||
}
|
||||
dependencyMismatch = false;
|
||||
|
||||
if ( result === "pending" ) {
|
||||
this.toHide = this.toHide.not( this.errorsFor( element ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !result ) {
|
||||
this.formatAndAdd( element, rule );
|
||||
return false;
|
||||
}
|
||||
} catch ( e ) {
|
||||
if ( this.settings.debug && window.console ) {
|
||||
console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
|
||||
}
|
||||
if ( e instanceof TypeError ) {
|
||||
e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if ( dependencyMismatch ) {
|
||||
return;
|
||||
}
|
||||
if ( this.objectLength( rules ) ) {
|
||||
this.successList.push( element );
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
// Return the custom message for the given element and validation method
|
||||
// specified in the element's HTML5 data attribute
|
||||
// return the generic message if present and no method specific message is present
|
||||
customDataMessage: function( element, method ) {
|
||||
return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
|
||||
method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
|
||||
},
|
||||
|
||||
// Return the custom message for the given element name and validation method
|
||||
customMessage: function( name, method ) {
|
||||
var m = this.settings.messages[ name ];
|
||||
return m && ( m.constructor === String ? m : m[ method ] );
|
||||
},
|
||||
|
||||
// Return the first defined argument, allowing empty strings
|
||||
findDefined: function() {
|
||||
for ( var i = 0; i < arguments.length; i++ ) {
|
||||
if ( arguments[ i ] !== undefined ) {
|
||||
return arguments[ i ];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
// The second parameter 'rule' used to be a string, and extended to an object literal
|
||||
// of the following form:
|
||||
// rule = {
|
||||
// method: "method name",
|
||||
// parameters: "the given method parameters"
|
||||
// }
|
||||
//
|
||||
// The old behavior still supported, kept to maintain backward compatibility with
|
||||
// old code, and will be removed in the next major release.
|
||||
defaultMessage: function( element, rule ) {
|
||||
if ( typeof rule === "string" ) {
|
||||
rule = { method: rule };
|
||||
}
|
||||
|
||||
var message = this.findDefined(
|
||||
this.customMessage( element.name, rule.method ),
|
||||
this.customDataMessage( element, rule.method ),
|
||||
|
||||
// 'title' is never undefined, so handle empty string as undefined
|
||||
!this.settings.ignoreTitle && element.title || undefined,
|
||||
$.validator.messages[ rule.method ],
|
||||
"<strong>Warning: No message defined for " + element.name + "</strong>"
|
||||
),
|
||||
theregex = /\$?\{(\d+)\}/g;
|
||||
if ( typeof message === "function" ) {
|
||||
message = message.call( this, rule.parameters, element );
|
||||
} else if ( theregex.test( message ) ) {
|
||||
message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
|
||||
}
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
formatAndAdd: function( element, rule ) {
|
||||
var message = this.defaultMessage( element, rule );
|
||||
|
||||
this.errorList.push( {
|
||||
message: message,
|
||||
element: element,
|
||||
method: rule.method
|
||||
} );
|
||||
|
||||
this.errorMap[ element.name ] = message;
|
||||
this.submitted[ element.name ] = message;
|
||||
},
|
||||
|
||||
addWrapper: function( toToggle ) {
|
||||
if ( this.settings.wrapper ) {
|
||||
toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
|
||||
}
|
||||
return toToggle;
|
||||
},
|
||||
|
||||
defaultShowErrors: function() {
|
||||
var i, elements, error;
|
||||
for ( i = 0; this.errorList[ i ]; i++ ) {
|
||||
error = this.errorList[ i ];
|
||||
if ( this.settings.highlight ) {
|
||||
this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
|
||||
}
|
||||
this.showLabel( error.element, error.message );
|
||||
}
|
||||
if ( this.errorList.length ) {
|
||||
this.toShow = this.toShow.add( this.containers );
|
||||
}
|
||||
if ( this.settings.success ) {
|
||||
for ( i = 0; this.successList[ i ]; i++ ) {
|
||||
this.showLabel( this.successList[ i ] );
|
||||
}
|
||||
}
|
||||
if ( this.settings.unhighlight ) {
|
||||
for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
|
||||
this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
|
||||
}
|
||||
}
|
||||
this.toHide = this.toHide.not( this.toShow );
|
||||
this.hideErrors();
|
||||
this.addWrapper( this.toShow ).show();
|
||||
},
|
||||
|
||||
validElements: function() {
|
||||
return this.currentElements.not( this.invalidElements() );
|
||||
},
|
||||
|
||||
invalidElements: function() {
|
||||
return $( this.errorList ).map( function() {
|
||||
return this.element;
|
||||
} );
|
||||
},
|
||||
|
||||
showLabel: function( element, message ) {
|
||||
var place, group, errorID, v,
|
||||
error = this.errorsFor( element ),
|
||||
elementID = this.idOrName( element ),
|
||||
describedBy = $( element ).attr( "aria-describedby" );
|
||||
|
||||
if ( error.length ) {
|
||||
|
||||
// Refresh error/success class
|
||||
error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
|
||||
|
||||
// Replace message on existing label
|
||||
error.html( message );
|
||||
} else {
|
||||
|
||||
// Create error element
|
||||
error = $( "<" + this.settings.errorElement + ">" )
|
||||
.attr( "id", elementID + "-error" )
|
||||
.addClass( this.settings.errorClass )
|
||||
.html( message || "" );
|
||||
|
||||
// Maintain reference to the element to be placed into the DOM
|
||||
place = error;
|
||||
if ( this.settings.wrapper ) {
|
||||
|
||||
// Make sure the element is visible, even in IE
|
||||
// actually showing the wrapped element is handled elsewhere
|
||||
place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
|
||||
}
|
||||
if ( this.labelContainer.length ) {
|
||||
this.labelContainer.append( place );
|
||||
} else if ( this.settings.errorPlacement ) {
|
||||
this.settings.errorPlacement.call( this, place, $( element ) );
|
||||
} else {
|
||||
place.insertAfter( element );
|
||||
}
|
||||
|
||||
// Link error back to the element
|
||||
if ( error.is( "label" ) ) {
|
||||
|
||||
// If the error is a label, then associate using 'for'
|
||||
error.attr( "for", elementID );
|
||||
|
||||
// If the element is not a child of an associated label, then it's necessary
|
||||
// to explicitly apply aria-describedby
|
||||
} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
|
||||
errorID = error.attr( "id" );
|
||||
|
||||
// Respect existing non-error aria-describedby
|
||||
if ( !describedBy ) {
|
||||
describedBy = errorID;
|
||||
} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
|
||||
|
||||
// Add to end of list if not already present
|
||||
describedBy += " " + errorID;
|
||||
}
|
||||
$( element ).attr( "aria-describedby", describedBy );
|
||||
|
||||
// If this element is grouped, then assign to all elements in the same group
|
||||
group = this.groups[ element.name ];
|
||||
if ( group ) {
|
||||
v = this;
|
||||
$.each( v.groups, function( name, testgroup ) {
|
||||
if ( testgroup === group ) {
|
||||
$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
|
||||
.attr( "aria-describedby", error.attr( "id" ) );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !message && this.settings.success ) {
|
||||
error.text( "" );
|
||||
if ( typeof this.settings.success === "string" ) {
|
||||
error.addClass( this.settings.success );
|
||||
} else {
|
||||
this.settings.success( error, element );
|
||||
}
|
||||
}
|
||||
this.toShow = this.toShow.add( error );
|
||||
},
|
||||
|
||||
errorsFor: function( element ) {
|
||||
var name = this.escapeCssMeta( this.idOrName( element ) ),
|
||||
describer = $( element ).attr( "aria-describedby" ),
|
||||
selector = "label[for='" + name + "'], label[for='" + name + "'] *";
|
||||
|
||||
// 'aria-describedby' should directly reference the error element
|
||||
if ( describer ) {
|
||||
selector = selector + ", #" + this.escapeCssMeta( describer )
|
||||
.replace( /\s+/g, ", #" );
|
||||
}
|
||||
|
||||
return this
|
||||
.errors()
|
||||
.filter( selector );
|
||||
},
|
||||
|
||||
// See https://api.jquery.com/category/selectors/, for CSS
|
||||
// meta-characters that should be escaped in order to be used with JQuery
|
||||
// as a literal part of a name/id or any selector.
|
||||
escapeCssMeta: function( string ) {
|
||||
return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
|
||||
},
|
||||
|
||||
idOrName: function( element ) {
|
||||
return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
|
||||
},
|
||||
|
||||
validationTargetFor: function( element ) {
|
||||
|
||||
// If radio/checkbox, validate first element in group instead
|
||||
if ( this.checkable( element ) ) {
|
||||
element = this.findByName( element.name );
|
||||
}
|
||||
|
||||
// Always apply ignore filter
|
||||
return $( element ).not( this.settings.ignore )[ 0 ];
|
||||
},
|
||||
|
||||
checkable: function( element ) {
|
||||
return ( /radio|checkbox/i ).test( element.type );
|
||||
},
|
||||
|
||||
findByName: function( name ) {
|
||||
return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
|
||||
},
|
||||
|
||||
getLength: function( value, element ) {
|
||||
switch ( element.nodeName.toLowerCase() ) {
|
||||
case "select":
|
||||
return $( "option:selected", element ).length;
|
||||
case "input":
|
||||
if ( this.checkable( element ) ) {
|
||||
return this.findByName( element.name ).filter( ":checked" ).length;
|
||||
}
|
||||
}
|
||||
return value.length;
|
||||
},
|
||||
|
||||
depend: function( param, element ) {
|
||||
return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
|
||||
},
|
||||
|
||||
dependTypes: {
|
||||
"boolean": function( param ) {
|
||||
return param;
|
||||
},
|
||||
"string": function( param, element ) {
|
||||
return !!$( param, element.form ).length;
|
||||
},
|
||||
"function": function( param, element ) {
|
||||
return param( element );
|
||||
}
|
||||
},
|
||||
|
||||
optional: function( element ) {
|
||||
var val = this.elementValue( element );
|
||||
return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
|
||||
},
|
||||
|
||||
startRequest: function( element ) {
|
||||
if ( !this.pending[ element.name ] ) {
|
||||
this.pendingRequest++;
|
||||
$( element ).addClass( this.settings.pendingClass );
|
||||
this.pending[ element.name ] = true;
|
||||
}
|
||||
},
|
||||
|
||||
stopRequest: function( element, valid ) {
|
||||
this.pendingRequest--;
|
||||
|
||||
// Sometimes synchronization fails, make sure pendingRequest is never < 0
|
||||
if ( this.pendingRequest < 0 ) {
|
||||
this.pendingRequest = 0;
|
||||
}
|
||||
delete this.pending[ element.name ];
|
||||
$( element ).removeClass( this.settings.pendingClass );
|
||||
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
|
||||
$( this.currentForm ).submit();
|
||||
|
||||
// Remove the hidden input that was used as a replacement for the
|
||||
// missing submit button. The hidden input is added by `handle()`
|
||||
// to ensure that the value of the used submit button is passed on
|
||||
// for scripted submits triggered by this method
|
||||
if ( this.submitButton ) {
|
||||
$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
|
||||
}
|
||||
|
||||
this.formSubmitted = false;
|
||||
} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
|
||||
$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
|
||||
this.formSubmitted = false;
|
||||
}
|
||||
},
|
||||
|
||||
previousValue: function( element, method ) {
|
||||
method = typeof method === "string" && method || "remote";
|
||||
|
||||
return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
|
||||
old: null,
|
||||
valid: true,
|
||||
message: this.defaultMessage( element, { method: method } )
|
||||
} );
|
||||
},
|
||||
|
||||
// Cleans up all forms and elements, removes validator-specific events
|
||||
destroy: function() {
|
||||
this.resetForm();
|
||||
|
||||
$( this.currentForm )
|
||||
.off( ".validate" )
|
||||
.removeData( "validator" )
|
||||
.find( ".validate-equalTo-blur" )
|
||||
.off( ".validate-equalTo" )
|
||||
.removeClass( "validate-equalTo-blur" );
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
classRuleSettings: {
|
||||
required: { required: true },
|
||||
email: { email: true },
|
||||
url: { url: true },
|
||||
date: { date: true },
|
||||
dateISO: { dateISO: true },
|
||||
number: { number: true },
|
||||
digits: { digits: true },
|
||||
creditcard: { creditcard: true }
|
||||
},
|
||||
|
||||
addClassRules: function( className, rules ) {
|
||||
if ( className.constructor === String ) {
|
||||
this.classRuleSettings[ className ] = rules;
|
||||
} else {
|
||||
$.extend( this.classRuleSettings, className );
|
||||
}
|
||||
},
|
||||
|
||||
classRules: function( element ) {
|
||||
var rules = {},
|
||||
classes = $( element ).attr( "class" );
|
||||
|
||||
if ( classes ) {
|
||||
$.each( classes.split( " " ), function() {
|
||||
if ( this in $.validator.classRuleSettings ) {
|
||||
$.extend( rules, $.validator.classRuleSettings[ this ] );
|
||||
}
|
||||
} );
|
||||
}
|
||||
return rules;
|
||||
},
|
||||
|
||||
normalizeAttributeRule: function( rules, type, method, value ) {
|
||||
|
||||
// Convert the value to a number for number inputs, and for text for backwards compability
|
||||
// allows type="date" and others to be compared as strings
|
||||
if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
|
||||
value = Number( value );
|
||||
|
||||
// Support Opera Mini, which returns NaN for undefined minlength
|
||||
if ( isNaN( value ) ) {
|
||||
value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if ( value || value === 0 ) {
|
||||
rules[ method ] = value;
|
||||
} else if ( type === method && type !== "range" ) {
|
||||
|
||||
// Exception: the jquery validate 'range' method
|
||||
// does not test for the html5 'range' type
|
||||
rules[ method ] = true;
|
||||
}
|
||||
},
|
||||
|
||||
attributeRules: function( element ) {
|
||||
var rules = {},
|
||||
$element = $( element ),
|
||||
type = element.getAttribute( "type" ),
|
||||
method, value;
|
||||
|
||||
for ( method in $.validator.methods ) {
|
||||
|
||||
// Support for <input required> in both html5 and older browsers
|
||||
if ( method === "required" ) {
|
||||
value = element.getAttribute( method );
|
||||
|
||||
// Some browsers return an empty string for the required attribute
|
||||
// and non-HTML5 browsers might have required="" markup
|
||||
if ( value === "" ) {
|
||||
value = true;
|
||||
}
|
||||
|
||||
// Force non-HTML5 browsers to return bool
|
||||
value = !!value;
|
||||
} else {
|
||||
value = $element.attr( method );
|
||||
}
|
||||
|
||||
this.normalizeAttributeRule( rules, type, method, value );
|
||||
}
|
||||
|
||||
// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
|
||||
if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
|
||||
delete rules.maxlength;
|
||||
}
|
||||
|
||||
return rules;
|
||||
},
|
||||
|
||||
dataRules: function( element ) {
|
||||
var rules = {},
|
||||
$element = $( element ),
|
||||
type = element.getAttribute( "type" ),
|
||||
method, value;
|
||||
|
||||
for ( method in $.validator.methods ) {
|
||||
value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
|
||||
this.normalizeAttributeRule( rules, type, method, value );
|
||||
}
|
||||
return rules;
|
||||
},
|
||||
|
||||
staticRules: function( element ) {
|
||||
var rules = {},
|
||||
validator = $.data( element.form, "validator" );
|
||||
|
||||
if ( validator.settings.rules ) {
|
||||
rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
|
||||
}
|
||||
return rules;
|
||||
},
|
||||
|
||||
normalizeRules: function( rules, element ) {
|
||||
|
||||
// Handle dependency check
|
||||
$.each( rules, function( prop, val ) {
|
||||
|
||||
// Ignore rule when param is explicitly false, eg. required:false
|
||||
if ( val === false ) {
|
||||
delete rules[ prop ];
|
||||
return;
|
||||
}
|
||||
if ( val.param || val.depends ) {
|
||||
var keepRule = true;
|
||||
switch ( typeof val.depends ) {
|
||||
case "string":
|
||||
keepRule = !!$( val.depends, element.form ).length;
|
||||
break;
|
||||
case "function":
|
||||
keepRule = val.depends.call( element, element );
|
||||
break;
|
||||
}
|
||||
if ( keepRule ) {
|
||||
rules[ prop ] = val.param !== undefined ? val.param : true;
|
||||
} else {
|
||||
$.data( element.form, "validator" ).resetElements( $( element ) );
|
||||
delete rules[ prop ];
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
// Evaluate parameters
|
||||
$.each( rules, function( rule, parameter ) {
|
||||
rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
|
||||
} );
|
||||
|
||||
// Clean number parameters
|
||||
$.each( [ "minlength", "maxlength" ], function() {
|
||||
if ( rules[ this ] ) {
|
||||
rules[ this ] = Number( rules[ this ] );
|
||||
}
|
||||
} );
|
||||
$.each( [ "rangelength", "range" ], function() {
|
||||
var parts;
|
||||
if ( rules[ this ] ) {
|
||||
if ( $.isArray( rules[ this ] ) ) {
|
||||
rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
|
||||
} else if ( typeof rules[ this ] === "string" ) {
|
||||
parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
|
||||
rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
if ( $.validator.autoCreateRanges ) {
|
||||
|
||||
// Auto-create ranges
|
||||
if ( rules.min != null && rules.max != null ) {
|
||||
rules.range = [ rules.min, rules.max ];
|
||||
delete rules.min;
|
||||
delete rules.max;
|
||||
}
|
||||
if ( rules.minlength != null && rules.maxlength != null ) {
|
||||
rules.rangelength = [ rules.minlength, rules.maxlength ];
|
||||
delete rules.minlength;
|
||||
delete rules.maxlength;
|
||||
}
|
||||
}
|
||||
|
||||
return rules;
|
||||
},
|
||||
|
||||
// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
|
||||
normalizeRule: function( data ) {
|
||||
if ( typeof data === "string" ) {
|
||||
var transformed = {};
|
||||
$.each( data.split( /\s/ ), function() {
|
||||
transformed[ this ] = true;
|
||||
} );
|
||||
data = transformed;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/jQuery.validator.addMethod/
|
||||
addMethod: function( name, method, message ) {
|
||||
$.validator.methods[ name ] = method;
|
||||
$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
|
||||
if ( method.length < 3 ) {
|
||||
$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
|
||||
}
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/jQuery.validator.methods/
|
||||
methods: {
|
||||
|
||||
// https://jqueryvalidation.org/required-method/
|
||||
required: function( value, element, param ) {
|
||||
|
||||
// Check if dependency is met
|
||||
if ( !this.depend( param, element ) ) {
|
||||
return "dependency-mismatch";
|
||||
}
|
||||
if ( element.nodeName.toLowerCase() === "select" ) {
|
||||
|
||||
// Could be an array for select-multiple or a string, both are fine this way
|
||||
var val = $( element ).val();
|
||||
return val && val.length > 0;
|
||||
}
|
||||
if ( this.checkable( element ) ) {
|
||||
return this.getLength( value, element ) > 0;
|
||||
}
|
||||
return value.length > 0;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/email-method/
|
||||
email: function( value, element ) {
|
||||
|
||||
// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
|
||||
// Retrieved 2014-01-14
|
||||
// If you have a problem with this implementation, report a bug against the above spec
|
||||
// Or use custom methods to implement your own email validation
|
||||
return 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 );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/url-method/
|
||||
url: function( value, element ) {
|
||||
|
||||
// Copyright (c) 2010-2013 Diego Perini, MIT licensed
|
||||
// https://gist.github.com/dperini/729294
|
||||
// see also https://mathiasbynens.be/demo/url-regex
|
||||
// modified to allow protocol-relative URLs
|
||||
return 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 );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/date-method/
|
||||
date: function( value, element ) {
|
||||
return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/dateISO-method/
|
||||
dateISO: function( value, element ) {
|
||||
return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/number-method/
|
||||
number: function( value, element ) {
|
||||
return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/digits-method/
|
||||
digits: function( value, element ) {
|
||||
return this.optional( element ) || /^\d+$/.test( value );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/minlength-method/
|
||||
minlength: function( value, element, param ) {
|
||||
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
|
||||
return this.optional( element ) || length >= param;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/maxlength-method/
|
||||
maxlength: function( value, element, param ) {
|
||||
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
|
||||
return this.optional( element ) || length <= param;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/rangelength-method/
|
||||
rangelength: function( value, element, param ) {
|
||||
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
|
||||
return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/min-method/
|
||||
min: function( value, element, param ) {
|
||||
return this.optional( element ) || value >= param;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/max-method/
|
||||
max: function( value, element, param ) {
|
||||
return this.optional( element ) || value <= param;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/range-method/
|
||||
range: function( value, element, param ) {
|
||||
return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/step-method/
|
||||
step: function( value, element, param ) {
|
||||
var type = $( element ).attr( "type" ),
|
||||
errorMessage = "Step attribute on input type " + type + " is not supported.",
|
||||
supportedTypes = [ "text", "number", "range" ],
|
||||
re = new RegExp( "\\b" + type + "\\b" ),
|
||||
notSupported = type && !re.test( supportedTypes.join() ),
|
||||
decimalPlaces = function( num ) {
|
||||
var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
|
||||
if ( !match ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Number of digits right of decimal point.
|
||||
return match[ 1 ] ? match[ 1 ].length : 0;
|
||||
},
|
||||
toInt = function( num ) {
|
||||
return Math.round( num * Math.pow( 10, decimals ) );
|
||||
},
|
||||
valid = true,
|
||||
decimals;
|
||||
|
||||
// Works only for text, number and range input types
|
||||
// TODO find a way to support input types date, datetime, datetime-local, month, time and week
|
||||
if ( notSupported ) {
|
||||
throw new Error( errorMessage );
|
||||
}
|
||||
|
||||
decimals = decimalPlaces( param );
|
||||
|
||||
// Value can't have too many decimals
|
||||
if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return this.optional( element ) || valid;
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/equalTo-method/
|
||||
equalTo: function( value, element, param ) {
|
||||
|
||||
// Bind to the blur event of the target in order to revalidate whenever the target field is updated
|
||||
var target = $( param );
|
||||
if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
|
||||
target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
|
||||
$( element ).valid();
|
||||
} );
|
||||
}
|
||||
return value === target.val();
|
||||
},
|
||||
|
||||
// https://jqueryvalidation.org/remote-method/
|
||||
remote: function( value, element, param, method ) {
|
||||
if ( this.optional( element ) ) {
|
||||
return "dependency-mismatch";
|
||||
}
|
||||
|
||||
method = typeof method === "string" && method || "remote";
|
||||
|
||||
var previous = this.previousValue( element, method ),
|
||||
validator, data, optionDataString;
|
||||
|
||||
if ( !this.settings.messages[ element.name ] ) {
|
||||
this.settings.messages[ element.name ] = {};
|
||||
}
|
||||
previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
|
||||
this.settings.messages[ element.name ][ method ] = previous.message;
|
||||
|
||||
param = typeof param === "string" && { url: param } || param;
|
||||
optionDataString = $.param( $.extend( { data: value }, param.data ) );
|
||||
if ( previous.old === optionDataString ) {
|
||||
return previous.valid;
|
||||
}
|
||||
|
||||
previous.old = optionDataString;
|
||||
validator = this;
|
||||
this.startRequest( element );
|
||||
data = {};
|
||||
data[ element.name ] = value;
|
||||
$.ajax( $.extend( true, {
|
||||
mode: "abort",
|
||||
port: "validate" + element.name,
|
||||
dataType: "json",
|
||||
data: data,
|
||||
context: validator.currentForm,
|
||||
success: function( response ) {
|
||||
var valid = response === true || response === "true",
|
||||
errors, message, submitted;
|
||||
|
||||
validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
|
||||
if ( valid ) {
|
||||
submitted = validator.formSubmitted;
|
||||
validator.resetInternals();
|
||||
validator.toHide = validator.errorsFor( element );
|
||||
validator.formSubmitted = submitted;
|
||||
validator.successList.push( element );
|
||||
validator.invalid[ element.name ] = false;
|
||||
validator.showErrors();
|
||||
} else {
|
||||
errors = {};
|
||||
message = response || validator.defaultMessage( element, { method: method, parameters: value } );
|
||||
errors[ element.name ] = previous.message = message;
|
||||
validator.invalid[ element.name ] = true;
|
||||
validator.showErrors( errors );
|
||||
}
|
||||
previous.valid = valid;
|
||||
validator.stopRequest( element, valid );
|
||||
}
|
||||
}, param ) );
|
||||
return "pending";
|
||||
}
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
// Ajax mode: abort
|
||||
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
|
||||
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
|
||||
|
||||
var pendingRequests = {},
|
||||
ajax;
|
||||
|
||||
// Use a prefilter if available (1.5+)
|
||||
if ( $.ajaxPrefilter ) {
|
||||
$.ajaxPrefilter( function( settings, _, xhr ) {
|
||||
var port = settings.port;
|
||||
if ( settings.mode === "abort" ) {
|
||||
if ( pendingRequests[ port ] ) {
|
||||
pendingRequests[ port ].abort();
|
||||
}
|
||||
pendingRequests[ port ] = xhr;
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
|
||||
// Proxy ajax
|
||||
ajax = $.ajax;
|
||||
$.ajax = function( settings ) {
|
||||
var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
|
||||
port = ( "port" in settings ? settings : $.ajaxSettings ).port;
|
||||
if ( mode === "abort" ) {
|
||||
if ( pendingRequests[ port ] ) {
|
||||
pendingRequests[ port ].abort();
|
||||
}
|
||||
pendingRequests[ port ] = ajax.apply( this, arguments );
|
||||
return pendingRequests[ port ];
|
||||
}
|
||||
return ajax.apply( this, arguments );
|
||||
};
|
||||
}
|
||||
return $;
|
||||
}));
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "jquery",
|
||||
"main": "dist/jquery.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"package.json"
|
||||
],
|
||||
"keywords": [
|
||||
"jquery",
|
||||
"javascript",
|
||||
"browser",
|
||||
"library"
|
||||
],
|
||||
"homepage": "https://github.com/jquery/jquery-dist",
|
||||
"version": "3.3.1",
|
||||
"_release": "3.3.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "3.3.1",
|
||||
"commit": "9e8ec3d10fad04748176144f108d7355662ae75e"
|
||||
},
|
||||
"_source": "https://github.com/jquery/jquery-dist.git",
|
||||
"_target": "^3.3.1",
|
||||
"_originalSource": "jquery",
|
||||
"_direct": true
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
Copyright JS Foundation and other contributors, https://js.foundation/
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals. For exact contribution history, see the revision history
|
||||
available at https://github.com/jquery/jquery
|
||||
|
||||
The following license applies to all parts of this software except as
|
||||
documented below:
|
||||
|
||||
====
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
====
|
||||
|
||||
All files located in the node_modules and external directories are
|
||||
externally maintained libraries used by this software which have their
|
||||
own licenses; we recommend you read them, as their terms may differ from
|
||||
the terms above.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue