Compare commits
No commits in common. "master" and "main" have entirely different histories.
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
<PackageReference Include="Dapper" Version="2.0.143" />
|
||||
<PackageReference Include="Dapper.Contrib" Version="2.0.78" />
|
||||
<PackageReference Include="MailKit" Version="4.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Cors.zh-Hant" Version="5.3.0" />
|
||||
<PackageReference Include="MimeKit" Version="4.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NPOI" Version="2.6.1" />
|
||||
|
|
@ -17,4 +18,9 @@
|
|||
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\upload\main\" />
|
||||
<Folder Include="wwwroot\upload\sub\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,47 +1,20 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.AspNetCore.Cors;
|
||||
using Dapper;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Web;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Dynamic;
|
||||
using NPOI;
|
||||
using NPOI.HPSF;
|
||||
using NPOI.HSSF;
|
||||
using NPOI.HSSF.UserModel;
|
||||
using NPOI.XSSF;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using NPOI.POIFS;
|
||||
using NPOI.Util;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using System.Security.Policy;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using static DbTableClass;
|
||||
using System.Runtime.InteropServices.ObjectiveC;
|
||||
using static System.Net.WebRequestMethods;
|
||||
using MimeKit;
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
using System.Net.Mail;
|
||||
using System.Net.Mime;
|
||||
|
||||
|
||||
namespace Bremen_ESG.Controllers
|
||||
{
|
||||
[EnableCors("any")]
|
||||
[Route("Api")]
|
||||
|
||||
public class ApiController : ControllerBase
|
||||
|
|
@ -49,13 +22,38 @@ namespace Bremen_ESG.Controllers
|
|||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IWebHostEnvironment _hostingEnvironment;
|
||||
|
||||
DbConn dbConn = new DbConn();
|
||||
SqlConnection conn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:SQLConnectionString"));
|
||||
|
||||
public ApiController(IHttpContextAccessor httpContextAccessor, IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
this._httpContextAccessor = httpContextAccessor;
|
||||
this._hostingEnvironment = webHostEnvironment;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
||||
[EnableCors("any")]
|
||||
[Route("news_list")]
|
||||
public async Task<ActionResult> News_List(IFormCollection obj) {
|
||||
newResult ret = new newResult();
|
||||
|
||||
List<news> newsList = conn.Query<news>("select * from news order by news_sn desc").ToList();
|
||||
|
||||
ret.news_num = newsList.Count;
|
||||
|
||||
foreach (news objNew in newsList)
|
||||
{
|
||||
newsDetial objDetial = new newsDetial(objNew);
|
||||
objDetial.news_content = objDetial.news_content.Replace("color: rgb(5, 5, 5);", "").Replace("font-family: 微軟正黑體;", "");
|
||||
ret.news_list.Add(objDetial);
|
||||
}
|
||||
|
||||
ret.ret = "yes";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
|
||||
[EnableCors("any")]
|
||||
[Route("esg_message")]
|
||||
public async Task<ActionResult> Esg_Message(IFormCollection obj) {
|
||||
result ret = new result();
|
||||
|
|
@ -72,6 +70,30 @@ namespace Bremen_ESG.Controllers
|
|||
objEsg.esgMessage_mediaUrl = obj["mediaUrl"].ToString();
|
||||
objEsg.esgMessage_testResult = obj["result"].ToString();
|
||||
|
||||
string err_msg = "";
|
||||
|
||||
if (objEsg.esgMessage_company == "") {
|
||||
err_msg += "無企業名稱\n";
|
||||
}
|
||||
|
||||
if (objEsg.esgMessage_name == "")
|
||||
{
|
||||
err_msg += "無聯絡人姓名\n";
|
||||
}
|
||||
|
||||
if (objEsg.esgMessage_tel == "")
|
||||
{
|
||||
err_msg += "無聯絡人電話\n";
|
||||
}
|
||||
|
||||
if (err_msg != "") {
|
||||
ret.ret = "no";
|
||||
ret.message = err_msg;
|
||||
ret.err_code = "0001";
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
string[] mediaUrl = objEsg.esgMessage_mediaUrl.Split(";");
|
||||
|
||||
string htmlBody = "";
|
||||
|
|
@ -95,7 +117,7 @@ namespace Bremen_ESG.Controllers
|
|||
|
||||
|
||||
MailRequest mailRequest = new MailRequest();
|
||||
mailRequest.ToEmail = "calvin@bremen.com.tw,queenie@bremen.com.tw,sunny.lin@bremen.com.tw,poli.chen@bremen.com.tw";
|
||||
mailRequest.ToEmail = "calvin@bremen.com.tw,queenie@bremen.com.tw,sunny.lin@bremen.com.tw";
|
||||
//mailRequest.attach = arrBites;
|
||||
//mailRequest.attachName = "結果.xlsx";
|
||||
mailRequest.Body = htmlBody;
|
||||
|
|
@ -116,6 +138,181 @@ namespace Bremen_ESG.Controllers
|
|||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
[EnableCors("any")]
|
||||
[Route("esg_mail")]
|
||||
public async Task<ActionResult> Esg_Mail(IFormCollection obj) {
|
||||
result ret = new result();
|
||||
|
||||
string company = obj["company"].ToString();
|
||||
string name = obj["name"].ToString();
|
||||
string job = obj["job"].ToString();
|
||||
string needs = obj["needs"].ToString();
|
||||
string other = obj["other"].ToString();
|
||||
string target_email = obj["email"].ToString();
|
||||
string target_link = obj["link"].ToString();
|
||||
|
||||
string err_msg = "";
|
||||
|
||||
//if (GlobalClass.isURL(target_link) == false)
|
||||
//{
|
||||
// err_msg += "無有效結果連結\n";
|
||||
//}
|
||||
|
||||
//if (GlobalClass.isURL(target_link) == false)
|
||||
//{
|
||||
// err_msg += "無有效結果連結\n";
|
||||
//}
|
||||
|
||||
if (target_email != "")
|
||||
{
|
||||
if (GlobalClass.isEmail(target_email) == false)
|
||||
{
|
||||
err_msg += "無有效Email\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (company == "")
|
||||
{
|
||||
err_msg += "無企業名稱\n";
|
||||
}
|
||||
|
||||
if (name == "")
|
||||
{
|
||||
err_msg += "無聯絡人姓名\n";
|
||||
}
|
||||
|
||||
if (target_link == "")
|
||||
{
|
||||
err_msg += "無檢測結果連結\n";
|
||||
}
|
||||
|
||||
|
||||
if (err_msg != "")
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.message = err_msg;
|
||||
ret.err_code = "0001";
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
|
||||
string ownHtml = "";
|
||||
ownHtml += "<h2>有人填寫ESG快速檢測通知信</h2>";
|
||||
ownHtml += "<br/>1.企業名稱:" + company;
|
||||
ownHtml += "<br/>2.聯絡人姓名:" + name;
|
||||
ownHtml += "<br/>3.聯絡人email:" + target_email;
|
||||
ownHtml += "<br/>4.聯絡人職稱:" + job;
|
||||
ownHtml += "<br/>5.已知ESG需求:" + needs;
|
||||
ownHtml += "<br/> 其他 >>> " + other;
|
||||
ownHtml += "<br/>6.檢測結果:<a href='" + target_link + "'>檢測結果頁</a>";
|
||||
|
||||
//建立AlternativeView
|
||||
var altView2 = AlternateView.CreateAlternateViewFromString(ownHtml, null, "text/html");
|
||||
//將圖檔資源加入AlternativeView
|
||||
|
||||
|
||||
await SendEsgResultOwnAsync(altView2);
|
||||
|
||||
string html = $@"";
|
||||
|
||||
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/email_pic/email_footer.jpg");
|
||||
var res = new LinkedResource(fullPath, MediaTypeNames.Image.Jpeg);
|
||||
res.ContentId = Guid.NewGuid().ToString();
|
||||
|
||||
html += "<body>";
|
||||
html += "<table align='center' border='0' cellpadding='0' cellspacing='0' role='presentation' style='border-collapse:collapse;width:100%' width='100%'>";
|
||||
html += " <tbody>";
|
||||
html += " <tr>";
|
||||
html += " <td style='border-collapse:collapse'>";
|
||||
html += " ";
|
||||
html += " <div style='margin:0px auto;max-width:1000px'>";
|
||||
html += " <table align='center' border='0' cellpadding='0' cellspacing='0' role='presentation' style='border-collapse:collapse;width:100%' width='100%'>";
|
||||
html += " <tbody>";
|
||||
html += " <tr>";
|
||||
html += " <td style='border-collapse:collapse;direction:ltr;font-size:0px;padding:20px 0;text-align:center' align='center'>";
|
||||
html += " ";
|
||||
html += " <div class='m_-2162171852830059364mj-column-per-100' style='font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%'>";
|
||||
html += " <table border='0' cellpadding='0' cellspacing='0' role='presentation' style='border-collapse:collapse;vertical-align:top' width='100%' valign='top'>";
|
||||
html += " <tbody>";
|
||||
html += " <tr>";
|
||||
html += " <td align='center' style='border-collapse:collapse;font-size:0px;padding:10px 25px;padding-top:40px;padding-bottom:20px;word-break:break-word'>";
|
||||
html += " <div style=\"font-family:'Source Han Sans','Noto Sans CJK TC',sans-serif;font-size:28px;font-weight:500;letter-spacing:1px;line-height:40px;text-align:center;text-transform:uppercase;color:#163713\">您好,謝謝您填寫ESG快速檢測<br>詳細的測驗結果分析,請點擊以下連結查看:</div>";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " <tr>";
|
||||
html += " <td align='center' style='border-collapse:collapse;font-size:0px;padding:10px 25px;word-break:break-word'>";
|
||||
html += " <table border='0' cellpadding='0' cellspacing='0' role='presentation' style='border-collapse:separate;line-height:100%'>";
|
||||
html += " <tbody><tr>";
|
||||
html += " <td align='center' bgcolor='#2c5228' role='presentation' style='border-collapse:collapse;border:none;border-radius:9999px;background:#2c5228' valign='middle'>";
|
||||
html += " <a href='" + target_link + "' style=\"display:inline-block;background:#2c5228;color:#ffffff;font-family:'Source Han Sans','Noto Sans CJK TC',sans-serif;font-size:28px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:10px 25px;border-radius:9999px\" target='_blank' data-saferedirecturl='" + target_link + "'> 查看結果 </a>";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " </tbody></table>";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " <tr>";
|
||||
html += " <td align='center' style='border-collapse:collapse;font-size:0px;padding:0;padding-top:40px;word-break:break-word'>";
|
||||
html += " <table border='0' cellpadding='0' cellspacing='0' role='presentation' style='border-collapse:collapse;border-spacing:0px'>";
|
||||
html += " <tbody>";
|
||||
html += " <tr>";
|
||||
html += " <td style='border-collapse:collapse;width:800px' width='800'>";
|
||||
html += " <a href='" + target_link + "' target='_blank' data-saferedirecturl='https://www.google.com/url?q=" + target_link + "'>";
|
||||
html += " <img alt='' height='auto' src='cid:" + res.ContentId + "' style='line-height:100%;border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px' width='800' class='CToWUd' data-bit='iit'>";
|
||||
html += " </a>";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " </tbody>";
|
||||
html += " </table>";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " </tbody>";
|
||||
html += " </table>";
|
||||
html += " </div>";
|
||||
html += " ";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " </tbody>";
|
||||
html += " </table>";
|
||||
html += " </div>";
|
||||
html += " ";
|
||||
html += " </td>";
|
||||
html += " </tr>";
|
||||
html += " </tbody>";
|
||||
html += "</table>";
|
||||
html += "</body>";
|
||||
|
||||
if (target_email != "") {
|
||||
//建立AlternativeView
|
||||
var altView = AlternateView.CreateAlternateViewFromString(html, null, "text/html");
|
||||
//將圖檔資源加入AlternativeView
|
||||
altView.LinkedResources.Add(res);
|
||||
|
||||
await SendEsgResultMailAsync(altView, target_email);
|
||||
|
||||
ret.ret = "yes";
|
||||
|
||||
ret.message = "已寄送結果通知信至" + target_email;
|
||||
}
|
||||
else {
|
||||
ret.ret = "yes";
|
||||
ret.message = "無Email,無法寄送結果通知信";
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
public class newResult
|
||||
{
|
||||
public string ret = "no";
|
||||
public string err_code = "0000";
|
||||
public string message = "";
|
||||
public int news_num = 0;
|
||||
public List<news> news_list = new List<news>();
|
||||
}
|
||||
|
||||
public class result
|
||||
{
|
||||
public string ret = "no";
|
||||
|
|
@ -124,6 +321,74 @@ namespace Bremen_ESG.Controllers
|
|||
|
||||
}
|
||||
|
||||
public async Task SendEsgResultOwnAsync(AlternateView altView)
|
||||
{
|
||||
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
|
||||
client.Host = GlobalClass.appsettings("MailServer:smtp_host");
|
||||
client.Port = int.Parse(GlobalClass.appsettings("MailServer:smtp_port"));
|
||||
client.EnableSsl = true;
|
||||
client.Credentials = new NetworkCredential(
|
||||
GlobalClass.appsettings("MailServer:smtp_username"),
|
||||
GlobalClass.appsettings("MailServer:smtp_password")
|
||||
);
|
||||
|
||||
var mail = new MailMessage();
|
||||
mail.IsBodyHtml = true;
|
||||
|
||||
mail.AlternateViews.Add(altView);
|
||||
mail.To.Add("calvin@bremen.com.tw,queenie@bremen.com.tw,sunny.lin@bremen.com.tw");
|
||||
|
||||
mail.From = new MailAddress(GlobalClass.appsettings("MailServer:smtp_username"), "用戶ESG快速檢測結果", System.Text.Encoding.UTF8);
|
||||
mail.Subject = "用戶ESG快速檢測結果";
|
||||
await client.SendMailAsync(mail).ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted)
|
||||
{
|
||||
Console.WriteLine("Error sending email: " + task.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Email sent successfully.");
|
||||
}
|
||||
});
|
||||
|
||||
client.Dispose();
|
||||
}
|
||||
|
||||
public async Task SendEsgResultMailAsync(AlternateView altView, string toEmail) {
|
||||
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
|
||||
client.Host = GlobalClass.appsettings("MailServer:smtp_host");
|
||||
client.Port = int.Parse(GlobalClass.appsettings("MailServer:smtp_port"));
|
||||
client.EnableSsl = true;
|
||||
client.Credentials = new NetworkCredential(
|
||||
GlobalClass.appsettings("MailServer:smtp_username"),
|
||||
GlobalClass.appsettings("MailServer:smtp_password")
|
||||
);
|
||||
|
||||
var mail = new MailMessage();
|
||||
mail.IsBodyHtml = true;
|
||||
|
||||
mail.AlternateViews.Add(altView);
|
||||
mail.To.Add(toEmail);
|
||||
mail.Bcc.Add("sunny.lin@bremen.com.tw");
|
||||
mail.From = new MailAddress(GlobalClass.appsettings("MailServer:smtp_username"), "ESG快速檢測結果分析", System.Text.Encoding.UTF8);
|
||||
mail.Subject = "ESG快速檢測結果分析";
|
||||
await client.SendMailAsync(mail).ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted)
|
||||
{
|
||||
Console.WriteLine("Error sending email: " + task.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Email sent successfully.");
|
||||
}
|
||||
});
|
||||
|
||||
client.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
public async Task SendEmailAsync(MailRequest mailRequest)
|
||||
{
|
||||
var email = new MimeMessage();
|
||||
|
|
@ -146,7 +411,7 @@ namespace Bremen_ESG.Controllers
|
|||
builder.HtmlBody = mailRequest.Body;
|
||||
email.Body = builder.ToMessageBody();
|
||||
|
||||
using var smtp = new SmtpClient();
|
||||
using var smtp = new MailKit.Net.Smtp.SmtpClient();
|
||||
smtp.Connect(GlobalClass.appsettings("MailServer:smtp_host"), int.Parse(GlobalClass.appsettings("MailServer:smtp_port")), SecureSocketOptions.StartTls);
|
||||
smtp.Authenticate(GlobalClass.appsettings("MailServer:smtp_username"), GlobalClass.appsettings("MailServer:smtp_password"));
|
||||
await smtp.SendAsync(email);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,626 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Dapper;
|
||||
using System.Data.SqlClient;
|
||||
using static Bremen_ESG.Controllers.ApiController;
|
||||
using static DbTableClass;
|
||||
using SixLabors.Fonts.Tables.AdvancedTypographic;
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
namespace Bremen_ESG.Controllers
|
||||
{
|
||||
[Route("BackEndApi")]
|
||||
public class BackEndApiController : ControllerBase
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
DbConn dbConn = new DbConn();
|
||||
SqlConnection conn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:SQLConnectionString"));
|
||||
|
||||
public BackEndApiController(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this._httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
[Route("newsAddEditDelGet")]
|
||||
public ActionResult NewsAddEditDelGet(IFormCollection obj) {
|
||||
newDetialResult ret = new newDetialResult();
|
||||
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
ret.ret = "no";
|
||||
ret.err_code = "9999";
|
||||
ret.message = "非登入狀態!";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
DbConn dbConn = new DbConn();
|
||||
SqlConnection conn = dbConn.sqlConnection();
|
||||
|
||||
string news_uid = obj["news_uid"].ToString();
|
||||
string news_title = obj["news_title"].ToString();
|
||||
string news_subtitle = obj["news_subtitle"].ToString();
|
||||
string news_date = obj["news_date"].ToString();
|
||||
string news_mainPhoto = obj["news_mainPhoto"].ToString();
|
||||
string news_content = obj["news_content"].ToString();
|
||||
string TagsStr = obj["news_tags"].ToString().TrimEnd(',');
|
||||
string photoArrayJson = obj["photoArrayJson"].ToString().TrimEnd(',');
|
||||
|
||||
string method = obj["method"].ToString();
|
||||
|
||||
|
||||
|
||||
if (method == "get")
|
||||
{
|
||||
news newObj = conn.QueryFirstOrDefault<news>("select * from news where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
|
||||
if (newObj == null) {
|
||||
ret.ret = "no";
|
||||
ret.err_code = "1009";
|
||||
ret.message = "無此news_uid資料!";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
ret.data = new newsDetial(newObj);
|
||||
ret.ret = "yes";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
if (method == "")
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0001";
|
||||
ret.message = "無method參數!";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
if (method == "del") {
|
||||
conn.Execute("delete photo where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
conn.Execute("delete tag where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
conn.Execute("delete news where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
|
||||
ret.ret = "yes";
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
string err_msg = "";
|
||||
|
||||
if (news_title == "")
|
||||
{
|
||||
err_msg += "無標題!\n";
|
||||
}
|
||||
|
||||
if (news_subtitle == "")
|
||||
{
|
||||
err_msg += "無副標題\n";
|
||||
}
|
||||
|
||||
if (news_content == "")
|
||||
{
|
||||
err_msg += "無內文\n";
|
||||
}
|
||||
|
||||
if (news_date == "")
|
||||
{
|
||||
err_msg += "無發布日期\n";
|
||||
}
|
||||
|
||||
if (err_msg != "")
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0001";
|
||||
ret.message = err_msg;
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
if (method == "edit") {
|
||||
if (news_uid == "") {
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0002";
|
||||
ret.message = "無 news_uid";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
news objNew = conn.QueryFirstOrDefault<news>("select * from news where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
|
||||
if (objNew == null) {
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0003";
|
||||
ret.message = "無此 news_uid資料";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
dynamic photoJsonObj;
|
||||
|
||||
try
|
||||
{
|
||||
photoJsonObj = JsonConvert.DeserializeObject(photoArrayJson);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0003";
|
||||
ret.message = "photo json error" + ex.Message;
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
conn.Execute("delete tag where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
conn.Execute("delete photo where news_uid = @news_uid", new { news_uid = news_uid });
|
||||
|
||||
string[] newsTagArr = TagsStr.Split(",");
|
||||
List<tag> newsTags = new List<tag>();
|
||||
foreach (string tag in newsTagArr)
|
||||
{
|
||||
tags tagData = conn.QueryFirstOrDefault<tags>("select * from tags where tag_uid = @tag_uid", new { tag_uid = tag });
|
||||
|
||||
if (tagData != null)
|
||||
{
|
||||
tag newTag = new tag();
|
||||
newTag.tag_uid = tagData.tag_uid;
|
||||
newTag.news_uid = news_uid;
|
||||
newTag.tag_text = tagData.tag_text;
|
||||
newsTags.Add(newTag);
|
||||
}
|
||||
}
|
||||
|
||||
List<photo> photos = new List<photo>();
|
||||
|
||||
foreach (dynamic item in photoJsonObj)
|
||||
{
|
||||
photo photoObj = new photo();
|
||||
|
||||
photoObj.photo_uid = GlobalClass.CreateRandomCode(12);
|
||||
photoObj.news_uid = news_uid;
|
||||
photoObj.photo_title = item.photo_title;
|
||||
photoObj.photo_path = item.photo_path;
|
||||
|
||||
|
||||
photos.Add(photoObj);
|
||||
}
|
||||
|
||||
objNew.news_title = news_title;
|
||||
objNew.news_date = news_date;
|
||||
objNew.news_subtitle = news_subtitle;
|
||||
objNew.news_content = news_content;
|
||||
objNew.news_mainPhoto = news_mainPhoto;
|
||||
objNew.news_modifydate = DateTime.Now;
|
||||
|
||||
conn.Update<news>(objNew);
|
||||
conn.Insert(photos);
|
||||
conn.Insert(newsTags);
|
||||
|
||||
ret.ret = "yes";
|
||||
ret.data = new newsDetial(objNew);
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
if (method == "add")
|
||||
{
|
||||
news_uid = "news_" + GlobalClass.CreateRandomCode(8);
|
||||
|
||||
string[] newsTagArr = TagsStr.Split(",");
|
||||
List<tag> newsTags = new List<tag>();
|
||||
foreach (string tag in newsTagArr)
|
||||
{
|
||||
tags tagData = conn.QueryFirstOrDefault<tags>("select * from tags where tag_uid = @tag_uid", new { tag_uid = tag });
|
||||
|
||||
if (tagData != null)
|
||||
{
|
||||
tag newTag = new tag();
|
||||
newTag.tag_uid = tagData.tag_uid;
|
||||
newTag.news_uid = news_uid;
|
||||
newTag.tag_text = tagData.tag_text;
|
||||
newsTags.Add(newTag);
|
||||
}
|
||||
}
|
||||
|
||||
dynamic photoJsonObj;
|
||||
|
||||
try
|
||||
{
|
||||
photoJsonObj = JsonConvert.DeserializeObject(photoArrayJson);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0003";
|
||||
ret.message = "photo json error" + ex.Message;
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
List<photo> photos = new List<photo>();
|
||||
|
||||
foreach (dynamic item in photoJsonObj)
|
||||
{
|
||||
photo photoObj = new photo();
|
||||
|
||||
photoObj.photo_uid = GlobalClass.CreateRandomCode(12);
|
||||
photoObj.news_uid= news_uid;
|
||||
photoObj.photo_title = item.photo_title;
|
||||
photoObj.photo_path = item.photo_path;
|
||||
|
||||
|
||||
photos.Add(photoObj);
|
||||
}
|
||||
|
||||
news objNew = new news();
|
||||
|
||||
objNew.news_uid = news_uid;
|
||||
objNew.news_title = news_title;
|
||||
objNew.news_date = news_date;
|
||||
objNew.news_subtitle = news_subtitle;
|
||||
objNew.news_content = news_content;
|
||||
objNew.news_mainPhoto = news_mainPhoto;
|
||||
|
||||
conn.Insert<news>(objNew);
|
||||
conn.Insert(photos);
|
||||
conn.Insert(newsTags);
|
||||
|
||||
ret.ret = "yes";
|
||||
ret.data = new newsDetial(objNew);
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
[Route("updateTags")]
|
||||
public ActionResult UpdateTags(IFormCollection obj)
|
||||
{
|
||||
updatTagResult ret = new updatTagResult();
|
||||
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
string search = obj["search"].ToString();
|
||||
|
||||
if (search.Length < 2)
|
||||
{
|
||||
ret.ret = "no";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
tags tag = conn.QueryFirstOrDefault<tags>("select * from tags where tag_text = @tag_text", new { tag_text = search });
|
||||
|
||||
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
tags newTag = new tags();
|
||||
newTag.tag_uid = "tag_" + GlobalClass.CreateRandomCode(12);
|
||||
newTag.tag_text = search;
|
||||
|
||||
conn.Insert<tags>(newTag);
|
||||
|
||||
ret.data.id = newTag.tag_uid;
|
||||
ret.data.text = search;
|
||||
ret.ret = "yes";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.data.id = tag.tag_uid;
|
||||
ret.data.text = search;
|
||||
ret.ret = "yes";
|
||||
}
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
[Route("queryTags")]
|
||||
public ActionResult QueryTags(IFormCollection obj)
|
||||
{
|
||||
tagListResult ret = new tagListResult();
|
||||
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
string search = obj["search"].ToString();
|
||||
search = "%" + search + "%";
|
||||
List<tags> tagList = conn.Query<tags>("select * from tags where tag_text like @tag_text", new { tag_text = search }).ToList();
|
||||
|
||||
foreach (tags tag in tagList)
|
||||
{
|
||||
optionData item = new optionData();
|
||||
|
||||
item.id = tag.tag_uid;
|
||||
item.text = tag.tag_text;
|
||||
|
||||
ret.data.Add(item);
|
||||
}
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
[Route("subPhotoUpload")]
|
||||
[RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue)]
|
||||
[RequestSizeLimit(int.MaxValue)]
|
||||
public ActionResult SubPhotoUpload([FromForm(Name = "subPhoto")] IFormFile file)
|
||||
{
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
List<errFile> files = new List<errFile>();
|
||||
|
||||
errFile newFile = new errFile();
|
||||
newFile.name = "";
|
||||
newFile.size = 0;
|
||||
newFile.error = "尚未登入";
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
|
||||
string originFileName = file.FileName;
|
||||
string newFileName = "subPhoto_" + GlobalClass.CreateRandomCode(8) + Path.GetExtension(originFileName);
|
||||
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload/sub/" + newFileName);
|
||||
try
|
||||
{
|
||||
using (var stream = new FileStream(fullPath, FileMode.Create))
|
||||
{
|
||||
file.CopyTo(stream);
|
||||
}
|
||||
|
||||
List<uploadFile> files = new List<uploadFile>();
|
||||
|
||||
uploadFile newFile = new uploadFile();
|
||||
|
||||
newFile.name = originFileName;
|
||||
newFile.url = "/upload/sub/" + newFileName;
|
||||
newFile.size = file.Length;
|
||||
newFile.thumbnailUrl = "/upload/sub/" + newFileName;
|
||||
newFile.deleteUrl = "/upload/sub/" + newFileName;
|
||||
|
||||
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return Content(JsonConvert.SerializeObject(obj), "application/json;charset=utf-8");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
List<errFile> files = new List<errFile>();
|
||||
|
||||
errFile newFile = new errFile();
|
||||
newFile.name = originFileName;
|
||||
newFile.size = file.Length;
|
||||
newFile.error = ex.Message;
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
|
||||
}
|
||||
}
|
||||
|
||||
[Route("mainPhotoUpload")]
|
||||
[RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue)]
|
||||
[RequestSizeLimit(int.MaxValue)]
|
||||
public ActionResult MainPhotoUpload([FromForm(Name = "avatar")] IFormFile file) {
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
List<errFile> files = new List<errFile>();
|
||||
|
||||
errFile newFile = new errFile();
|
||||
newFile.name = "";
|
||||
newFile.size = 0;
|
||||
newFile.error = "尚未登入";
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
|
||||
string originFileName = file.FileName;
|
||||
string newFileName = "mainPhoto_" + GlobalClass.CreateRandomCode(8) + Path.GetExtension(originFileName);
|
||||
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload/main/" + newFileName);
|
||||
try
|
||||
{
|
||||
using (var stream = new FileStream(fullPath, FileMode.Create))
|
||||
{
|
||||
file.CopyTo(stream);
|
||||
}
|
||||
|
||||
List<uploadFile> files = new List<uploadFile>();
|
||||
|
||||
uploadFile newFile = new uploadFile();
|
||||
|
||||
newFile.name = originFileName;
|
||||
newFile.url = "/upload/main/" + newFileName;
|
||||
newFile.size = file.Length;
|
||||
newFile.thumbnailUrl = "/upload/main/" + newFileName;
|
||||
newFile.deleteUrl = "/upload/main/" + newFileName;
|
||||
|
||||
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return Content(JsonConvert.SerializeObject(obj), "application/json;charset=utf-8");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
List<errFile> files = new List<errFile>();
|
||||
|
||||
errFile newFile = new errFile();
|
||||
newFile.name = originFileName;
|
||||
newFile.size = file.Length;
|
||||
newFile.error = ex.Message;
|
||||
|
||||
files.Add(newFile);
|
||||
|
||||
fileResult obj = new fileResult();
|
||||
|
||||
obj.files = files;
|
||||
|
||||
return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
|
||||
}
|
||||
}
|
||||
|
||||
//後台登入
|
||||
[Route("signin")]
|
||||
public ActionResult Signin(IFormCollection obj)
|
||||
{
|
||||
result ret = new result();
|
||||
|
||||
string input_ID = obj["id"].ToString();
|
||||
string input_PWD = obj["pwd"].ToString();
|
||||
|
||||
string sys_ID = GlobalClass.appsettings("Admin:id");
|
||||
string sys_PWD = GlobalClass.Sha256(GlobalClass.appsettings("Admin:pwd"));
|
||||
|
||||
if (input_ID == sys_ID && input_PWD == sys_PWD)
|
||||
{
|
||||
DbConn dbConn = new DbConn();
|
||||
|
||||
SqlConnection conn = dbConn.sqlConnection();
|
||||
|
||||
string token_key = GlobalClass.CreateRandomCode(24);
|
||||
|
||||
int effCount = conn.Execute("insert into token (token_key, user_uid, user_id, user_perm, token_expireddate) values (@token_key, @user_uid, @user_id, @user_perm, @token_expireddate)", new { token_key = token_key, user_uid = "system", user_id = input_ID, user_perm = "system", token_expireddate = DateTime.Now.AddMinutes(20) });
|
||||
|
||||
CookieOptions options = new CookieOptions();
|
||||
|
||||
options.Secure = true;
|
||||
options.Expires = DateTime.Now.AddMinutes(30);
|
||||
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
|
||||
_httpContextAccessor.HttpContext.Response.Cookies.Append("token_key", token_key, options);
|
||||
|
||||
dbConn.closeConn();
|
||||
|
||||
ret.ret = "yes";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.ret = "no";
|
||||
ret.err_code = "0001";
|
||||
ret.message = "帳號或密碼錯誤!";
|
||||
}
|
||||
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
[Route("newsList")]
|
||||
public ActionResult NewsList(IFormCollection obj) {
|
||||
newResult ret = new newResult();
|
||||
|
||||
authToken token = new authToken(this._httpContextAccessor);
|
||||
|
||||
if (token.user_isLogin == false)
|
||||
{
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
ret.ret = "no";
|
||||
ret.err_code = "9999";
|
||||
ret.message = "非登入狀態!";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
DbConn dbConn = new DbConn();
|
||||
SqlConnection conn = dbConn.sqlConnection();
|
||||
|
||||
ret.newsList = conn.Query<news>("select * from news order by news_sn desc").ToList();
|
||||
ret.ret = "yes";
|
||||
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
|
||||
}
|
||||
|
||||
public class newResult
|
||||
{
|
||||
public string ret = "no";
|
||||
public string err_code = "0000";
|
||||
public string message = "";
|
||||
public List<news> newsList = new List<news>();
|
||||
|
||||
}
|
||||
|
||||
public class newDetialResult
|
||||
{
|
||||
public string ret = "no";
|
||||
public string err_code = "0000";
|
||||
public string message = "";
|
||||
public newsDetial data = new newsDetial();
|
||||
}
|
||||
|
||||
public class fileResult
|
||||
{
|
||||
public object files = new object();
|
||||
}
|
||||
|
||||
public class uploadFile
|
||||
{
|
||||
public string name { get; set; } = "";
|
||||
public long size { get; set; } = 0;
|
||||
public string url { get; set; } = "";
|
||||
public string thumbnailUrl { get; set; } = "";
|
||||
public string deleteUrl { get; set; } = "";
|
||||
public string deleteType { get; set; } = "DELETE";
|
||||
}
|
||||
|
||||
public class errFile
|
||||
{
|
||||
public string name { get; set; } = "";
|
||||
public long size { get; set; } = 0;
|
||||
public string error { get; set; } = "";
|
||||
}
|
||||
|
||||
public class updatTagResult
|
||||
{
|
||||
public string ret { get; set; } = "no";
|
||||
public string err_code { get; set; } = "0000";
|
||||
public string message { get; set; } = "";
|
||||
|
||||
public optionData data = new optionData();
|
||||
}
|
||||
public class tagListResult
|
||||
{
|
||||
public List<optionData> data = new List<optionData>();
|
||||
}
|
||||
|
||||
public class optionData
|
||||
{
|
||||
public string id { get; set; } = "";
|
||||
public string text { get; set; } = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Net.Http;
|
||||
using Dapper;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace Bremen_ESG.Controllers
|
||||
{
|
||||
public class BackEndController : Controller
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private authToken _objToken;
|
||||
|
||||
public BackEndController(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this._httpContextAccessor = httpContextAccessor;
|
||||
|
||||
this._objToken = new authToken(this._httpContextAccessor);
|
||||
}
|
||||
|
||||
public IActionResult NewsList() {
|
||||
if (checkToken() == false)
|
||||
{
|
||||
return Redirect("~/BackEnd/Index");
|
||||
}
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Logout()
|
||||
{
|
||||
string token_key = _httpContextAccessor.HttpContext.Request.Cookies["token_key"];
|
||||
|
||||
DbConn dbConn = new DbConn();
|
||||
dbConn.sqlConnection().Execute("delete token where token_key = @token_key", new { token_key = token_key });
|
||||
dbConn.closeConn();
|
||||
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
|
||||
HttpContext.Response.Redirect("/BackEnd/Index");
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public Boolean checkToken()
|
||||
{
|
||||
this._objToken = new authToken(this._httpContextAccessor);
|
||||
|
||||
if (this._objToken.user_isLogin == false)
|
||||
{
|
||||
HttpContext.Response.Cookies.Delete("token_key");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ViewData["User_name"] = this._objToken.user_name;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,58 @@ using Org.BouncyCastle.Bcpg;
|
|||
|
||||
|
||||
public class DbTableClass {
|
||||
|
||||
[Table("tags")]
|
||||
public class tags
|
||||
{
|
||||
[JsonIgnore]
|
||||
[Key]
|
||||
public int tag_sn { get; set; }
|
||||
public string tag_uid { get; set; } = "";
|
||||
public string tag_text { get; set; } = "";
|
||||
}
|
||||
|
||||
[Table("photo")]
|
||||
public class photo
|
||||
{
|
||||
[JsonIgnore]
|
||||
[Key]
|
||||
public int photo_sn { get; set; }
|
||||
public string photo_uid { get; set; } = "";
|
||||
public string news_uid { get; set; } = "";
|
||||
public string photo_path { get; set; } = "";
|
||||
public string photo_title { get; set; } = "";
|
||||
}
|
||||
|
||||
[Table("tag")]
|
||||
public class tag
|
||||
{
|
||||
[JsonIgnore]
|
||||
[Key]
|
||||
public int tag_sn { get; set; }
|
||||
public string tag_uid { get; set; } = "";
|
||||
public string news_uid { get; set; } = "";
|
||||
public string tag_text { get; set; } = "";
|
||||
}
|
||||
|
||||
[Table("news")]
|
||||
public class news
|
||||
{
|
||||
[JsonIgnore]
|
||||
[Key]
|
||||
public int news_sn { get; set; }
|
||||
public string news_uid { get; set; } = "";
|
||||
public string news_title { get; set; } = "";
|
||||
public string news_date { get; set; } = "";
|
||||
public string news_subtitle { get; set; } = "";
|
||||
public string news_mainPhoto { get; set; } = "";
|
||||
public string news_content { get; set; } = "";
|
||||
public DateTime news_createdate { get; set; } = DateTime.Now;
|
||||
public DateTime news_modifydate { get; set; } = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Table("esgMessage")]
|
||||
public class esgMessage
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ using System.Collections.Specialized;
|
|||
public static class GlobalClass {
|
||||
public static IServiceProvider ServiceProvider;
|
||||
public static bool isURL(string url) {
|
||||
return Uri.IsWellFormedUriString(url, UriKind.Absolute);
|
||||
return Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute);
|
||||
}
|
||||
|
||||
public static string GetIP(this HttpContext context) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
using Dapper;
|
||||
using Dapper.Contrib.Extensions;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Data.SqlClient;
|
||||
using static DbTableClass;
|
||||
|
||||
public class newsDetial: news
|
||||
{
|
||||
DbConn dbConn = new DbConn();
|
||||
SqlConnection conn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:SQLConnectionString"));
|
||||
|
||||
public List<tag> tags = new List<tag>();
|
||||
public List<photo> photos = new List<photo>();
|
||||
public newsDetial() {
|
||||
|
||||
}
|
||||
|
||||
public newsDetial(news obj) {
|
||||
Type newsType = obj.GetType();
|
||||
|
||||
foreach (var prop in newsType.GetProperties())
|
||||
{
|
||||
string propName = prop.Name;
|
||||
var valueProperty = newsType.GetProperty(propName);
|
||||
object propValue = valueProperty.GetValue(obj, null);
|
||||
|
||||
this.GetType().GetProperty(propName).SetValue(this, propValue);
|
||||
}
|
||||
|
||||
tags = conn.Query<tag>("select * from tag where news_uid = @news_uid", new { news_uid = this.news_uid }).ToList();
|
||||
photos = conn.Query<photo>("select * from photo where news_uid = @news_uid", new { news_uid = this.news_uid }).ToList();
|
||||
}
|
||||
}
|
||||
96
Program.cs
96
Program.cs
|
|
@ -1,48 +1,82 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
//builder.Services.AddCors(options =>
|
||||
//{
|
||||
// options.AddDefaultPolicy(
|
||||
// policy =>
|
||||
// {
|
||||
// policy.WithOrigins("http://www.bremen.com.tw",
|
||||
// "http://bremen.com.tw",
|
||||
// "https://www.bremen.com.tw",
|
||||
// "https://bremen.com.tw",
|
||||
// "http://preview.bremen.com.tw",
|
||||
// "https://preview.bremen.com.tw"
|
||||
// ).AllowAnyMethod().AllowAnyHeader();
|
||||
// });
|
||||
//});
|
||||
|
||||
//builder.Services.AddCors(options =>
|
||||
//{
|
||||
// options.AddDefaultPolicy(builder =>
|
||||
// {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// builder
|
||||
// .WithOrigins("https://*.bremen.com.tw",
|
||||
// "https://localhost:7245",
|
||||
// "https://bremen.com.tw")
|
||||
// .AllowAnyMethod()
|
||||
// .AllowAnyHeader();
|
||||
|
||||
|
||||
// // builder
|
||||
// //.WithOrigins(GlobalClass.appsettings("CorsOrigins")
|
||||
// //.Split(",", StringSplitOptions.RemoveEmptyEntries)
|
||||
// //.ToArray() ?? Array.Empty<string>())
|
||||
// //.SetIsOriginAllowedToAllowWildcardSubdomains()
|
||||
// //.AllowAnyMethod()
|
||||
// //.AllowAnyHeader();
|
||||
|
||||
|
||||
// });
|
||||
//});
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddDefaultPolicy(builder =>
|
||||
options.AddPolicy(name: "any", builder =>
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
builder
|
||||
.WithOrigins("https://*.bremen.com.tw",
|
||||
"https://localhost:7245",
|
||||
"https://bremen.com.tw")
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
*/
|
||||
|
||||
builder
|
||||
.WithOrigins(GlobalClass.appsettings("CorsOrigins")
|
||||
.Split(",", StringSplitOptions.RemoveEmptyEntries)
|
||||
.ToArray() ?? Array.Empty<string>())
|
||||
.SetIsOriginAllowedToAllowWildcardSubdomains()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
|
||||
|
||||
});
|
||||
builder.WithOrigins("https://www.bremen.com.tw",
|
||||
"https://bremen.com.tw", "https://preview.bremen.com.tw",
|
||||
"http://970px.dscloud.me/")
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
|
||||
|
||||
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
//builder.Services.AddControllers();
|
||||
builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
|
|
@ -56,13 +90,19 @@ defaultFilesOptions.DefaultFileNames.Clear();
|
|||
defaultFilesOptions.DefaultFileNames.Add("index.html");
|
||||
defaultFilesOptions.DefaultFileNames.Add("iisstart.htm");
|
||||
app.UseDefaultFiles(defaultFilesOptions);
|
||||
app.UseCors();
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
app.UseCors("any");
|
||||
|
||||
//app.UseAuthorization();
|
||||
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,226 @@
|
|||
@*
|
||||
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||
*@
|
||||
@{
|
||||
Layout = "_BackEnd";
|
||||
}
|
||||
@section Script {
|
||||
<script src="~/backend/assets/vendor/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="~/backend/assets/vendor/datatables.net-responsive/js/dataTables.responsive.min.js"></script>
|
||||
<script src="~/backend/assets/vendor/datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js"></script>
|
||||
<script src="~/backend/assets/vendor/summernote/summernote-bs4.min.js"></script>
|
||||
<script src="~/backend/assets/javascript/pages/dataTables.bootstrap.js"></script>
|
||||
<script src="~/backend/assets/javascript/custom/newslist.js" asp-append-version="true"></script>
|
||||
|
||||
}
|
||||
|
||||
<!-- .page-inner -->
|
||||
<div class="page-inner">
|
||||
<!-- .page-title-bar -->
|
||||
<header class="page-title-bar">
|
||||
<!-- .breadcrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item active">
|
||||
<a href="#"><i class="breadcrumb-icon fa fa-angle-left mr-2"></i>最新消息</a>
|
||||
</li>
|
||||
</ol>
|
||||
</nav><!-- /.breadcrumb -->
|
||||
<!-- title -->
|
||||
<h1 class="page-title"> 最新消息清單 </h1>
|
||||
<p class="text-muted"> </p><!-- /title -->
|
||||
</header><!-- /.page-title-bar -->
|
||||
<!-- .page-section -->
|
||||
<div class="page-section">
|
||||
<button type="button" id="newsNewModal" class="btn btn-primary btn-floated position-absolute" title="Add new client"><i class="fa fa-plus"></i></button>
|
||||
<!-- .card -->
|
||||
<div class="card card-fluid">
|
||||
<!-- .card-body -->
|
||||
<div class="card-body">
|
||||
<!-- .table -->
|
||||
<table id="dt-responsive" class="table dt-responsive nowrap w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> 主圖片 </th>
|
||||
<th> 發布日期 </th>
|
||||
<th> 標題 </th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
</table><!-- /.table -->
|
||||
</div><!-- /.card-body -->
|
||||
</div><!-- /.card -->
|
||||
</div><!-- /.page-section -->
|
||||
</div><!-- /.page-inner -->
|
||||
|
||||
|
||||
<!-- .modal -->
|
||||
<form id="clientNewForm" name="clientNewForm">
|
||||
<div class="modal fade" id="clientNewModal" tabindex="-1" role="dialog" aria-labelledby="clientNewModalLabel" data-backdrop="static"
|
||||
data-keyboard="false" aria-hidden="true">
|
||||
<!-- .modal-dialog -->
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<!-- .modal-content -->
|
||||
<div class="modal-content">
|
||||
<!-- .modal-header -->
|
||||
<div class="modal-header">
|
||||
<h6 id="clientNewModalLabel" class="modal-title inline-editable">
|
||||
<span class="sr-only">Client name</span> <input id="modelTitle" type="text" class="form-control form-control-lg" placeholder="最新消息資料維護" required="">
|
||||
</h6>
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span><span class="sr-only">Close</span>
|
||||
</button>
|
||||
</div><!-- /.modal-header -->
|
||||
<!-- .modal-body -->
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="method" />
|
||||
<input type="hidden" id="news_uid" />
|
||||
<!-- .form-row -->
|
||||
<div class="form-row">
|
||||
|
||||
|
||||
<div class="col-md-12" id="user_name_div">
|
||||
<div class="form-group">
|
||||
<label for="news_title">主標題</label>
|
||||
<textarea maxlength="50" id="news_title" class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12" id="user_name_div">
|
||||
<div class="form-group">
|
||||
<label for="news_subtitle">副標題</label> <input type="text" maxlength="50" id="news_subtitle" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<!-- .media -->
|
||||
<div class="media">
|
||||
<div class="user-avatar user-avatar-xxl fileinput-button">
|
||||
<div class="fileinput-button-label"> Change photo </div><img src="~/BackEnd/assets/images/avatars/unknown-profile.jpg" alt=""> <input id="fileupload-avatar" type="file" name="avatar">
|
||||
</div>
|
||||
<div class="media-body pl-3">
|
||||
<h3 class="card-title"> 主圖片 </h3>
|
||||
<p class="card-text"> 點擊圖片可更換照片. </p>
|
||||
<p class="card-text text-muted"> 最大容許檔案大小為 5MB. </p>
|
||||
</div>
|
||||
</div><!-- /.media -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- .form-group -->
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="flatpickr01">日期</label> <input id="news_date" type="text" class="form-control" data-toggle="flatpickr" data-date-format="Y.m.d">
|
||||
</div><!-- /.form-group -->
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="news_tags">HashTag</label> <select type="text" id="news_tags" class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12" id="user_id_div">
|
||||
<div class="form-group">
|
||||
<label for="news_title">內容</label>
|
||||
<!-- .card -->
|
||||
<div class="card card-fluid">
|
||||
<!-- #summernote-basic -->
|
||||
<div id="summernote" data-placeholder="最新消息內容..." data-height="200"></div><!-- /#summernote-basic -->
|
||||
</div><!-- /.card -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
<!-- .card-body -->
|
||||
<div class="card-body">
|
||||
<h2 class="card-title"> </h2><!-- .table-responsive -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" style="min-width: 678px" id="media_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 30%;"> 圖片 </th>
|
||||
<th> 說明文字</th>
|
||||
<th style="width: 20%;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="align-middle">
|
||||
<div class="user-avatar user-avatar-xxl">
|
||||
<img src="" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="align-middle"> zamy_ding </td>
|
||||
<td class="align-middle text-right">
|
||||
<button type="button" data-uid="" data-method="" class="btn btn-sm btn-icon btn-secondary" data-toggle="modal" data-target="#clientContactEditModal"><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button> <button type="button" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div><!-- /.table-responsive -->
|
||||
</div><!-- /.card-body -->
|
||||
<!-- .card-footer -->
|
||||
<div class="card-footer">
|
||||
<a href="javascript: void();" id="socialNewBtn" class="card-footer-item"><i class="fa fa-plus-circle mr-1"></i> 新增輪播圖片</a>
|
||||
</div><!-- /.card-footer -->
|
||||
</div>
|
||||
|
||||
</div><!-- /.form-row -->
|
||||
</div><!-- /.modal-body -->
|
||||
<!-- .modal-footer -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" id="newsSaveBtn" class="btn btn-primary">儲存</button> <button id="closeBtn" type="button" class="btn btn-light" data-dismiss="modal">關閉</button>
|
||||
</div><!-- /.modal-footer -->
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div>
|
||||
</form><!-- /.modal -->
|
||||
|
||||
<!-- .modal -->
|
||||
<form id="clientSocialEditForm" name="clientSocialEditForm">
|
||||
<div class="modal fade" id="socialItemModal" tabindex="-1" role="dialog" aria-labelledby="socialModalLabel" data-backdrop="static" aria-hidden="true">
|
||||
<!-- .modal-dialog -->
|
||||
<div class="modal-dialog" role="document">
|
||||
<!-- .modal-content -->
|
||||
<div class="modal-content">
|
||||
<!-- .modal-header -->
|
||||
<div class="modal-header">
|
||||
<h6 id="socialModalLabel" class="modal-title inline-editable">
|
||||
<span class="sr-only">輪播圖片</span> <input id="option_name" type="text" class="form-control form-control-lg" value="" placeholder="輪播圖片" readonly="readonly " required="">
|
||||
</h6>
|
||||
</div><!-- /.modal-header -->
|
||||
<!-- .modal-body -->
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="photo_method" />
|
||||
<input type="hidden" id="photo_uid" />
|
||||
<input type="hidden" id="news_uid" />
|
||||
<div class="form-group">
|
||||
<div class="card-body">
|
||||
<!-- .media -->
|
||||
<div class="media">
|
||||
<div class="user-avatar user-avatar-xxl fileinput-button">
|
||||
<div class="fileinput-button-label"> Change photo </div><img src="~/BackEnd/assets/images/avatars/unknown-profile.jpg" alt=""> <input id="fileupload-subPhoto" type="file" accept="image/*" name="subPhoto">
|
||||
</div>
|
||||
<div class="media-body pl-3">
|
||||
<h3 class="card-title"> 輪播圖片 </h3>
|
||||
<p class="card-text"> 點擊圖片可更換照片. </p>
|
||||
<p class="card-text text-muted"> 最大容許檔案大小為 5MB. </p>
|
||||
</div>
|
||||
</div><!-- /.media -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- .form-group -->
|
||||
<div class="form-group">
|
||||
<div class="form-label-group">
|
||||
<input type="text" id="photo_title" class="form-control" value="" placeholder="圖片說明" maxlength="50" required=""> <label for="photo_title">圖片說明</label>
|
||||
</div>
|
||||
</div><!-- /.form-group -->
|
||||
|
||||
|
||||
</div><!-- /.modal-body -->
|
||||
<!-- .modal-footer -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" id="optionItemDialogSaveBtn" class="btn btn-primary">Save</button> <button type="button" class="btn btn-light" data-dismiss="modal">Close</button>
|
||||
</div><!-- /.modal-footer -->
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div>
|
||||
</form><!-- /.modal -->
|
||||
|
|
@ -18,10 +18,12 @@
|
|||
<link rel="stylesheet" href="~/BackEnd/assets/vendor/fortawesome/fontawesome-free/css/all.min.css">
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/vendor/datatables.net-buttons-bs4/css/buttons.bootstrap4.min.css">
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/vendor/flatpickr/flatpickr.min.css">
|
||||
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/vendor/select2/css/select2.min.css">
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/vendor/summernote/summernote-bs4.min.css">
|
||||
<!-- END PLUGINS STYLES -->
|
||||
<!-- BEGIN THEME STYLES -->
|
||||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/blitzer/jquery-ui.css">
|
||||
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/stylesheets/theme.min.css" data-skin="default">
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/stylesheets/theme-dark.min.css" data-skin="dark">
|
||||
<link rel="stylesheet" href="~/BackEnd/assets/stylesheets/custom.css">
|
||||
|
|
@ -113,21 +115,10 @@
|
|||
<ul class="menu">
|
||||
<!-- .menu-item -->
|
||||
<li class="menu-item" style="display:block;">
|
||||
<a href="/BackEnd/motGiftList" class="menu-link"><span class="menu-icon fas fa-folder"></span> <span class="menu-text"></span></a>
|
||||
<a href="/BackEnd/newsList" class="menu-link"><span class="menu-icon fas fa-folder"></span> <span class="menu-text">最新消息</span></a>
|
||||
</li><!-- /.menu-item -->
|
||||
|
||||
<!-- .menu-item -->
|
||||
<li class="menu-item" style="display:block;">
|
||||
<a href="/BackEnd/motUserList" class="menu-link"><span class="menu-icon fas fa-folder"></span> <span class="menu-text">MOT兌換清單</span></a>
|
||||
</li><!-- /.menu-item -->
|
||||
<!-- .menu-item -->
|
||||
<li class="menu-item" style="display:block;">
|
||||
<a href="/BackEnd/ruleList" class="menu-link"><span class="menu-icon fas fa-folder"></span> <span class="menu-text">MOT中獎機率</span></a>
|
||||
</li><!-- /.menu-item -->
|
||||
<!-- .menu-item -->
|
||||
<li class="menu-item" style="display:block;">
|
||||
<a href="/BackEnd/totUserList" class="menu-link"><span class="menu-icon fas fa-folder"></span> <span class="menu-text">TOT兌換清單</span></a>
|
||||
</li><!-- /.menu-item -->
|
||||
|
||||
|
||||
|
||||
</ul><!-- /.menu -->
|
||||
|
|
@ -168,9 +159,25 @@
|
|||
<script src="~/BackEnd/assets/vendor/stacked-menu/js/stacked-menu.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/perfect-scrollbar/perfect-scrollbar.min.js"></script>
|
||||
|
||||
<script src="~/BackEnd/assets/vendor/wnumb/wNumb.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/nouisliderribute/nouislider.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-load-image/js/load-image.all.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-process.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-image.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-audio.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-video.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-validate.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/bootstrap-touchspin/jquery.bootstrap-touchspin.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/easy-pie-chart/jquery.easypiechart.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/chart.js/Chart.min.js"></script>
|
||||
|
||||
<script src="~/BackEnd/assets/javascript/pages/sha256.js"></script> <!-- END PLUGINS JS -->
|
||||
<script src="~/BackEnd/assets/javascript/pages/waitingfor.js"></script>
|
||||
<script src="~/BackEnd/assets/javascript/custom/globalJS.js"></script>
|
||||
<script src="~/BackEnd/assets/javascript/custom/globalJS.js" asp-append-version="true"></script>
|
||||
<!-- BEGIN THEME JS -->
|
||||
<script src="~/BackEnd/assets/javascript/theme.min.js"></script> <!-- END THEME JS -->
|
||||
<!-- BEGIN datatables JS-->
|
||||
|
|
@ -187,7 +194,20 @@
|
|||
<!-- Bootstrap DatePicker -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.css" type="text/css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.js" type="text/javascript"></script>
|
||||
<!-- Bootstrap DatePicker -->
|
||||
<script src="~/BackEnd/assets/vendor/flatpickr/flatpickr.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/flatpickr/plugins/monthSelect/index.js"></script>
|
||||
<!-- Bootstrap DatePicker
|
||||
<!-- BEGIN SELECT2-->
|
||||
<script src="~/BackEnd/assets/vendor/handlebars/handlebars.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/typeahead.js/typeahead.bundle.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/select2/js/select2.full.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/tributejs/tribute.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/jquery.caret/jquery.caret.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/at.js/js/jquery.atwho.min.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/zxcvbn/zxcvbn.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/vanilla-text-mask/vanillaTextMask.js"></script>
|
||||
<script src="~/BackEnd/assets/vendor/text-mask-addons/textMaskAddons.js"></script>
|
||||
<!-- END SELECT2-->
|
||||
@RenderSection("Script", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
"smtp_host": "smtp.gmail.com",
|
||||
"smtp_port": 587,
|
||||
"smtp_username": "bremen@bremen.com.tw",
|
||||
"smtp_password": "2776Bremen5485",
|
||||
"smtp_password": "sbkm kcwm opzu zaon",
|
||||
"sender_email": "bremen@bremen.com.tw",
|
||||
"sender_name": "ESG需求聯絡表通知信"
|
||||
},
|
||||
"CorsOrigins": "https://*.bremen.com.tw,https://localhost:7245,https://bremen.com.tw"
|
||||
"CorsOrigins": "https://*.bremen.com.tw,https://localhost:7245,https://bremen.com.tw,https://preview.bremen.com.tw"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (data.ret == "yes") {
|
||||
location.href = "/BackEnd/MotGiftList";
|
||||
location.href = "/BackEnd/NewsList";
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,33 +124,33 @@ function padding(num, length) {
|
|||
}
|
||||
|
||||
function clearChildren(element) {
|
||||
for (var i = 0; i < element.childNodes.length; i++) {
|
||||
var e = element.childNodes[i];
|
||||
if (e.tagName) switch (e.tagName.toLowerCase()) {
|
||||
case 'input':
|
||||
switch (e.type) {
|
||||
case "radio":
|
||||
case "checkbox": break;
|
||||
case "button":
|
||||
case "submit":
|
||||
case "text": e.value = ''; break;
|
||||
case "image": break;
|
||||
default: if (e.type != "checkbox") { e.value = ''; }; break;
|
||||
}
|
||||
break;
|
||||
case 'select': e.selectedIndex = 0; break;
|
||||
case 'textarea': e.innerHTML = ''; break;
|
||||
default: clearChildren(e);
|
||||
}
|
||||
}
|
||||
//for (var i = 0; i < element.childNodes.length; i++) {
|
||||
// var e = element.childNodes[i];
|
||||
// if (e.tagName) switch (e.tagName.toLowerCase()) {
|
||||
// case 'input':
|
||||
// switch (e.type) {
|
||||
// case "radio":
|
||||
// case "checkbox": break;
|
||||
// case "button":
|
||||
// case "submit":
|
||||
// case "text": e.value = ''; break;
|
||||
// case "image": break;
|
||||
// default: if (e.type != "checkbox") { e.value = ''; }; break;
|
||||
// }
|
||||
// break;
|
||||
// case 'select': e.selectedIndex = 0; break;
|
||||
// case 'textarea': e.innerHTML = ''; break;
|
||||
// default: clearChildren(e);
|
||||
// }
|
||||
//}
|
||||
|
||||
$(element).children().find('textarea').each(function () {
|
||||
$(this).val('');
|
||||
});
|
||||
//$(element).children().find('textarea').each(function () {
|
||||
// $(this).val('');
|
||||
//});
|
||||
|
||||
$(element).children().find('select').each(function () {
|
||||
$(this).prop('selectedIndex', 0);
|
||||
});
|
||||
//$(element).children().find('select').each(function () {
|
||||
// $(this).prop('selectedIndex', 0);
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,682 @@
|
|||
var mainTable;
|
||||
var mainRowID;
|
||||
var mainPos;
|
||||
var mediaTr;
|
||||
|
||||
$(document).ready(function () {
|
||||
loadTagsInput();
|
||||
loadDataTable();
|
||||
initSummernote();
|
||||
initMainPhotoUpload();
|
||||
initSubPhotoUpload();
|
||||
|
||||
$('#newsSaveBtn').on('click', function () {
|
||||
var method = $('#method').val();
|
||||
var news_uid = $('#news_uid').val();
|
||||
var news_title = $('#news_title').val();
|
||||
var news_subtitle = $('#news_subtitle').val();
|
||||
var news_content = $('#summernote').summernote('code');
|
||||
|
||||
var src = $('#fileupload-avatar').parent().children('img').prop('src');
|
||||
var origin = location.origin;
|
||||
src = src.replace(origin, '');
|
||||
|
||||
var news_mainPhoto = src;
|
||||
var news_date = $('#news_date').val();
|
||||
var tags = $('#news_tags').val();
|
||||
var news_tags = "";
|
||||
var photoArray = [];
|
||||
var photoArrayJson = "";
|
||||
|
||||
$.each(tags, function (key, value) {
|
||||
news_tags = news_tags + value + ",";
|
||||
});
|
||||
|
||||
$('#media_table tbody tr').each(function () {
|
||||
var tmpphoto_path = $(this).find('td').eq(0).find('img').prop('src').trim();
|
||||
tmpphoto_path = tmpphoto_path.replace(origin, '');
|
||||
|
||||
var item = {
|
||||
photo_title: $(this).find('td').eq(1).text().trim(),
|
||||
photo_path: tmpphoto_path.trim()
|
||||
}
|
||||
|
||||
photoArray.push(item);
|
||||
});
|
||||
|
||||
var err_msg = "";
|
||||
|
||||
if (news_mainPhoto == '/BackEnd/assets/images/avatars/unknown-profile.jpg') {
|
||||
err_msg += "請選擇要顯示的圖片!\n";
|
||||
}
|
||||
|
||||
if (news_title == "") {
|
||||
err_msg += "請輸入標題!\n";
|
||||
}
|
||||
|
||||
if (news_subtitle == "") {
|
||||
err_msg += "請輸入副標題!\n";
|
||||
}
|
||||
|
||||
if (news_content == "") {
|
||||
err_msg += "請輸入內容!\n";
|
||||
}
|
||||
|
||||
if (err_msg != "") {
|
||||
alert(err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
mainTable = $('#dt-responsive').dataTable();
|
||||
|
||||
var formData = {
|
||||
method: method,
|
||||
news_uid: news_uid,
|
||||
news_title: news_title,
|
||||
news_subtitle: news_subtitle,
|
||||
news_content: news_content,
|
||||
news_mainPhoto: news_mainPhoto,
|
||||
news_date: news_date,
|
||||
news_tags: news_tags,
|
||||
photoArrayJson: JSON.stringify(photoArray)
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/BackEndApi/newsAddEditDelGet",
|
||||
type: "post",
|
||||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var obj = data.data;
|
||||
if (data.ret == "yes") {
|
||||
|
||||
if (method == "add") {
|
||||
mainTable.fnAddData(obj);
|
||||
}
|
||||
|
||||
if (method == "edit") {
|
||||
mainTable.fnUpdate(obj, mainPos);
|
||||
}
|
||||
|
||||
$('#clientNewModal').modal('toggle');
|
||||
} else {
|
||||
alert(data.message);
|
||||
|
||||
if (data.err_code == "99999") {
|
||||
location.href = "/Root/Login";
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('網路或伺服器發生錯誤,請稍後重試!');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#socialNewBtn').on('click', function () {
|
||||
//var src = $('#fileupload-avatar').parent().children('img').prop('src');
|
||||
//var origin = location.origin;
|
||||
//src = src.replace(origin, '');
|
||||
//alert(src);
|
||||
$('#fileupload-subPhoto').parent().children('img').prop('src', '/BackEnd/assets/images/avatars/unknown-profile.jpg');
|
||||
|
||||
$('#photo_method').val('add');
|
||||
$('#socialItemModal').modal('toggle');
|
||||
});
|
||||
|
||||
$('#newsNewModal').on('click', function () {
|
||||
|
||||
//loadTagsInput();
|
||||
|
||||
cleanModalData();
|
||||
|
||||
$('#summernote').summernote('code', '');
|
||||
|
||||
$('#method').val('add');
|
||||
|
||||
$('#clientNewModal').modal('toggle');
|
||||
|
||||
|
||||
});
|
||||
|
||||
$('#optionItemDialogSaveBtn').on('click', function () {
|
||||
var method = $('#photo_method').val();
|
||||
var news_uid = $("#news_uid").val();
|
||||
var photo_uid = $('#photo_uid').val();
|
||||
var photo_title = $('#photo_title').val();
|
||||
var sub_photo = "";
|
||||
|
||||
var src = $('#fileupload-subPhoto').parent().children('img').prop('src');
|
||||
var origin = location.origin;
|
||||
src = src.replace(origin, '');
|
||||
sub_photo = src;
|
||||
|
||||
var err_msg = "";
|
||||
|
||||
if (photo_title == "") {
|
||||
err_msg += "請輸入圖片說明\n";
|
||||
}
|
||||
|
||||
if (src == '/BackEnd/assets/images/avatars/unknown-profile.jpg') {
|
||||
err_msg += "請選擇要顯示的圖片!\n";
|
||||
}
|
||||
|
||||
if (err_msg != "") {
|
||||
alert(err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (method == "add") {
|
||||
var ret = '';
|
||||
ret += '<div class="user-avatar user-avatar-xxl">';
|
||||
ret += ' <img src="' + sub_photo + '" alt="">';
|
||||
ret += '</div>';
|
||||
|
||||
var trHtml = "";
|
||||
trHtml += '<tr>';
|
||||
trHtml += ' <td class="align-middle"> ' + ret + ' </td>';
|
||||
|
||||
trHtml += ' <td class="align-middle"> ' + photo_title + ' </td>';
|
||||
trHtml += ' <td class="align-middle text-right">';
|
||||
trHtml += ' <button type="button" data-uid="" media-uid="' + photo_uid + '" data-method="edit" onclick="buttonClick(this);" class="btn btn-sm btn-icon btn-secondary" data-toggle="modal" data-target="#clientContactEditModal"><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button>';
|
||||
trHtml += ' <button type="button" data-uid="" media-uid="' + photo_uid + '" data-method="del" onclick="buttonClick(this);" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>';
|
||||
trHtml += ' </td>';
|
||||
trHtml += '</tr>';
|
||||
|
||||
$('#media_table tbody').append(trHtml);
|
||||
$('#socialItemModal').modal('toggle');
|
||||
|
||||
}
|
||||
|
||||
if (method == "edit") {
|
||||
mediaTr.find('td').eq(0).find('img').prop('src', sub_photo);
|
||||
mediaTr.find('td').eq(1).text(photo_title);
|
||||
|
||||
|
||||
|
||||
$('#socialItemModal').modal('toggle');
|
||||
}
|
||||
});
|
||||
|
||||
function loadDataTable() {
|
||||
var dataTables = {
|
||||
init: function init() {
|
||||
|
||||
this.bindUIActions();
|
||||
},
|
||||
bindUIActions: function bindUIActions() {
|
||||
|
||||
// event handlers
|
||||
this.table = this.handleDataTables();
|
||||
|
||||
// add buttons
|
||||
//this.table.buttons().container().appendTo('#dt-buttons').unwrap();
|
||||
},
|
||||
handleDataTables: function handleDataTables() {
|
||||
//$('#myTable').append("<tfoot><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr></tfoot>");
|
||||
return $('#dt-responsive').DataTable({
|
||||
dom: '<\'text-muted\'Bif>\n <\'table-responsive\'trl>\n <\'mt-4\'p>',
|
||||
lengthChange: true,
|
||||
lengthMenu: [[25, 50, 100, -1], [25, 50, 100, "All"]],
|
||||
pageLength: 25,
|
||||
buttons: [
|
||||
//{
|
||||
// text: '休假設定',
|
||||
// action: function (e, dt, node, config) {
|
||||
// vacationBtnFun();
|
||||
|
||||
// }
|
||||
//},
|
||||
//'excelHtml5'
|
||||
],
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<i class="fa fa-lg fa-angle-left"></i>',
|
||||
next: '<i class="fa fa-lg fa-angle-right"></i>'
|
||||
},
|
||||
buttons: {
|
||||
copyTitle: 'Data copied',
|
||||
copyKeys: 'Use your keyboard or menu to select the copy command'
|
||||
}
|
||||
},
|
||||
autoWidth: false,
|
||||
ajax: {
|
||||
url: '/BackEndApi/newsList',
|
||||
type: 'POST',
|
||||
data: function (d) {
|
||||
Object.assign(d, {
|
||||
bar_area: $('#bar_area').val(),
|
||||
is_lottery: $('#isLottery').val()
|
||||
});
|
||||
|
||||
return d;
|
||||
},
|
||||
dataSrc: 'newsList'
|
||||
},
|
||||
rowId: 'news_uid',
|
||||
deferRender: true,
|
||||
initComplete: function () {
|
||||
$('#dt-responsive').on('click', 'a', function () {
|
||||
buttonClick2(this);
|
||||
});
|
||||
|
||||
$('#dt-responsive').on('click', 'button', function () {
|
||||
buttonClick2(this);
|
||||
});
|
||||
|
||||
$('#dt-responsive').on('click', 'input[name="selectedRow[]"]', function () {
|
||||
checkboxClick(this);
|
||||
});
|
||||
},
|
||||
order: [[1, 'desc']],
|
||||
info: true,
|
||||
search: "搜尋:",
|
||||
searching: true,
|
||||
columns: [{ data: 'news_mainPhoto', className: 'align-middle', orderable: false, searchable: false },
|
||||
{ data: 'news_date', className: 'align-middle text-left', orderable: true, searchable: true },
|
||||
{ data: 'news_title', className: 'align-middle text-left', orderable: true, searchable: true },
|
||||
{ data: 'news_uid', className: 'align-middle text-left', orderable: false, searchable: true }],
|
||||
columnDefs: [
|
||||
{
|
||||
targets: 0,
|
||||
className: 'align-middle text-center',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function render(data, type, row, meta) {
|
||||
var ret = '';
|
||||
ret += '<div class="user-avatar user-avatar-xxl">';
|
||||
ret += ' <img src="' + row.news_mainPhoto + '" alt="">';
|
||||
ret += '</div>';
|
||||
return ret;
|
||||
//return row.gift_city + row.gift_area + row.gift_address;
|
||||
//var editRet = '<a id="table-btn" class="btn btn-sm btn-secondary" href="javascript: void(0);" data-method="edit" data-uid="' + row.quotation_serial + '"><i class="fa fa-pencil-alt"></i></a> <a id="table-btn" class="btn btn-sm btn-secondary" href="javascript: void(0);" data-method="setting" data-uid="' + row.quotation_serial + '"><i class="fas fa-cog"></i></a>';
|
||||
|
||||
//if (row.quotationUser_perm == "A" || row.quotationUser_perm == "D" || row.quotationUser_perm == "admin" || row.quotationUser_perm == "pro") {
|
||||
// editRet = editRet + ' <a id="table-btn" class="btn btn-sm btn-secondary" href="javascript: void(0);" data-method="del" data-uid="' + row.quotation_serial + '"><i class="far fa-trash-alt"></i></a>';
|
||||
//}
|
||||
//return editRet;
|
||||
}
|
||||
}
|
||||
, {
|
||||
targets: 3,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function render(data, type, row, meta) {
|
||||
var ret = '';
|
||||
|
||||
ret += '<button type="button" data-uid="' + row.news_uid + '" data-method="edit" class="btn btn-sm btn-icon btn-secondary" ><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button>';
|
||||
ret += '<button type="button" data-uid="' + row.news_uid + '" data-method="del" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>';
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
});
|
||||
},
|
||||
handleSearchRecords: function handleSearchRecords() {
|
||||
var self = this;
|
||||
|
||||
$('#table-search, #filterBy').on('keyup change focus', function (e) {
|
||||
var filterBy = $('#filterBy').val();
|
||||
var hasFilter = filterBy !== '';
|
||||
var value = $('#table-search').val();
|
||||
|
||||
self.table.search('').columns().search('').draw();
|
||||
|
||||
if (hasFilter) {
|
||||
self.table.columns(filterBy).search(value).draw();
|
||||
} else {
|
||||
self.table.search(value).draw();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
dataTables.init();
|
||||
}
|
||||
|
||||
function loadTagsInput() {
|
||||
$('#news_tags').select2({
|
||||
width: '100%',
|
||||
tags: true,
|
||||
tokenSeparators: [',', ' '],
|
||||
multiple: true,
|
||||
minimumInputLength: 2,
|
||||
placeholder: '輸入Tag用空白或逗號分隔關鍵字',
|
||||
ajax: {
|
||||
url: '/BackEndApi/queryTags',
|
||||
dataType: 'json',
|
||||
delay: 500,
|
||||
type: 'post',
|
||||
// 要送出的資料
|
||||
data: function (params) {
|
||||
// 在伺服器會得到一個 POST 'search'
|
||||
return {
|
||||
search: params.term
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
console.log(data.data)
|
||||
|
||||
// 一定要返回 results 物件
|
||||
return {
|
||||
results: data.data,
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
createTag: function (params) {
|
||||
let term = $.trim(params.term);
|
||||
if (term.length < 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
id: term,
|
||||
text: term,
|
||||
// add indicator:
|
||||
isNew: true
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$('#news_tags').on('select2:select', function (e) {
|
||||
let tag = e.params.data;
|
||||
var formData = {
|
||||
search: tag.text
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/BackEndApi/updateTags",
|
||||
type: "post",
|
||||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var obj = data.data;
|
||||
if (data.ret == "yes") {
|
||||
$('#news_tags').find('[value="' + tag.text + '"]').replaceWith('<option selected value="' + obj.id + '">' + obj.text + '</option>');
|
||||
|
||||
|
||||
} else {
|
||||
alert(data.message);
|
||||
|
||||
if (data.err_code == "99999") {
|
||||
location.href = "/Root/Login";
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('網路或伺服器發生錯誤,請稍後重試!');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function buttonClick2(obj) {
|
||||
var type = obj.getAttribute('data-method');
|
||||
var uid = obj.getAttribute('data-uid');
|
||||
|
||||
mainTable = $('#dt-responsive').dataTable();
|
||||
mainRowID = $('#' + uid);
|
||||
|
||||
mainPos = mainTable.fnGetPosition($('#' + uid)[0]);
|
||||
|
||||
if (type == "del") {
|
||||
if (confirm('確定刪除此筆資料? 刪除後將無任何方法回復!')) {
|
||||
var formData = {
|
||||
method: "del",
|
||||
news_uid: uid
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/BackEndApi/newsAddEditDelGet",
|
||||
type: "post",
|
||||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (data.ret == "yes") {
|
||||
var row = mainTable.api().row(mainRowID).remove().draw(false);
|
||||
alert('刪除完成!');
|
||||
|
||||
} else {
|
||||
alert(data.message);
|
||||
|
||||
if (data.err_code == "9999") {
|
||||
location.href = "/Home/Index";
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('網路或伺服器發生錯誤,請稍後重試!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (type == "edit") {
|
||||
$('#method').val('edit');
|
||||
$('#news_uid').val(uid);
|
||||
|
||||
var formData = {
|
||||
method: "get",
|
||||
news_uid: uid
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/BackEndApi/newsAddEditDelGet",
|
||||
type: "post",
|
||||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (data.ret == "yes") {
|
||||
cleanModalData();
|
||||
|
||||
var obj = data.data;
|
||||
$('#method').val('edit');
|
||||
$('#news_uid').val(uid);
|
||||
$('#news_title').val(obj.news_title).trigger('change');
|
||||
$('#news_subtitle').val(obj.news_subtitle).trigger('change');
|
||||
$('#fileupload-avatar').parent().children('img').prop('src', obj.news_mainPhoto);
|
||||
$('#news_date').val(obj.news_date).trigger('change');
|
||||
$('#summernote').summernote('code', obj.news_content);
|
||||
|
||||
$.each(obj.tags, function (key, value) {
|
||||
//var tagObj = {};
|
||||
//tagObj.id = value.tag_uid;
|
||||
//tagObj.text = value.tag_text;
|
||||
|
||||
//tagArray.push(tagObj);
|
||||
//tagValArray.push(value.tag_uid);
|
||||
|
||||
var newOption = new Option(value.tag_text, value.tag_uid, true, true);
|
||||
$('#news_tags').append(newOption).trigger('change');
|
||||
});
|
||||
|
||||
$.each(obj.photos, function (key, value) {
|
||||
var ret = '';
|
||||
ret += '<div class="user-avatar user-avatar-xxl">';
|
||||
ret += ' <img src="' + value.photo_path + '" alt="">';
|
||||
ret += '</div>';
|
||||
|
||||
var trHtml = "";
|
||||
trHtml += '<tr>';
|
||||
trHtml += ' <td class="align-middle"> ' + ret + ' </td>';
|
||||
|
||||
trHtml += ' <td class="align-middle"> ' + value.photo_title + ' </td>';
|
||||
trHtml += ' <td class="align-middle text-right">';
|
||||
trHtml += ' <button type="button" data-uid="" media-uid="' + value.photo_uid + '" data-method="edit" onclick="buttonClick(this);" class="btn btn-sm btn-icon btn-secondary" data-toggle="modal" data-target="#clientContactEditModal"><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button>';
|
||||
trHtml += ' <button type="button" data-uid="" media-uid="' + value.photo_uid + '" data-method="del" onclick="buttonClick(this);" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>';
|
||||
trHtml += ' </td>';
|
||||
trHtml += '</tr>';
|
||||
|
||||
$('#media_table tbody').append(trHtml);
|
||||
//$("input:checkbox[value='" + value.optionItem_uid + "']").prop('checked', true);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$('#clientNewModal').modal('toggle');
|
||||
} else {
|
||||
alert(data.message);
|
||||
|
||||
if (data.err_code == "9999") {
|
||||
location.href = "/Home/Index";
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('網路或伺服器發生錯誤,請稍後重試!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buttonClick(obj) {
|
||||
mediaTr = $(obj).closest('tr');
|
||||
|
||||
var dataMethod = obj.getAttribute('data-method');
|
||||
var dataUid = obj.getAttribute('data-uid');
|
||||
var photo_uid = obj.getAttribute('media-uid');
|
||||
var photo_src = mediaTr.find('td').eq(0).find('img').prop('src').trim();
|
||||
var photo_title = mediaTr.find('td').eq(1).text().trim();
|
||||
|
||||
var origin = location.origin;
|
||||
photo_src = photo_src.replace(origin, '');
|
||||
|
||||
|
||||
if (dataMethod == 'edit') {
|
||||
$('#photo_method').val('edit');
|
||||
$('#photo_uid').val(photo_uid);
|
||||
|
||||
$('#fileupload-subPhoto').parent().children('img').prop('src', photo_src);
|
||||
|
||||
$('#photo_title').val(photo_title).trigger('change');
|
||||
|
||||
$('#socialItemModal').modal('toggle');
|
||||
}
|
||||
|
||||
if (dataMethod == "del") {
|
||||
if (confirm('確定刪除此筆資料?')) {
|
||||
|
||||
|
||||
mediaTr.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cleanModalData() {
|
||||
$("#method").val("");
|
||||
$("#news_uid").val("");
|
||||
$("#news_title").val("");
|
||||
$("#news_subtitle").val("");
|
||||
$("#news_date").val("");
|
||||
|
||||
|
||||
$('#fileupload-avatar').parent().children('img').prop('src', '/BackEnd/assets/images/avatars/unknown-profile.jpg');
|
||||
|
||||
|
||||
var trList = $("#media_table").find("tbody").find("tr");
|
||||
$.each(trList, function (index, item) {
|
||||
$(item).remove();
|
||||
});
|
||||
$('#news_tags').empty();
|
||||
$('#news_tags').val(null).trigger('change')
|
||||
}
|
||||
|
||||
function initMainPhotoUpload() {
|
||||
var url = "/BackEndApi/mainPhotoUpload";
|
||||
|
||||
// =============================================================
|
||||
|
||||
$('#fileupload-avatar').fileupload({
|
||||
url: url,
|
||||
dropZone: null,
|
||||
dataType: 'json',
|
||||
autoUpload: true,
|
||||
acceptFileTypes: /(\.|\/)(jpe?g|png)$/i,
|
||||
maxFileSize: 5000000
|
||||
}).on('fileuploadprocessalways', function (e, data) {
|
||||
var index = data.index;
|
||||
var file = data.files[index];
|
||||
$('#avatar-warning-container').removeClass('show').text('');
|
||||
|
||||
if (file.error) {
|
||||
$('#avatar-warning-container').addClass('show').text(file.error);
|
||||
}
|
||||
}).on('fileuploadprogressall', function (e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
$('#progress-avatar').addClass('show').children().css('width', progress + '%');
|
||||
}).on('fileuploaddone', function (e, data) {
|
||||
var file = data.result.files[0];
|
||||
var $img = $(this).parent().children('img');
|
||||
var $old = $img.prop('src');
|
||||
|
||||
if (file.url) {
|
||||
$img.prop('src', file.url);
|
||||
} else if (file.error) {
|
||||
$('#avatar-warning-container').addClass('show').text(file.error);
|
||||
}
|
||||
|
||||
$('#progress-avatar').removeClass('show').children().css('width', 0);
|
||||
}); // File upload using button
|
||||
// =============================================================
|
||||
}
|
||||
|
||||
function initSubPhotoUpload() {
|
||||
var url = "/BackEndApi/subPhotoUpload";
|
||||
|
||||
// =============================================================
|
||||
|
||||
$('#fileupload-subPhoto').fileupload({
|
||||
url: url,
|
||||
dropZone: null,
|
||||
dataType: 'json',
|
||||
autoUpload: true,
|
||||
acceptFileTypes: /(\.|\/)(jpe?g|png)$/i,
|
||||
maxFileSize: 5000000
|
||||
}).on('fileuploadprocessalways', function (e, data) {
|
||||
var index = data.index;
|
||||
var file = data.files[index];
|
||||
$('#avatar-warning-container').removeClass('show').text('');
|
||||
|
||||
if (file.error) {
|
||||
$('#avatar-warning-container').addClass('show').text(file.error);
|
||||
}
|
||||
}).on('fileuploadprogressall', function (e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
$('#progress-avatar').addClass('show').children().css('width', progress + '%');
|
||||
}).on('fileuploaddone', function (e, data) {
|
||||
var file = data.result.files[0];
|
||||
var $img = $(this).parent().children('img');
|
||||
var $old = $img.prop('src');
|
||||
|
||||
if (file.url) {
|
||||
$img.prop('src', file.url);
|
||||
} else if (file.error) {
|
||||
$('#avatar-warning-container').addClass('show').text(file.error);
|
||||
}
|
||||
|
||||
$('#progress-avatar').removeClass('show').children().css('width', 0);
|
||||
}); // File upload using button
|
||||
// =============================================================
|
||||
}
|
||||
|
||||
function initSummernote() {
|
||||
$('#summernote').summernote({
|
||||
height: 250,
|
||||
toolbar: [
|
||||
// [groupName, [list of button]]
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['insert', ['link']],
|
||||
['para', ['ul', 'paragraph']]
|
||||
],onPaste: function (e) {
|
||||
var bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');
|
||||
e.preventDefault();
|
||||
document.execCommand('insertText', false, bufferText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
MIT License
|
||||
|
||||
Copyright © 2012 Sebastian Tschan, https://blueimp.net
|
||||
|
||||
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.
|
||||
2
wwwroot/BackEnd/assets/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.min.js
vendored
Normal file
2
wwwroot/BackEnd/assets/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.min.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
!function(t){"use strict";var r=t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype,f=t.Blob&&function(){try{return Boolean(new Blob)}catch(t){return!1}}(),b=f&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(t){return!1}}(),d=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,B=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,a=(f||d)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(t){var e,o,n,r,a,i,l,u,c;if(!(e=t.match(B)))throw new Error("invalid data URI");for(o=e[2]?e[1]:"text/plain"+(e[3]||";charset=US-ASCII"),n=!!e[4],r=t.slice(e[0].length),a=(n?atob:decodeURIComponent)(r),i=new ArrayBuffer(a.length),l=new Uint8Array(i),u=0;u<a.length;u+=1)l[u]=a.charCodeAt(u);return f?new Blob([b?l:i],{type:o}):((c=new d).append(i),c.getBlob(o))};t.HTMLCanvasElement&&!r.toBlob&&(r.mozGetAsFile?r.toBlob=function(t,e,o){var n=this;setTimeout(function(){o&&r.toDataURL&&a?t(a(n.toDataURL(e,o))):t(n.mozGetAsFile("blob",e))})}:r.toDataURL&&a&&(r.toBlob=function(t,e,o){var n=this;setTimeout(function(){t(a(n.toDataURL(e,o)))})})),"function"==typeof define&&define.amd?define(function(){return a}):"object"==typeof module&&module.exports?module.exports=a:t.dataURLtoBlob=a}(window);
|
||||
//# sourceMappingURL=canvas-to-blob.min.js.map
|
||||
1
wwwroot/BackEnd/assets/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.min.js.map
vendored
Normal file
1
wwwroot/BackEnd/assets/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.min.js.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["canvas-to-blob.js"],"names":["window","CanvasPrototype","HTMLCanvasElement","prototype","hasBlobConstructor","Blob","Boolean","e","hasArrayBufferViewSupport","Uint8Array","size","BlobBuilder","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","dataURIPattern","dataURLtoBlob","atob","ArrayBuffer","dataURI","matches","mediaType","isBase64","dataString","byteString","arrayBuffer","intArray","i","bb","match","Error","slice","length","decodeURIComponent","charCodeAt","type","append","getBlob","toBlob","mozGetAsFile","callback","quality","self","this","setTimeout","toDataURL","define","amd","module","exports"],"mappings":"CAgBC,SAAWA,GACV,aAEA,IAAIC,EACFD,EAAOE,mBAAqBF,EAAOE,kBAAkBC,UACnDC,EACFJ,EAAOK,MACP,WACE,IACE,OAAOC,QAAQ,IAAID,MACnB,MAAOE,GACP,OAAO,GAJX,GAOEC,EACFJ,GACAJ,EAAOS,YACP,WACE,IACE,OAAgD,MAAzC,IAAIJ,KAAK,CAAC,IAAII,WAAW,OAAOC,KACvC,MAAOH,GACP,OAAO,GAJX,GAOEI,EACFX,EAAOW,aACPX,EAAOY,mBACPZ,EAAOa,gBACPb,EAAOc,cACLC,EAAiB,0CACjBC,GACDZ,GAAsBO,IACvBX,EAAOiB,MACPjB,EAAOkB,aACPlB,EAAOS,YACP,SAAUU,GACR,IAAIC,EACFC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGF,KADAR,EAAUD,EAAQU,MAAMd,IAEtB,MAAM,IAAIe,MAAM,oBAkBlB,IAfAT,EAAYD,EAAQ,GAChBA,EAAQ,GACR,cAAgBA,EAAQ,IAAM,qBAClCE,IAAaF,EAAQ,GACrBG,EAAaJ,EAAQY,MAAMX,EAAQ,GAAGY,QAGpCR,GAFEF,EAEWL,KAGAgB,oBAHKV,GAMpBE,EAAc,IAAIP,YAAYM,EAAWQ,QACzCN,EAAW,IAAIjB,WAAWgB,GACrBE,EAAI,EAAGA,EAAIH,EAAWQ,OAAQL,GAAK,EACtCD,EAASC,GAAKH,EAAWU,WAAWP,GAGtC,OAAIvB,EACK,IAAIC,KAAK,CAACG,EAA4BkB,EAAWD,GAAc,CACpEU,KAAMd,MAGVO,EAAK,IAAIjB,GACNyB,OAAOX,GACHG,EAAGS,QAAQhB,KAElBrB,EAAOE,oBAAsBD,EAAgBqC,SAC3CrC,EAAgBsC,aAClBtC,EAAgBqC,OAAS,SAAUE,EAAUL,EAAMM,GACjD,IAAIC,EAAOC,KACXC,WAAW,WACLH,GAAWxC,EAAgB4C,WAAa7B,EAC1CwB,EAASxB,EAAc0B,EAAKG,UAAUV,EAAMM,KAE5CD,EAASE,EAAKH,aAAa,OAAQJ,OAIhClC,EAAgB4C,WAAa7B,IACtCf,EAAgBqC,OAAS,SAAUE,EAAUL,EAAMM,GACjD,IAAIC,EAAOC,KACXC,WAAW,WACTJ,EAASxB,EAAc0B,EAAKG,UAAUV,EAAMM,UAK9B,mBAAXK,QAAyBA,OAAOC,IACzCD,OAAO,WACL,OAAO9B,IAEkB,iBAAXgC,QAAuBA,OAAOC,QAC9CD,OAAOC,QAAUjC,EAEjBhB,EAAOgB,cAAgBA,EA3G1B,CA6GEhB"}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
MIT License
|
||||
|
||||
Copyright © 2010 Sebastian Tschan, https://blueimp.net
|
||||
|
||||
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.
|
||||
22
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-noscript.css
vendored
Normal file
22
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-noscript.css
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload Plugin NoScript CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button input {
|
||||
position: static;
|
||||
opacity: 1;
|
||||
filter: none;
|
||||
font-size: inherit !important;
|
||||
direction: inherit;
|
||||
}
|
||||
.fileinput-button span {
|
||||
display: none;
|
||||
}
|
||||
17
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-ui-noscript.css
vendored
Normal file
17
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-ui-noscript.css
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload UI Plugin NoScript CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button i,
|
||||
.fileupload-buttonbar .delete,
|
||||
.fileupload-buttonbar .toggle {
|
||||
display: none;
|
||||
}
|
||||
61
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-ui.css
vendored
Normal file
61
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/css/jquery.fileupload-ui.css
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload UI Plugin CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.progress-animated .progress-bar,
|
||||
.progress-animated .bar {
|
||||
background: url('../img/progressbar.gif') !important;
|
||||
filter: none;
|
||||
}
|
||||
.fileupload-process {
|
||||
float: right;
|
||||
display: none;
|
||||
}
|
||||
.fileupload-processing .fileupload-process,
|
||||
.files .processing .preview {
|
||||
display: block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url('../img/loading.gif') center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 300px;
|
||||
}
|
||||
.toggle[type='checkbox'] {
|
||||
transform: scale(2);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.fileupload-buttonbar .btn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.fileupload-buttonbar .delete,
|
||||
.fileupload-buttonbar .toggle,
|
||||
.files .toggle,
|
||||
.files .btn span {
|
||||
display: none;
|
||||
}
|
||||
.files .name {
|
||||
width: 80px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 80px;
|
||||
}
|
||||
.files img,
|
||||
.files canvas {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload Plugin CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
.fileinput-button input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
-ms-filter: 'alpha(opacity=0)';
|
||||
font-size: 200px !important;
|
||||
direction: ltr;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Fixes for IE < 8 */
|
||||
@media screen\9 {
|
||||
.fileinput-button input {
|
||||
filter: alpha(opacity=0);
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
126
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/cors/jquery.postmessage-transport.js
vendored
Normal file
126
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/cors/jquery.postmessage-transport.js
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* jQuery postMessage Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var counter = 0,
|
||||
names = [
|
||||
'accepts',
|
||||
'cache',
|
||||
'contents',
|
||||
'contentType',
|
||||
'crossDomain',
|
||||
'data',
|
||||
'dataType',
|
||||
'headers',
|
||||
'ifModified',
|
||||
'mimeType',
|
||||
'password',
|
||||
'processData',
|
||||
'timeout',
|
||||
'traditional',
|
||||
'type',
|
||||
'url',
|
||||
'username'
|
||||
],
|
||||
convert = function (p) {
|
||||
return p;
|
||||
};
|
||||
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'postmessage text': convert,
|
||||
'postmessage json': convert,
|
||||
'postmessage html': convert
|
||||
}
|
||||
});
|
||||
|
||||
$.ajaxTransport('postmessage', function (options) {
|
||||
if (options.postMessage && window.postMessage) {
|
||||
var iframe,
|
||||
loc = $('<a>').prop('href', options.postMessage)[0],
|
||||
target = loc.protocol + '//' + loc.host,
|
||||
xhrUpload = options.xhr().upload;
|
||||
// IE always includes the port for the host property of a link
|
||||
// element, but not in the location.host or origin property for the
|
||||
// default http port 80 and https port 443, so we strip it:
|
||||
if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
|
||||
target = target.replace(/:(80|443)$/, '');
|
||||
}
|
||||
return {
|
||||
send: function (_, completeCallback) {
|
||||
counter += 1;
|
||||
var message = {
|
||||
id: 'postmessage-transport-' + counter
|
||||
},
|
||||
eventName = 'message.' + message.id;
|
||||
iframe = $(
|
||||
'<iframe style="display:none;" src="' +
|
||||
options.postMessage +
|
||||
'" name="' +
|
||||
message.id +
|
||||
'"></iframe>'
|
||||
)
|
||||
.on('load', function () {
|
||||
$.each(names, function (i, name) {
|
||||
message[name] = options[name];
|
||||
});
|
||||
message.dataType = message.dataType.replace('postmessage ', '');
|
||||
$(window).on(eventName, function (event) {
|
||||
var e = event.originalEvent;
|
||||
var data = e.data;
|
||||
var ev;
|
||||
if (e.origin === target && data.id === message.id) {
|
||||
if (data.type === 'progress') {
|
||||
ev = document.createEvent('Event');
|
||||
ev.initEvent(data.type, false, true);
|
||||
$.extend(ev, data);
|
||||
xhrUpload.dispatchEvent(ev);
|
||||
} else {
|
||||
completeCallback(
|
||||
data.status,
|
||||
data.statusText,
|
||||
{ postmessage: data.result },
|
||||
data.headers
|
||||
);
|
||||
iframe.remove();
|
||||
$(window).off(eventName);
|
||||
}
|
||||
}
|
||||
});
|
||||
iframe[0].contentWindow.postMessage(message, target);
|
||||
})
|
||||
.appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
iframe.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
97
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/cors/jquery.xdr-transport.js
vendored
Normal file
97
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/cors/jquery.xdr-transport.js
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* jQuery XDomainRequest Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
* Based on Julian Aubourg's ajaxHooks xdr.js:
|
||||
* https://github.com/jaubourg/ajaxHooks/
|
||||
*/
|
||||
|
||||
/* global define, require, XDomainRequest */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
if (window.XDomainRequest && !$.support.cors) {
|
||||
$.ajaxTransport(function (s) {
|
||||
if (s.crossDomain && s.async) {
|
||||
if (s.timeout) {
|
||||
s.xdrTimeout = s.timeout;
|
||||
delete s.timeout;
|
||||
}
|
||||
var xdr;
|
||||
return {
|
||||
send: function (headers, completeCallback) {
|
||||
var addParamChar = /\?/.test(s.url) ? '&' : '?';
|
||||
/**
|
||||
* Callback wrapper function
|
||||
*
|
||||
* @param {number} status HTTP status code
|
||||
* @param {string} statusText HTTP status text
|
||||
* @param {object} [responses] Content-type specific responses
|
||||
* @param {string} [responseHeaders] Response headers string
|
||||
*/
|
||||
function callback(status, statusText, responses, responseHeaders) {
|
||||
xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
|
||||
xdr = null;
|
||||
completeCallback(status, statusText, responses, responseHeaders);
|
||||
}
|
||||
xdr = new XDomainRequest();
|
||||
// XDomainRequest only supports GET and POST:
|
||||
if (s.type === 'DELETE') {
|
||||
s.url = s.url + addParamChar + '_method=DELETE';
|
||||
s.type = 'POST';
|
||||
} else if (s.type === 'PUT') {
|
||||
s.url = s.url + addParamChar + '_method=PUT';
|
||||
s.type = 'POST';
|
||||
} else if (s.type === 'PATCH') {
|
||||
s.url = s.url + addParamChar + '_method=PATCH';
|
||||
s.type = 'POST';
|
||||
}
|
||||
xdr.open(s.type, s.url);
|
||||
xdr.onload = function () {
|
||||
callback(
|
||||
200,
|
||||
'OK',
|
||||
{ text: xdr.responseText },
|
||||
'Content-Type: ' + xdr.contentType
|
||||
);
|
||||
};
|
||||
xdr.onerror = function () {
|
||||
callback(404, 'Not Found');
|
||||
};
|
||||
if (s.xdrTimeout) {
|
||||
xdr.ontimeout = function () {
|
||||
callback(0, 'timeout');
|
||||
};
|
||||
xdr.timeout = s.xdrTimeout;
|
||||
}
|
||||
xdr.send((s.hasContent && s.data) || null);
|
||||
},
|
||||
abort: function () {
|
||||
if (xdr) {
|
||||
xdr.onerror = $.noop();
|
||||
xdr.abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
101
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-audio.js
vendored
Normal file
101
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-audio.js
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* jQuery File Upload Audio Preview Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery', 'load-image', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('blueimp-load-image/js/load-image'),
|
||||
require('./jquery.fileupload-process')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadAudio',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
disabled: '@disableAudioPreview'
|
||||
},
|
||||
{
|
||||
action: 'setAudio',
|
||||
name: '@audioPreviewName',
|
||||
disabled: '@disableAudioPreview'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Audio Preview plugin extends the fileupload widget
|
||||
// with audio preview functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
// The regular expression for the types of audio files to load,
|
||||
// matched against the file type:
|
||||
loadAudioFileTypes: /^audio\/.*$/
|
||||
},
|
||||
|
||||
_audioElement: document.createElement('audio'),
|
||||
|
||||
processActions: {
|
||||
// Loads the audio file given via data.files and data.index
|
||||
// as audio element if the browser supports playing it.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadAudio: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
audio;
|
||||
if (
|
||||
this._audioElement.canPlayType &&
|
||||
this._audioElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes || options.fileTypes.test(file.type))
|
||||
) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
audio = this._audioElement.cloneNode(false);
|
||||
audio.src = url;
|
||||
audio.controls = true;
|
||||
data.audio = audio;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the audio element as a property of the file object:
|
||||
setAudio: function (data, options) {
|
||||
if (data.audio && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.audio;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
339
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-image.js
vendored
Normal file
339
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-image.js
vendored
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* jQuery File Upload Image Preview & Resize Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'load-image-meta',
|
||||
'load-image-scale',
|
||||
'load-image-exif',
|
||||
'canvas-to-blob',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('blueimp-load-image/js/load-image'),
|
||||
require('blueimp-load-image/js/load-image-meta'),
|
||||
require('blueimp-load-image/js/load-image-scale'),
|
||||
require('blueimp-load-image/js/load-image-exif'),
|
||||
require('blueimp-canvas-to-blob'),
|
||||
require('./jquery.fileupload-process')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadImageMetaData',
|
||||
disableImageHead: '@',
|
||||
disableExif: '@',
|
||||
disableExifThumbnail: '@',
|
||||
disableExifSub: '@',
|
||||
disableExifGps: '@',
|
||||
disabled: '@disableImageMetaDataLoad'
|
||||
},
|
||||
{
|
||||
action: 'loadImage',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
noRevoke: '@',
|
||||
disabled: '@disableImageLoad'
|
||||
},
|
||||
{
|
||||
action: 'resizeImage',
|
||||
// Use "image" as prefix for the "@" options:
|
||||
prefix: 'image',
|
||||
maxWidth: '@',
|
||||
maxHeight: '@',
|
||||
minWidth: '@',
|
||||
minHeight: '@',
|
||||
crop: '@',
|
||||
orientation: '@',
|
||||
forceResize: '@',
|
||||
disabled: '@disableImageResize'
|
||||
},
|
||||
{
|
||||
action: 'saveImage',
|
||||
quality: '@imageQuality',
|
||||
type: '@imageType',
|
||||
disabled: '@disableImageResize'
|
||||
},
|
||||
{
|
||||
action: 'saveImageMetaData',
|
||||
disabled: '@disableImageMetaDataSave'
|
||||
},
|
||||
{
|
||||
action: 'resizeImage',
|
||||
// Use "preview" as prefix for the "@" options:
|
||||
prefix: 'preview',
|
||||
maxWidth: '@',
|
||||
maxHeight: '@',
|
||||
minWidth: '@',
|
||||
minHeight: '@',
|
||||
crop: '@',
|
||||
orientation: '@',
|
||||
thumbnail: '@',
|
||||
canvas: '@',
|
||||
disabled: '@disableImagePreview'
|
||||
},
|
||||
{
|
||||
action: 'setImage',
|
||||
name: '@imagePreviewName',
|
||||
disabled: '@disableImagePreview'
|
||||
},
|
||||
{
|
||||
action: 'deleteImageReferences',
|
||||
disabled: '@disableImageReferencesDeletion'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Resize plugin extends the fileupload widget
|
||||
// with image resize functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
// The regular expression for the types of images to load:
|
||||
// matched against the file type:
|
||||
loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
|
||||
// The maximum file size of images to load:
|
||||
loadImageMaxFileSize: 10000000, // 10MB
|
||||
// The maximum width of resized images:
|
||||
imageMaxWidth: 1920,
|
||||
// The maximum height of resized images:
|
||||
imageMaxHeight: 1080,
|
||||
// Defines the image orientation (1-8) or takes the orientation
|
||||
// value from Exif data if set to true:
|
||||
imageOrientation: false,
|
||||
// Define if resized images should be cropped or only scaled:
|
||||
imageCrop: false,
|
||||
// Disable the resize image functionality by default:
|
||||
disableImageResize: true,
|
||||
// The maximum width of the preview images:
|
||||
previewMaxWidth: 80,
|
||||
// The maximum height of the preview images:
|
||||
previewMaxHeight: 80,
|
||||
// Defines the preview orientation (1-8) or takes the orientation
|
||||
// value from Exif data if set to true:
|
||||
previewOrientation: true,
|
||||
// Create the preview using the Exif data thumbnail:
|
||||
previewThumbnail: true,
|
||||
// Define if preview images should be cropped or only scaled:
|
||||
previewCrop: false,
|
||||
// Define if preview images should be resized as canvas elements:
|
||||
previewCanvas: true
|
||||
},
|
||||
|
||||
processActions: {
|
||||
// Loads the image given via data.files and data.index
|
||||
// as img element, if the browser supports the File API.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadImage: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
if (
|
||||
($.type(options.maxFileSize) === 'number' &&
|
||||
file.size > options.maxFileSize) ||
|
||||
(options.fileTypes && !options.fileTypes.test(file.type)) ||
|
||||
!loadImage(
|
||||
file,
|
||||
function (img) {
|
||||
if (img.src) {
|
||||
data.img = img;
|
||||
}
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options
|
||||
)
|
||||
) {
|
||||
return data;
|
||||
}
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
// Resizes the image given as data.canvas or data.img
|
||||
// and updates data.canvas or data.img with the resized image.
|
||||
// Also stores the resized image as preview property.
|
||||
// Accepts the options maxWidth, maxHeight, minWidth,
|
||||
// minHeight, canvas and crop:
|
||||
resizeImage: function (data, options) {
|
||||
if (options.disabled || !(data.canvas || data.img)) {
|
||||
return data;
|
||||
}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = $.extend({ canvas: true }, options);
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred(),
|
||||
img = (options.canvas && data.canvas) || data.img,
|
||||
resolve = function (newImg) {
|
||||
if (
|
||||
newImg &&
|
||||
(newImg.width !== img.width ||
|
||||
newImg.height !== img.height ||
|
||||
options.forceResize)
|
||||
) {
|
||||
data[newImg.getContext ? 'canvas' : 'img'] = newImg;
|
||||
}
|
||||
data.preview = newImg;
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
thumbnail;
|
||||
if (data.exif) {
|
||||
if (options.orientation === true) {
|
||||
options.orientation = data.exif.get('Orientation');
|
||||
}
|
||||
if (options.thumbnail) {
|
||||
thumbnail = data.exif.get('Thumbnail');
|
||||
if (thumbnail) {
|
||||
loadImage(thumbnail, resolve, options);
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
// Prevent orienting the same image twice:
|
||||
if (data.orientation) {
|
||||
delete options.orientation;
|
||||
} else {
|
||||
data.orientation = options.orientation;
|
||||
}
|
||||
}
|
||||
if (img) {
|
||||
resolve(loadImage.scale(img, options));
|
||||
return dfd.promise();
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Saves the processed image given as data.canvas
|
||||
// inplace at data.index of data.files:
|
||||
saveImage: function (data, options) {
|
||||
if (!data.canvas || options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
if (data.canvas.toBlob) {
|
||||
data.canvas.toBlob(
|
||||
function (blob) {
|
||||
if (!blob.name) {
|
||||
if (file.type === blob.type) {
|
||||
blob.name = file.name;
|
||||
} else if (file.name) {
|
||||
blob.name = file.name.replace(
|
||||
/\.\w+$/,
|
||||
'.' + blob.type.substr(6)
|
||||
);
|
||||
}
|
||||
}
|
||||
// Don't restore invalid meta data:
|
||||
if (file.type !== blob.type) {
|
||||
delete data.imageHead;
|
||||
}
|
||||
// Store the created blob at the position
|
||||
// of the original file in the files list:
|
||||
data.files[data.index] = blob;
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options.type || file.type,
|
||||
options.quality
|
||||
);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
loadImageMetaData: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
loadImage.parseMetaData(
|
||||
data.files[data.index],
|
||||
function (result) {
|
||||
$.extend(data, result);
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options
|
||||
);
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
saveImageMetaData: function (data, options) {
|
||||
if (
|
||||
!(
|
||||
data.imageHead &&
|
||||
data.canvas &&
|
||||
data.canvas.toBlob &&
|
||||
!options.disabled
|
||||
)
|
||||
) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
blob = new Blob(
|
||||
[
|
||||
data.imageHead,
|
||||
// Resized images always have a head size of 20 bytes,
|
||||
// including the JPEG marker and a minimal JFIF header:
|
||||
this._blobSlice.call(file, 20)
|
||||
],
|
||||
{ type: file.type }
|
||||
);
|
||||
blob.name = file.name;
|
||||
data.files[data.index] = blob;
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the resized version of the image as a property of the
|
||||
// file object, must be called after "saveImage":
|
||||
setImage: function (data, options) {
|
||||
if (data.preview && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.preview;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
deleteImageReferences: function (data, options) {
|
||||
if (!options.disabled) {
|
||||
delete data.img;
|
||||
delete data.canvas;
|
||||
delete data.preview;
|
||||
delete data.imageHead;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
169
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-process.js
vendored
Normal file
169
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-process.js
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* jQuery File Upload Processing Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery', './jquery.fileupload'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'), require('./jquery.fileupload'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var originalAdd = $.blueimp.fileupload.prototype.options.add;
|
||||
|
||||
// The File Upload Processing plugin extends the fileupload widget
|
||||
// with file processing functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
// The list of processing actions:
|
||||
processQueue: [
|
||||
/*
|
||||
{
|
||||
action: 'log',
|
||||
type: 'debug'
|
||||
}
|
||||
*/
|
||||
],
|
||||
add: function (e, data) {
|
||||
var $this = $(this);
|
||||
data.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
});
|
||||
originalAdd.call(this, e, data);
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
/*
|
||||
log: function (data, options) {
|
||||
console[options.type](
|
||||
'Processing "' + data.files[data.index].name + '"'
|
||||
);
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
_processFile: function (data, originalData) {
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred().resolveWith(that, [data]),
|
||||
chain = dfd.promise();
|
||||
this._trigger('process', null, data);
|
||||
$.each(data.processQueue, function (i, settings) {
|
||||
var func = function (data) {
|
||||
if (originalData.errorThrown) {
|
||||
// eslint-disable-next-line new-cap
|
||||
return $.Deferred().rejectWith(that, [originalData]).promise();
|
||||
}
|
||||
return that.processActions[settings.action].call(
|
||||
that,
|
||||
data,
|
||||
settings
|
||||
);
|
||||
};
|
||||
chain = chain.then(func, settings.always && func);
|
||||
});
|
||||
chain
|
||||
.done(function () {
|
||||
that._trigger('processdone', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
})
|
||||
.fail(function () {
|
||||
that._trigger('processfail', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
});
|
||||
return chain;
|
||||
},
|
||||
|
||||
// Replaces the settings of each processQueue item that
|
||||
// are strings starting with an "@", using the remaining
|
||||
// substring as key for the option map,
|
||||
// e.g. "@autoUpload" is replaced with options.autoUpload:
|
||||
_transformProcessQueue: function (options) {
|
||||
var processQueue = [];
|
||||
$.each(options.processQueue, function () {
|
||||
var settings = {},
|
||||
action = this.action,
|
||||
prefix = this.prefix === true ? action : this.prefix;
|
||||
$.each(this, function (key, value) {
|
||||
if ($.type(value) === 'string' && value.charAt(0) === '@') {
|
||||
settings[key] =
|
||||
options[
|
||||
value.slice(1) ||
|
||||
(prefix
|
||||
? prefix + key.charAt(0).toUpperCase() + key.slice(1)
|
||||
: key)
|
||||
];
|
||||
} else {
|
||||
settings[key] = value;
|
||||
}
|
||||
});
|
||||
processQueue.push(settings);
|
||||
});
|
||||
options.processQueue = processQueue;
|
||||
},
|
||||
|
||||
// Returns the number of files currently in the processsing queue:
|
||||
processing: function () {
|
||||
return this._processing;
|
||||
},
|
||||
|
||||
// Processes the files given as files property of the data parameter,
|
||||
// returns a Promise object that allows to bind callbacks:
|
||||
process: function (data) {
|
||||
var that = this,
|
||||
options = $.extend({}, this.options, data);
|
||||
if (options.processQueue && options.processQueue.length) {
|
||||
this._transformProcessQueue(options);
|
||||
if (this._processing === 0) {
|
||||
this._trigger('processstart');
|
||||
}
|
||||
$.each(data.files, function (index) {
|
||||
var opts = index ? $.extend({}, options) : options,
|
||||
func = function () {
|
||||
if (data.errorThrown) {
|
||||
// eslint-disable-next-line new-cap
|
||||
return $.Deferred().rejectWith(that, [data]).promise();
|
||||
}
|
||||
return that._processFile(opts, data);
|
||||
};
|
||||
opts.index = index;
|
||||
that._processing += 1;
|
||||
that._processingQueue = that._processingQueue
|
||||
.then(func, func)
|
||||
.always(function () {
|
||||
that._processing -= 1;
|
||||
if (that._processing === 0) {
|
||||
that._trigger('processstop');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return this._processingQueue;
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._processing = 0;
|
||||
// eslint-disable-next-line new-cap
|
||||
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
||||
}
|
||||
});
|
||||
});
|
||||
759
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-ui.js
vendored
Normal file
759
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-ui.js
vendored
Normal file
|
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
* jQuery File Upload User Interface Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'blueimp-tmpl',
|
||||
'./jquery.fileupload-image',
|
||||
'./jquery.fileupload-audio',
|
||||
'./jquery.fileupload-video',
|
||||
'./jquery.fileupload-validate'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('blueimp-tmpl'),
|
||||
require('./jquery.fileupload-image'),
|
||||
require('./jquery.fileupload-audio'),
|
||||
require('./jquery.fileupload-video'),
|
||||
require('./jquery.fileupload-validate')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery, window.tmpl);
|
||||
}
|
||||
})(function ($, tmpl) {
|
||||
'use strict';
|
||||
|
||||
$.blueimp.fileupload.prototype._specialOptions.push(
|
||||
'filesContainer',
|
||||
'uploadTemplateId',
|
||||
'downloadTemplateId'
|
||||
);
|
||||
|
||||
// The UI version extends the file upload widget
|
||||
// and adds complete user interface interaction:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
// By default, files added to the widget are uploaded as soon
|
||||
// as the user clicks on the start buttons. To enable automatic
|
||||
// uploads, set the following option to true:
|
||||
autoUpload: false,
|
||||
// The class to show/hide UI elements:
|
||||
showElementClass: 'in',
|
||||
// The ID of the upload template:
|
||||
uploadTemplateId: 'template-upload',
|
||||
// The ID of the download template:
|
||||
downloadTemplateId: 'template-download',
|
||||
// The container for the list of files. If undefined, it is set to
|
||||
// an element with class "files" inside of the widget element:
|
||||
filesContainer: undefined,
|
||||
// By default, files are appended to the files container.
|
||||
// Set the following option to true, to prepend files instead:
|
||||
prependFiles: false,
|
||||
// The expected data type of the upload response, sets the dataType
|
||||
// option of the $.ajax upload requests:
|
||||
dataType: 'json',
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
unknownError: 'Unknown error'
|
||||
},
|
||||
|
||||
// Function returning the current number of files,
|
||||
// used by the maxNumberOfFiles validation:
|
||||
getNumberOfFiles: function () {
|
||||
return this.filesContainer.children().not('.processing').length;
|
||||
},
|
||||
|
||||
// Callback to retrieve the list of files from the server response:
|
||||
getFilesFromResponse: function (data) {
|
||||
if (data.result && $.isArray(data.result.files)) {
|
||||
return data.result.files;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
// The add callback is invoked as soon as files are added to the fileupload
|
||||
// widget (via file input selection, drag & drop or add API call).
|
||||
// See the basic file upload widget for more information:
|
||||
add: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
that = $this.data('blueimp-fileupload') || $this.data('fileupload'),
|
||||
options = that.options;
|
||||
data.context = that
|
||||
._renderUpload(data.files)
|
||||
.data('data', data)
|
||||
.addClass('processing');
|
||||
options.filesContainer[options.prependFiles ? 'prepend' : 'append'](
|
||||
data.context
|
||||
);
|
||||
that._forceReflow(data.context);
|
||||
that._transition(data.context);
|
||||
data
|
||||
.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
})
|
||||
.always(function () {
|
||||
data.context
|
||||
.each(function (index) {
|
||||
$(this)
|
||||
.find('.size')
|
||||
.text(that._formatFileSize(data.files[index].size));
|
||||
})
|
||||
.removeClass('processing');
|
||||
that._renderPreviews(data);
|
||||
})
|
||||
.done(function () {
|
||||
data.context.find('.edit,.start').prop('disabled', false);
|
||||
if (
|
||||
that._trigger('added', e, data) !== false &&
|
||||
(options.autoUpload || data.autoUpload) &&
|
||||
data.autoUpload !== false
|
||||
) {
|
||||
data.submit();
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
if (data.files.error) {
|
||||
data.context.each(function (index) {
|
||||
var error = data.files[index].error;
|
||||
if (error) {
|
||||
$(this).find('.error').text(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// Callback for the start of each file upload request:
|
||||
send: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload');
|
||||
if (
|
||||
data.context &&
|
||||
data.dataType &&
|
||||
data.dataType.substr(0, 6) === 'iframe'
|
||||
) {
|
||||
// Iframe Transport does not support progress events.
|
||||
// In lack of an indeterminate progress bar, we set
|
||||
// the progress to 100%, showing the full animated bar:
|
||||
data.context
|
||||
.find('.progress')
|
||||
.addClass(!$.support.transition && 'progress-animated')
|
||||
.attr('aria-valuenow', 100)
|
||||
.children()
|
||||
.first()
|
||||
.css('width', '100%');
|
||||
}
|
||||
return that._trigger('sent', e, data);
|
||||
},
|
||||
// Callback for successful uploads:
|
||||
done: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
getFilesFromResponse =
|
||||
data.getFilesFromResponse || that.options.getFilesFromResponse,
|
||||
files = getFilesFromResponse(data),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
var file = files[index] || { error: 'Empty file upload result' };
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file]).replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
template = that
|
||||
._renderDownload(files)
|
||||
[that.options.prependFiles ? 'prependTo' : 'appendTo'](
|
||||
that.options.filesContainer
|
||||
);
|
||||
that._forceReflow(template);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(template).done(function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
},
|
||||
// Callback for failed (abort or error) uploads:
|
||||
fail: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
if (data.errorThrown !== 'abort') {
|
||||
var file = data.files[index];
|
||||
file.error =
|
||||
file.error || data.errorThrown || data.i18n('unknownError');
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file]).replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(function () {
|
||||
$(this).remove();
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (data.errorThrown !== 'abort') {
|
||||
data.context = that
|
||||
._renderUpload(data.files)
|
||||
[that.options.prependFiles ? 'prependTo' : 'appendTo'](
|
||||
that.options.filesContainer
|
||||
)
|
||||
.data('data', data);
|
||||
that._forceReflow(data.context);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(data.context).done(function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
that._addFinishedDeferreds().resolve();
|
||||
}
|
||||
},
|
||||
// Callback for upload progress events:
|
||||
progress: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var progress = Math.floor((data.loaded / data.total) * 100);
|
||||
if (data.context) {
|
||||
data.context.each(function () {
|
||||
$(this)
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children()
|
||||
.first()
|
||||
.css('width', progress + '%');
|
||||
});
|
||||
}
|
||||
},
|
||||
// Callback for global upload progress events:
|
||||
progressall: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
progress = Math.floor((data.loaded / data.total) * 100),
|
||||
globalProgressNode = $this.find('.fileupload-progress'),
|
||||
extendedProgressNode = globalProgressNode.find('.progress-extended');
|
||||
if (extendedProgressNode.length) {
|
||||
extendedProgressNode.html(
|
||||
(
|
||||
$this.data('blueimp-fileupload') || $this.data('fileupload')
|
||||
)._renderExtendedProgress(data)
|
||||
);
|
||||
}
|
||||
globalProgressNode
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children()
|
||||
.first()
|
||||
.css('width', progress + '%');
|
||||
},
|
||||
// Callback for uploads start, equivalent to the global ajaxStart event:
|
||||
start: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload');
|
||||
that._resetFinishedDeferreds();
|
||||
that
|
||||
._transition($(this).find('.fileupload-progress'))
|
||||
.done(function () {
|
||||
that._trigger('started', e);
|
||||
});
|
||||
},
|
||||
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
||||
stop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
deferred = that._addFinishedDeferreds();
|
||||
$.when.apply($, that._getFinishedDeferreds()).done(function () {
|
||||
that._trigger('stopped', e);
|
||||
});
|
||||
that
|
||||
._transition($(this).find('.fileupload-progress'))
|
||||
.done(function () {
|
||||
$(this)
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', '0')
|
||||
.children()
|
||||
.first()
|
||||
.css('width', '0%');
|
||||
$(this).find('.progress-extended').html(' ');
|
||||
deferred.resolve();
|
||||
});
|
||||
},
|
||||
processstart: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).addClass('fileupload-processing');
|
||||
},
|
||||
processstop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).removeClass('fileupload-processing');
|
||||
},
|
||||
// Callback for file deletion:
|
||||
destroy: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
removeNode = function () {
|
||||
that._transition(data.context).done(function () {
|
||||
$(this).remove();
|
||||
that._trigger('destroyed', e, data);
|
||||
});
|
||||
};
|
||||
if (data.url) {
|
||||
data.dataType = data.dataType || that.options.dataType;
|
||||
$.ajax(data)
|
||||
.done(removeNode)
|
||||
.fail(function () {
|
||||
that._trigger('destroyfailed', e, data);
|
||||
});
|
||||
} else {
|
||||
removeNode();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_resetFinishedDeferreds: function () {
|
||||
this._finishedUploads = [];
|
||||
},
|
||||
|
||||
_addFinishedDeferreds: function (deferred) {
|
||||
// eslint-disable-next-line new-cap
|
||||
var promise = deferred || $.Deferred();
|
||||
this._finishedUploads.push(promise);
|
||||
return promise;
|
||||
},
|
||||
|
||||
_getFinishedDeferreds: function () {
|
||||
return this._finishedUploads;
|
||||
},
|
||||
|
||||
// Link handler, that allows to download files
|
||||
// by drag & drop of the links to the desktop:
|
||||
_enableDragToDesktop: function () {
|
||||
var link = $(this),
|
||||
url = link.prop('href'),
|
||||
name = link.prop('download'),
|
||||
type = 'application/octet-stream';
|
||||
link.on('dragstart', function (e) {
|
||||
try {
|
||||
e.originalEvent.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
[type, name, url].join(':')
|
||||
);
|
||||
} catch (ignore) {
|
||||
// Ignore exceptions
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_formatFileSize: function (bytes) {
|
||||
if (typeof bytes !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bytes >= 1000000000) {
|
||||
return (bytes / 1000000000).toFixed(2) + ' GB';
|
||||
}
|
||||
if (bytes >= 1000000) {
|
||||
return (bytes / 1000000).toFixed(2) + ' MB';
|
||||
}
|
||||
return (bytes / 1000).toFixed(2) + ' KB';
|
||||
},
|
||||
|
||||
_formatBitrate: function (bits) {
|
||||
if (typeof bits !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bits >= 1000000000) {
|
||||
return (bits / 1000000000).toFixed(2) + ' Gbit/s';
|
||||
}
|
||||
if (bits >= 1000000) {
|
||||
return (bits / 1000000).toFixed(2) + ' Mbit/s';
|
||||
}
|
||||
if (bits >= 1000) {
|
||||
return (bits / 1000).toFixed(2) + ' kbit/s';
|
||||
}
|
||||
return bits.toFixed(2) + ' bit/s';
|
||||
},
|
||||
|
||||
_formatTime: function (seconds) {
|
||||
var date = new Date(seconds * 1000),
|
||||
days = Math.floor(seconds / 86400);
|
||||
days = days ? days + 'd ' : '';
|
||||
return (
|
||||
days +
|
||||
('0' + date.getUTCHours()).slice(-2) +
|
||||
':' +
|
||||
('0' + date.getUTCMinutes()).slice(-2) +
|
||||
':' +
|
||||
('0' + date.getUTCSeconds()).slice(-2)
|
||||
);
|
||||
},
|
||||
|
||||
_formatPercentage: function (floatValue) {
|
||||
return (floatValue * 100).toFixed(2) + ' %';
|
||||
},
|
||||
|
||||
_renderExtendedProgress: function (data) {
|
||||
return (
|
||||
this._formatBitrate(data.bitrate) +
|
||||
' | ' +
|
||||
this._formatTime(((data.total - data.loaded) * 8) / data.bitrate) +
|
||||
' | ' +
|
||||
this._formatPercentage(data.loaded / data.total) +
|
||||
' | ' +
|
||||
this._formatFileSize(data.loaded) +
|
||||
' / ' +
|
||||
this._formatFileSize(data.total)
|
||||
);
|
||||
},
|
||||
|
||||
_renderTemplate: function (func, files) {
|
||||
if (!func) {
|
||||
return $();
|
||||
}
|
||||
var result = func({
|
||||
files: files,
|
||||
formatFileSize: this._formatFileSize,
|
||||
options: this.options
|
||||
});
|
||||
if (result instanceof $) {
|
||||
return result;
|
||||
}
|
||||
return $(this.options.templatesContainer).html(result).children();
|
||||
},
|
||||
|
||||
_renderPreviews: function (data) {
|
||||
data.context.find('.preview').each(function (index, elm) {
|
||||
$(elm).empty().append(data.files[index].preview);
|
||||
});
|
||||
},
|
||||
|
||||
_renderUpload: function (files) {
|
||||
return this._renderTemplate(this.options.uploadTemplate, files);
|
||||
},
|
||||
|
||||
_renderDownload: function (files) {
|
||||
return this._renderTemplate(this.options.downloadTemplate, files)
|
||||
.find('a[download]')
|
||||
.each(this._enableDragToDesktop)
|
||||
.end();
|
||||
},
|
||||
|
||||
_editHandler: function (e) {
|
||||
e.preventDefault();
|
||||
if (!this.options.edit) return;
|
||||
var that = this,
|
||||
button = $(e.currentTarget),
|
||||
template = button.closest('.template-upload'),
|
||||
data = template.data('data'),
|
||||
index = button.data().index;
|
||||
this.options.edit(data.files[index]).then(function (file) {
|
||||
if (!file) return;
|
||||
data.files[index] = file;
|
||||
data.context.addClass('processing');
|
||||
template.find('.edit,.start').prop('disabled', true);
|
||||
$(that.element)
|
||||
.fileupload('process', data)
|
||||
.always(function () {
|
||||
template
|
||||
.find('.size')
|
||||
.text(that._formatFileSize(data.files[index].size));
|
||||
data.context.removeClass('processing');
|
||||
that._renderPreviews(data);
|
||||
})
|
||||
.done(function () {
|
||||
template.find('.edit,.start').prop('disabled', false);
|
||||
})
|
||||
.fail(function () {
|
||||
template.find('.edit').prop('disabled', false);
|
||||
var error = data.files[index].error;
|
||||
if (error) {
|
||||
template.find('.error').text(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_startHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget),
|
||||
template = button.closest('.template-upload'),
|
||||
data = template.data('data');
|
||||
button.prop('disabled', true);
|
||||
if (data && data.submit) {
|
||||
data.submit();
|
||||
}
|
||||
},
|
||||
|
||||
_cancelHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var template = $(e.currentTarget).closest(
|
||||
'.template-upload,.template-download'
|
||||
),
|
||||
data = template.data('data') || {};
|
||||
data.context = data.context || template;
|
||||
if (data.abort) {
|
||||
data.abort();
|
||||
} else {
|
||||
data.errorThrown = 'abort';
|
||||
this._trigger('fail', e, data);
|
||||
}
|
||||
},
|
||||
|
||||
_deleteHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget);
|
||||
this._trigger(
|
||||
'destroy',
|
||||
e,
|
||||
$.extend(
|
||||
{
|
||||
context: button.closest('.template-download'),
|
||||
type: 'DELETE'
|
||||
},
|
||||
button.data()
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
_forceReflow: function (node) {
|
||||
return $.support.transition && node.length && node[0].offsetWidth;
|
||||
},
|
||||
|
||||
_transition: function (node) {
|
||||
// eslint-disable-next-line new-cap
|
||||
var dfd = $.Deferred();
|
||||
if (
|
||||
$.support.transition &&
|
||||
node.hasClass('fade') &&
|
||||
node.is(':visible')
|
||||
) {
|
||||
var transitionEndHandler = function (e) {
|
||||
// Make sure we don't respond to other transition events
|
||||
// in the container element, e.g. from button elements:
|
||||
if (e.target === node[0]) {
|
||||
node.off($.support.transition.end, transitionEndHandler);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
};
|
||||
node
|
||||
.on($.support.transition.end, transitionEndHandler)
|
||||
.toggleClass(this.options.showElementClass);
|
||||
} else {
|
||||
node.toggleClass(this.options.showElementClass);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
return dfd;
|
||||
},
|
||||
|
||||
_initButtonBarEventHandlers: function () {
|
||||
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
|
||||
filesList = this.options.filesContainer;
|
||||
this._on(fileUploadButtonBar.find('.start'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.start').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.cancel'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.cancel').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.delete'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList
|
||||
.find('.toggle:checked')
|
||||
.closest('.template-download')
|
||||
.find('.delete')
|
||||
.click();
|
||||
fileUploadButtonBar.find('.toggle').prop('checked', false);
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.toggle'), {
|
||||
change: function (e) {
|
||||
filesList
|
||||
.find('.toggle')
|
||||
.prop('checked', $(e.currentTarget).is(':checked'));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_destroyButtonBarEventHandlers: function () {
|
||||
this._off(
|
||||
this.element
|
||||
.find('.fileupload-buttonbar')
|
||||
.find('.start, .cancel, .delete'),
|
||||
'click'
|
||||
);
|
||||
this._off(this.element.find('.fileupload-buttonbar .toggle'), 'change.');
|
||||
},
|
||||
|
||||
_initEventHandlers: function () {
|
||||
this._super();
|
||||
this._on(this.options.filesContainer, {
|
||||
'click .edit': this._editHandler,
|
||||
'click .start': this._startHandler,
|
||||
'click .cancel': this._cancelHandler,
|
||||
'click .delete': this._deleteHandler
|
||||
});
|
||||
this._initButtonBarEventHandlers();
|
||||
},
|
||||
|
||||
_destroyEventHandlers: function () {
|
||||
this._destroyButtonBarEventHandlers();
|
||||
this._off(this.options.filesContainer, 'click');
|
||||
this._super();
|
||||
},
|
||||
|
||||
_enableFileInputButton: function () {
|
||||
this.element
|
||||
.find('.fileinput-button input')
|
||||
.prop('disabled', false)
|
||||
.parent()
|
||||
.removeClass('disabled');
|
||||
},
|
||||
|
||||
_disableFileInputButton: function () {
|
||||
this.element
|
||||
.find('.fileinput-button input')
|
||||
.prop('disabled', true)
|
||||
.parent()
|
||||
.addClass('disabled');
|
||||
},
|
||||
|
||||
_initTemplates: function () {
|
||||
var options = this.options;
|
||||
options.templatesContainer = this.document[0].createElement(
|
||||
options.filesContainer.prop('nodeName')
|
||||
);
|
||||
if (tmpl) {
|
||||
if (options.uploadTemplateId) {
|
||||
options.uploadTemplate = tmpl(options.uploadTemplateId);
|
||||
}
|
||||
if (options.downloadTemplateId) {
|
||||
options.downloadTemplate = tmpl(options.downloadTemplateId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_initFilesContainer: function () {
|
||||
var options = this.options;
|
||||
if (options.filesContainer === undefined) {
|
||||
options.filesContainer = this.element.find('.files');
|
||||
} else if (!(options.filesContainer instanceof $)) {
|
||||
options.filesContainer = $(options.filesContainer);
|
||||
}
|
||||
},
|
||||
|
||||
_initSpecialOptions: function () {
|
||||
this._super();
|
||||
this._initFilesContainer();
|
||||
this._initTemplates();
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._resetFinishedDeferreds();
|
||||
if (!$.support.fileInput) {
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
var wasDisabled = false;
|
||||
if (this.options.disabled) {
|
||||
wasDisabled = true;
|
||||
}
|
||||
this._super();
|
||||
if (wasDisabled) {
|
||||
this.element.find('input, button').prop('disabled', false);
|
||||
this._enableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
if (!this.options.disabled) {
|
||||
this.element.find('input, button').prop('disabled', true);
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
});
|
||||
119
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-validate.js
vendored
Normal file
119
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-validate.js
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* jQuery File Upload Validation Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'), require('./jquery.fileupload-process'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Append to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.push({
|
||||
action: 'validate',
|
||||
// Always trigger this action,
|
||||
// even if the previous action was rejected:
|
||||
always: true,
|
||||
// Options taken from the global options map:
|
||||
acceptFileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
minFileSize: '@',
|
||||
maxNumberOfFiles: '@',
|
||||
disabled: '@disableValidation'
|
||||
});
|
||||
|
||||
// The File Upload Validation plugin extends the fileupload widget
|
||||
// with file validation functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
/*
|
||||
// The regular expression for allowed file types, matches
|
||||
// against either file type or file name:
|
||||
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
|
||||
// The maximum allowed file size in bytes:
|
||||
maxFileSize: 10000000, // 10 MB
|
||||
// The minimum allowed file size in bytes:
|
||||
minFileSize: undefined, // No minimal file size
|
||||
// The limit of files to be uploaded:
|
||||
maxNumberOfFiles: 10,
|
||||
*/
|
||||
|
||||
// Function returning the current number of files,
|
||||
// has to be overriden for maxNumberOfFiles validation:
|
||||
getNumberOfFiles: $.noop,
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
maxNumberOfFiles: 'Maximum number of files exceeded',
|
||||
acceptFileTypes: 'File type not allowed',
|
||||
maxFileSize: 'File is too large',
|
||||
minFileSize: 'File is too small'
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
validate: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
// eslint-disable-next-line new-cap
|
||||
var dfd = $.Deferred(),
|
||||
settings = this.options,
|
||||
file = data.files[data.index],
|
||||
fileSize;
|
||||
if (options.minFileSize || options.maxFileSize) {
|
||||
fileSize = file.size;
|
||||
}
|
||||
if (
|
||||
$.type(options.maxNumberOfFiles) === 'number' &&
|
||||
(settings.getNumberOfFiles() || 0) + data.files.length >
|
||||
options.maxNumberOfFiles
|
||||
) {
|
||||
file.error = settings.i18n('maxNumberOfFiles');
|
||||
} else if (
|
||||
options.acceptFileTypes &&
|
||||
!(
|
||||
options.acceptFileTypes.test(file.type) ||
|
||||
options.acceptFileTypes.test(file.name)
|
||||
)
|
||||
) {
|
||||
file.error = settings.i18n('acceptFileTypes');
|
||||
} else if (fileSize > options.maxFileSize) {
|
||||
file.error = settings.i18n('maxFileSize');
|
||||
} else if (
|
||||
$.type(fileSize) === 'number' &&
|
||||
fileSize < options.minFileSize
|
||||
) {
|
||||
file.error = settings.i18n('minFileSize');
|
||||
} else {
|
||||
delete file.error;
|
||||
}
|
||||
if (file.error || data.files.error) {
|
||||
data.files.error = true;
|
||||
dfd.rejectWith(this, [data]);
|
||||
} else {
|
||||
dfd.resolveWith(this, [data]);
|
||||
}
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
101
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-video.js
vendored
Normal file
101
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.fileupload-video.js
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* jQuery File Upload Video Preview Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery', 'load-image', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('blueimp-load-image/js/load-image'),
|
||||
require('./jquery.fileupload-process')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadVideo',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
disabled: '@disableVideoPreview'
|
||||
},
|
||||
{
|
||||
action: 'setVideo',
|
||||
name: '@videoPreviewName',
|
||||
disabled: '@disableVideoPreview'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Video Preview plugin extends the fileupload widget
|
||||
// with video preview functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
options: {
|
||||
// The regular expression for the types of video files to load,
|
||||
// matched against the file type:
|
||||
loadVideoFileTypes: /^video\/.*$/
|
||||
},
|
||||
|
||||
_videoElement: document.createElement('video'),
|
||||
|
||||
processActions: {
|
||||
// Loads the video file given via data.files and data.index
|
||||
// as video element if the browser supports playing it.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadVideo: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
video;
|
||||
if (
|
||||
this._videoElement.canPlayType &&
|
||||
this._videoElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes || options.fileTypes.test(file.type))
|
||||
) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
video = this._videoElement.cloneNode(false);
|
||||
video.src = url;
|
||||
video.controls = true;
|
||||
data.video = video;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the video element as a property of the file object:
|
||||
setVideo: function (data, options) {
|
||||
if (data.video && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.video;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
221
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.iframe-transport.js
vendored
Normal file
221
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/jquery.iframe-transport.js
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* jQuery Iframe Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Helper variable to create unique names for the transport iframes:
|
||||
var counter = 0,
|
||||
jsonAPI = $,
|
||||
jsonParse = 'parseJSON';
|
||||
|
||||
if ('JSON' in window && 'parse' in JSON) {
|
||||
jsonAPI = JSON;
|
||||
jsonParse = 'parse';
|
||||
}
|
||||
|
||||
// The iframe transport accepts four additional options:
|
||||
// options.fileInput: a jQuery collection of file input fields
|
||||
// options.paramName: the parameter name for the file form data,
|
||||
// overrides the name property of the file input field(s),
|
||||
// can be a string or an array of strings.
|
||||
// options.formData: an array of objects with name and value properties,
|
||||
// equivalent to the return data of .serializeArray(), e.g.:
|
||||
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
|
||||
// options.initialIframeSrc: the URL of the initial iframe src,
|
||||
// by default set to "javascript:false;"
|
||||
$.ajaxTransport('iframe', function (options) {
|
||||
if (options.async) {
|
||||
// javascript:false as initial iframe src
|
||||
// prevents warning popups on HTTPS in IE6:
|
||||
// eslint-disable-next-line no-script-url
|
||||
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
|
||||
form,
|
||||
iframe,
|
||||
addParamChar;
|
||||
return {
|
||||
send: function (_, completeCallback) {
|
||||
form = $('<form style="display:none;"></form>');
|
||||
form.attr('accept-charset', options.formAcceptCharset);
|
||||
addParamChar = /\?/.test(options.url) ? '&' : '?';
|
||||
// XDomainRequest only supports GET and POST:
|
||||
if (options.type === 'DELETE') {
|
||||
options.url = options.url + addParamChar + '_method=DELETE';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PUT') {
|
||||
options.url = options.url + addParamChar + '_method=PUT';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PATCH') {
|
||||
options.url = options.url + addParamChar + '_method=PATCH';
|
||||
options.type = 'POST';
|
||||
}
|
||||
// IE versions below IE8 cannot set the name property of
|
||||
// elements that have already been added to the DOM,
|
||||
// so we set the name along with the iframe HTML markup:
|
||||
counter += 1;
|
||||
iframe = $(
|
||||
'<iframe src="' +
|
||||
initialIframeSrc +
|
||||
'" name="iframe-transport-' +
|
||||
counter +
|
||||
'"></iframe>'
|
||||
).on('load', function () {
|
||||
var fileInputClones,
|
||||
paramNames = $.isArray(options.paramName)
|
||||
? options.paramName
|
||||
: [options.paramName];
|
||||
iframe.off('load').on('load', function () {
|
||||
var response;
|
||||
// Wrap in a try/catch block to catch exceptions thrown
|
||||
// when trying to access cross-domain iframe contents:
|
||||
try {
|
||||
response = iframe.contents();
|
||||
// Google Chrome and Firefox do not throw an
|
||||
// exception when calling iframe.contents() on
|
||||
// cross-domain requests, so we unify the response:
|
||||
if (!response.length || !response[0].firstChild) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
response = undefined;
|
||||
}
|
||||
// The complete callback returns the
|
||||
// iframe content document as response object:
|
||||
completeCallback(200, 'success', { iframe: response });
|
||||
// Fix for IE endless progress bar activity bug
|
||||
// (happens on form submits to iframe targets):
|
||||
$('<iframe src="' + initialIframeSrc + '"></iframe>').appendTo(
|
||||
form
|
||||
);
|
||||
window.setTimeout(function () {
|
||||
// Removing the form in a setTimeout call
|
||||
// allows Chrome's developer tools to display
|
||||
// the response result
|
||||
form.remove();
|
||||
}, 0);
|
||||
});
|
||||
form
|
||||
.prop('target', iframe.prop('name'))
|
||||
.prop('action', options.url)
|
||||
.prop('method', options.type);
|
||||
if (options.formData) {
|
||||
$.each(options.formData, function (index, field) {
|
||||
$('<input type="hidden"/>')
|
||||
.prop('name', field.name)
|
||||
.val(field.value)
|
||||
.appendTo(form);
|
||||
});
|
||||
}
|
||||
if (
|
||||
options.fileInput &&
|
||||
options.fileInput.length &&
|
||||
options.type === 'POST'
|
||||
) {
|
||||
fileInputClones = options.fileInput.clone();
|
||||
// Insert a clone for each file input field:
|
||||
options.fileInput.after(function (index) {
|
||||
return fileInputClones[index];
|
||||
});
|
||||
if (options.paramName) {
|
||||
options.fileInput.each(function (index) {
|
||||
$(this).prop('name', paramNames[index] || options.paramName);
|
||||
});
|
||||
}
|
||||
// Appending the file input fields to the hidden form
|
||||
// removes them from their original location:
|
||||
form
|
||||
.append(options.fileInput)
|
||||
.prop('enctype', 'multipart/form-data')
|
||||
// enctype must be set as encoding for IE:
|
||||
.prop('encoding', 'multipart/form-data');
|
||||
// Remove the HTML5 form attribute from the input(s):
|
||||
options.fileInput.removeAttr('form');
|
||||
}
|
||||
form.submit();
|
||||
// Insert the file input fields at their original location
|
||||
// by replacing the clones with the originals:
|
||||
if (fileInputClones && fileInputClones.length) {
|
||||
options.fileInput.each(function (index, input) {
|
||||
var clone = $(fileInputClones[index]);
|
||||
// Restore the original name and form properties:
|
||||
$(input)
|
||||
.prop('name', clone.prop('name'))
|
||||
.attr('form', clone.attr('form'));
|
||||
clone.replaceWith(input);
|
||||
});
|
||||
}
|
||||
});
|
||||
form.append(iframe).appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
// javascript:false as iframe src aborts the request
|
||||
// and prevents warning popups on HTTPS in IE6.
|
||||
iframe.off('load').prop('src', initialIframeSrc);
|
||||
}
|
||||
if (form) {
|
||||
form.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// The iframe transport returns the iframe content document as response.
|
||||
// The following adds converters from iframe to text, json, html, xml
|
||||
// and script.
|
||||
// Please note that the Content-Type for JSON responses has to be text/plain
|
||||
// or text/html, if the browser doesn't include application/json in the
|
||||
// Accept header, else IE will show a download dialog.
|
||||
// The Content-Type for XML responses on the other hand has to be always
|
||||
// application/xml or text/xml, so IE properly parses the XML response.
|
||||
// See also
|
||||
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'iframe text': function (iframe) {
|
||||
return iframe && $(iframe[0].body).text();
|
||||
},
|
||||
'iframe json': function (iframe) {
|
||||
return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
|
||||
},
|
||||
'iframe html': function (iframe) {
|
||||
return iframe && $(iframe[0].body).html();
|
||||
},
|
||||
'iframe xml': function (iframe) {
|
||||
var xmlDoc = iframe && iframe[0];
|
||||
return xmlDoc && $.isXMLDoc(xmlDoc)
|
||||
? xmlDoc
|
||||
: $.parseXML(
|
||||
(xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
|
||||
$(xmlDoc.body).html()
|
||||
);
|
||||
},
|
||||
'iframe script': function (iframe) {
|
||||
return iframe && $.globalEval($(iframe[0].body).text());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
808
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/vendor/jquery.ui.widget.js
vendored
Normal file
808
wwwroot/BackEnd/assets/vendor/blueimp-file-upload/js/vendor/jquery.ui.widget.js
vendored
Normal file
|
|
@ -0,0 +1,808 @@
|
|||
/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20
|
||||
* http://jqueryui.com
|
||||
* Includes: widget.js
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
/* global define, require */
|
||||
/* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(window.jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
('use strict');
|
||||
|
||||
$.ui = $.ui || {};
|
||||
|
||||
$.ui.version = '1.12.1';
|
||||
|
||||
/*!
|
||||
* jQuery UI Widget 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
//>>label: Widget
|
||||
//>>group: Core
|
||||
//>>description: Provides a factory for creating stateful widgets with a common API.
|
||||
//>>docs: http://api.jqueryui.com/jQuery.widget/
|
||||
//>>demos: http://jqueryui.com/widget/
|
||||
|
||||
// Support: jQuery 1.9.x or older
|
||||
// $.expr[ ":" ] is deprecated.
|
||||
if (!$.expr.pseudos) {
|
||||
$.expr.pseudos = $.expr[':'];
|
||||
}
|
||||
|
||||
// Support: jQuery 1.11.x or older
|
||||
// $.unique has been renamed to $.uniqueSort
|
||||
if (!$.uniqueSort) {
|
||||
$.uniqueSort = $.unique;
|
||||
}
|
||||
|
||||
var widgetUuid = 0;
|
||||
var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
|
||||
var widgetSlice = Array.prototype.slice;
|
||||
|
||||
$.cleanData = (function (orig) {
|
||||
return function (elems) {
|
||||
var events, elem, i;
|
||||
// eslint-disable-next-line eqeqeq
|
||||
for (i = 0; (elem = elems[i]) != null; i++) {
|
||||
// Only trigger remove when necessary to save time
|
||||
events = $._data(elem, 'events');
|
||||
if (events && events.remove) {
|
||||
$(elem).triggerHandler('remove');
|
||||
}
|
||||
}
|
||||
orig(elems);
|
||||
};
|
||||
})($.cleanData);
|
||||
|
||||
$.widget = function (name, base, prototype) {
|
||||
var existingConstructor, constructor, basePrototype;
|
||||
|
||||
// ProxiedPrototype allows the provided prototype to remain unmodified
|
||||
// so that it can be used as a mixin for multiple widgets (#8876)
|
||||
var proxiedPrototype = {};
|
||||
|
||||
var namespace = name.split('.')[0];
|
||||
name = name.split('.')[1];
|
||||
var fullName = namespace + '-' + name;
|
||||
|
||||
if (!prototype) {
|
||||
prototype = base;
|
||||
base = $.Widget;
|
||||
}
|
||||
|
||||
if ($.isArray(prototype)) {
|
||||
prototype = $.extend.apply(null, [{}].concat(prototype));
|
||||
}
|
||||
|
||||
// Create selector for plugin
|
||||
$.expr.pseudos[fullName.toLowerCase()] = function (elem) {
|
||||
return !!$.data(elem, fullName);
|
||||
};
|
||||
|
||||
$[namespace] = $[namespace] || {};
|
||||
existingConstructor = $[namespace][name];
|
||||
constructor = $[namespace][name] = function (options, element) {
|
||||
// Allow instantiation without "new" keyword
|
||||
if (!this._createWidget) {
|
||||
return new constructor(options, element);
|
||||
}
|
||||
|
||||
// Allow instantiation without initializing for simple inheritance
|
||||
// must use "new" keyword (the code above always passes args)
|
||||
if (arguments.length) {
|
||||
this._createWidget(options, element);
|
||||
}
|
||||
};
|
||||
|
||||
// Extend with the existing constructor to carry over any static properties
|
||||
$.extend(constructor, existingConstructor, {
|
||||
version: prototype.version,
|
||||
|
||||
// Copy the object used to create the prototype in case we need to
|
||||
// redefine the widget later
|
||||
_proto: $.extend({}, prototype),
|
||||
|
||||
// Track widgets that inherit from this widget in case this widget is
|
||||
// redefined after a widget inherits from it
|
||||
_childConstructors: []
|
||||
});
|
||||
|
||||
basePrototype = new base();
|
||||
|
||||
// We need to make the options hash a property directly on the new instance
|
||||
// otherwise we'll modify the options hash on the prototype that we're
|
||||
// inheriting from
|
||||
basePrototype.options = $.widget.extend({}, basePrototype.options);
|
||||
$.each(prototype, function (prop, value) {
|
||||
if (!$.isFunction(value)) {
|
||||
proxiedPrototype[prop] = value;
|
||||
return;
|
||||
}
|
||||
proxiedPrototype[prop] = (function () {
|
||||
function _super() {
|
||||
return base.prototype[prop].apply(this, arguments);
|
||||
}
|
||||
|
||||
function _superApply(args) {
|
||||
return base.prototype[prop].apply(this, args);
|
||||
}
|
||||
|
||||
return function () {
|
||||
var __super = this._super;
|
||||
var __superApply = this._superApply;
|
||||
var returnValue;
|
||||
|
||||
this._super = _super;
|
||||
this._superApply = _superApply;
|
||||
|
||||
returnValue = value.apply(this, arguments);
|
||||
|
||||
this._super = __super;
|
||||
this._superApply = __superApply;
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
})();
|
||||
});
|
||||
constructor.prototype = $.widget.extend(
|
||||
basePrototype,
|
||||
{
|
||||
// TODO: remove support for widgetEventPrefix
|
||||
// always use the name + a colon as the prefix, e.g., draggable:start
|
||||
// don't prefix for widgets that aren't DOM-based
|
||||
widgetEventPrefix: existingConstructor
|
||||
? basePrototype.widgetEventPrefix || name
|
||||
: name
|
||||
},
|
||||
proxiedPrototype,
|
||||
{
|
||||
constructor: constructor,
|
||||
namespace: namespace,
|
||||
widgetName: name,
|
||||
widgetFullName: fullName
|
||||
}
|
||||
);
|
||||
|
||||
// If this widget is being redefined then we need to find all widgets that
|
||||
// are inheriting from it and redefine all of them so that they inherit from
|
||||
// the new version of this widget. We're essentially trying to replace one
|
||||
// level in the prototype chain.
|
||||
if (existingConstructor) {
|
||||
$.each(existingConstructor._childConstructors, function (i, child) {
|
||||
var childPrototype = child.prototype;
|
||||
|
||||
// Redefine the child widget using the same prototype that was
|
||||
// originally used, but inherit from the new version of the base
|
||||
$.widget(
|
||||
childPrototype.namespace + '.' + childPrototype.widgetName,
|
||||
constructor,
|
||||
child._proto
|
||||
);
|
||||
});
|
||||
|
||||
// Remove the list of existing child constructors from the old constructor
|
||||
// so the old child constructors can be garbage collected
|
||||
delete existingConstructor._childConstructors;
|
||||
} else {
|
||||
base._childConstructors.push(constructor);
|
||||
}
|
||||
|
||||
$.widget.bridge(name, constructor);
|
||||
|
||||
return constructor;
|
||||
};
|
||||
|
||||
$.widget.extend = function (target) {
|
||||
var input = widgetSlice.call(arguments, 1);
|
||||
var inputIndex = 0;
|
||||
var inputLength = input.length;
|
||||
var key;
|
||||
var value;
|
||||
|
||||
for (; inputIndex < inputLength; inputIndex++) {
|
||||
for (key in input[inputIndex]) {
|
||||
value = input[inputIndex][key];
|
||||
if (
|
||||
widgetHasOwnProperty.call(input[inputIndex], key) &&
|
||||
value !== undefined
|
||||
) {
|
||||
// Clone objects
|
||||
if ($.isPlainObject(value)) {
|
||||
target[key] = $.isPlainObject(target[key])
|
||||
? $.widget.extend({}, target[key], value)
|
||||
: // Don't extend strings, arrays, etc. with objects
|
||||
$.widget.extend({}, value);
|
||||
|
||||
// Copy everything else by reference
|
||||
} else {
|
||||
target[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
$.widget.bridge = function (name, object) {
|
||||
var fullName = object.prototype.widgetFullName || name;
|
||||
$.fn[name] = function (options) {
|
||||
var isMethodCall = typeof options === 'string';
|
||||
var args = widgetSlice.call(arguments, 1);
|
||||
var returnValue = this;
|
||||
|
||||
if (isMethodCall) {
|
||||
// If this is an empty collection, we need to have the instance method
|
||||
// return undefined instead of the jQuery instance
|
||||
if (!this.length && options === 'instance') {
|
||||
returnValue = undefined;
|
||||
} else {
|
||||
this.each(function () {
|
||||
var methodValue;
|
||||
var instance = $.data(this, fullName);
|
||||
|
||||
if (options === 'instance') {
|
||||
returnValue = instance;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
return $.error(
|
||||
'cannot call methods on ' +
|
||||
name +
|
||||
' prior to initialization; ' +
|
||||
"attempted to call method '" +
|
||||
options +
|
||||
"'"
|
||||
);
|
||||
}
|
||||
|
||||
if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {
|
||||
return $.error(
|
||||
"no such method '" +
|
||||
options +
|
||||
"' for " +
|
||||
name +
|
||||
' widget instance'
|
||||
);
|
||||
}
|
||||
|
||||
methodValue = instance[options].apply(instance, args);
|
||||
|
||||
if (methodValue !== instance && methodValue !== undefined) {
|
||||
returnValue =
|
||||
methodValue && methodValue.jquery
|
||||
? returnValue.pushStack(methodValue.get())
|
||||
: methodValue;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Allow multiple hashes to be passed on init
|
||||
if (args.length) {
|
||||
options = $.widget.extend.apply(null, [options].concat(args));
|
||||
}
|
||||
|
||||
this.each(function () {
|
||||
var instance = $.data(this, fullName);
|
||||
if (instance) {
|
||||
instance.option(options || {});
|
||||
if (instance._init) {
|
||||
instance._init();
|
||||
}
|
||||
} else {
|
||||
$.data(this, fullName, new object(options, this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
};
|
||||
|
||||
$.Widget = function (/* options, element */) {};
|
||||
$.Widget._childConstructors = [];
|
||||
|
||||
$.Widget.prototype = {
|
||||
widgetName: 'widget',
|
||||
widgetEventPrefix: '',
|
||||
defaultElement: '<div>',
|
||||
|
||||
options: {
|
||||
classes: {},
|
||||
disabled: false,
|
||||
|
||||
// Callbacks
|
||||
create: null
|
||||
},
|
||||
|
||||
_createWidget: function (options, element) {
|
||||
element = $(element || this.defaultElement || this)[0];
|
||||
this.element = $(element);
|
||||
this.uuid = widgetUuid++;
|
||||
this.eventNamespace = '.' + this.widgetName + this.uuid;
|
||||
|
||||
this.bindings = $();
|
||||
this.hoverable = $();
|
||||
this.focusable = $();
|
||||
this.classesElementLookup = {};
|
||||
|
||||
if (element !== this) {
|
||||
$.data(element, this.widgetFullName, this);
|
||||
this._on(true, this.element, {
|
||||
remove: function (event) {
|
||||
if (event.target === element) {
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.document = $(
|
||||
element.style
|
||||
? // Element within the document
|
||||
element.ownerDocument
|
||||
: // Element is window or document
|
||||
element.document || element
|
||||
);
|
||||
this.window = $(
|
||||
this.document[0].defaultView || this.document[0].parentWindow
|
||||
);
|
||||
}
|
||||
|
||||
this.options = $.widget.extend(
|
||||
{},
|
||||
this.options,
|
||||
this._getCreateOptions(),
|
||||
options
|
||||
);
|
||||
|
||||
this._create();
|
||||
|
||||
if (this.options.disabled) {
|
||||
this._setOptionDisabled(this.options.disabled);
|
||||
}
|
||||
|
||||
this._trigger('create', null, this._getCreateEventData());
|
||||
this._init();
|
||||
},
|
||||
|
||||
_getCreateOptions: function () {
|
||||
return {};
|
||||
},
|
||||
|
||||
_getCreateEventData: $.noop,
|
||||
|
||||
_create: $.noop,
|
||||
|
||||
_init: $.noop,
|
||||
|
||||
destroy: function () {
|
||||
var that = this;
|
||||
|
||||
this._destroy();
|
||||
$.each(this.classesElementLookup, function (key, value) {
|
||||
that._removeClass(value, key);
|
||||
});
|
||||
|
||||
// We can probably remove the unbind calls in 2.0
|
||||
// all event bindings should go through this._on()
|
||||
this.element.off(this.eventNamespace).removeData(this.widgetFullName);
|
||||
this.widget().off(this.eventNamespace).removeAttr('aria-disabled');
|
||||
|
||||
// Clean up events and states
|
||||
this.bindings.off(this.eventNamespace);
|
||||
},
|
||||
|
||||
_destroy: $.noop,
|
||||
|
||||
widget: function () {
|
||||
return this.element;
|
||||
},
|
||||
|
||||
option: function (key, value) {
|
||||
var options = key;
|
||||
var parts;
|
||||
var curOption;
|
||||
var i;
|
||||
|
||||
if (arguments.length === 0) {
|
||||
// Don't return a reference to the internal hash
|
||||
return $.widget.extend({}, this.options);
|
||||
}
|
||||
|
||||
if (typeof key === 'string') {
|
||||
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
||||
options = {};
|
||||
parts = key.split('.');
|
||||
key = parts.shift();
|
||||
if (parts.length) {
|
||||
curOption = options[key] = $.widget.extend({}, this.options[key]);
|
||||
for (i = 0; i < parts.length - 1; i++) {
|
||||
curOption[parts[i]] = curOption[parts[i]] || {};
|
||||
curOption = curOption[parts[i]];
|
||||
}
|
||||
key = parts.pop();
|
||||
if (arguments.length === 1) {
|
||||
return curOption[key] === undefined ? null : curOption[key];
|
||||
}
|
||||
curOption[key] = value;
|
||||
} else {
|
||||
if (arguments.length === 1) {
|
||||
return this.options[key] === undefined ? null : this.options[key];
|
||||
}
|
||||
options[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
this._setOptions(options);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_setOptions: function (options) {
|
||||
var key;
|
||||
|
||||
for (key in options) {
|
||||
this._setOption(key, options[key]);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_setOption: function (key, value) {
|
||||
if (key === 'classes') {
|
||||
this._setOptionClasses(value);
|
||||
}
|
||||
|
||||
this.options[key] = value;
|
||||
|
||||
if (key === 'disabled') {
|
||||
this._setOptionDisabled(value);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_setOptionClasses: function (value) {
|
||||
var classKey, elements, currentElements;
|
||||
|
||||
for (classKey in value) {
|
||||
currentElements = this.classesElementLookup[classKey];
|
||||
if (
|
||||
value[classKey] === this.options.classes[classKey] ||
|
||||
!currentElements ||
|
||||
!currentElements.length
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We are doing this to create a new jQuery object because the _removeClass() call
|
||||
// on the next line is going to destroy the reference to the current elements being
|
||||
// tracked. We need to save a copy of this collection so that we can add the new classes
|
||||
// below.
|
||||
elements = $(currentElements.get());
|
||||
this._removeClass(currentElements, classKey);
|
||||
|
||||
// We don't use _addClass() here, because that uses this.options.classes
|
||||
// for generating the string of classes. We want to use the value passed in from
|
||||
// _setOption(), this is the new value of the classes option which was passed to
|
||||
// _setOption(). We pass this value directly to _classes().
|
||||
elements.addClass(
|
||||
this._classes({
|
||||
element: elements,
|
||||
keys: classKey,
|
||||
classes: value,
|
||||
add: true
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_setOptionDisabled: function (value) {
|
||||
this._toggleClass(
|
||||
this.widget(),
|
||||
this.widgetFullName + '-disabled',
|
||||
null,
|
||||
!!value
|
||||
);
|
||||
|
||||
// If the widget is becoming disabled, then nothing is interactive
|
||||
if (value) {
|
||||
this._removeClass(this.hoverable, null, 'ui-state-hover');
|
||||
this._removeClass(this.focusable, null, 'ui-state-focus');
|
||||
}
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
return this._setOptions({ disabled: false });
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
return this._setOptions({ disabled: true });
|
||||
},
|
||||
|
||||
_classes: function (options) {
|
||||
var full = [];
|
||||
var that = this;
|
||||
|
||||
options = $.extend(
|
||||
{
|
||||
element: this.element,
|
||||
classes: this.options.classes || {}
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
function bindRemoveEvent() {
|
||||
options.element.each(function (_, element) {
|
||||
var isTracked = $.map(that.classesElementLookup, function (elements) {
|
||||
return elements;
|
||||
}).some(function (elements) {
|
||||
return elements.is(element);
|
||||
});
|
||||
|
||||
if (!isTracked) {
|
||||
that._on($(element), {
|
||||
remove: '_untrackClassesElement'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function processClassString(classes, checkOption) {
|
||||
var current, i;
|
||||
for (i = 0; i < classes.length; i++) {
|
||||
current = that.classesElementLookup[classes[i]] || $();
|
||||
if (options.add) {
|
||||
bindRemoveEvent();
|
||||
current = $(
|
||||
$.uniqueSort(current.get().concat(options.element.get()))
|
||||
);
|
||||
} else {
|
||||
current = $(current.not(options.element).get());
|
||||
}
|
||||
that.classesElementLookup[classes[i]] = current;
|
||||
full.push(classes[i]);
|
||||
if (checkOption && options.classes[classes[i]]) {
|
||||
full.push(options.classes[classes[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.keys) {
|
||||
processClassString(options.keys.match(/\S+/g) || [], true);
|
||||
}
|
||||
if (options.extra) {
|
||||
processClassString(options.extra.match(/\S+/g) || []);
|
||||
}
|
||||
|
||||
return full.join(' ');
|
||||
},
|
||||
|
||||
_untrackClassesElement: function (event) {
|
||||
var that = this;
|
||||
$.each(that.classesElementLookup, function (key, value) {
|
||||
if ($.inArray(event.target, value) !== -1) {
|
||||
that.classesElementLookup[key] = $(value.not(event.target).get());
|
||||
}
|
||||
});
|
||||
|
||||
this._off($(event.target));
|
||||
},
|
||||
|
||||
_removeClass: function (element, keys, extra) {
|
||||
return this._toggleClass(element, keys, extra, false);
|
||||
},
|
||||
|
||||
_addClass: function (element, keys, extra) {
|
||||
return this._toggleClass(element, keys, extra, true);
|
||||
},
|
||||
|
||||
_toggleClass: function (element, keys, extra, add) {
|
||||
add = typeof add === 'boolean' ? add : extra;
|
||||
var shift = typeof element === 'string' || element === null,
|
||||
options = {
|
||||
extra: shift ? keys : extra,
|
||||
keys: shift ? element : keys,
|
||||
element: shift ? this.element : element,
|
||||
add: add
|
||||
};
|
||||
options.element.toggleClass(this._classes(options), add);
|
||||
return this;
|
||||
},
|
||||
|
||||
_on: function (suppressDisabledCheck, element, handlers) {
|
||||
var delegateElement;
|
||||
var instance = this;
|
||||
|
||||
// No suppressDisabledCheck flag, shuffle arguments
|
||||
if (typeof suppressDisabledCheck !== 'boolean') {
|
||||
handlers = element;
|
||||
element = suppressDisabledCheck;
|
||||
suppressDisabledCheck = false;
|
||||
}
|
||||
|
||||
// No element argument, shuffle and use this.element
|
||||
if (!handlers) {
|
||||
handlers = element;
|
||||
element = this.element;
|
||||
delegateElement = this.widget();
|
||||
} else {
|
||||
element = delegateElement = $(element);
|
||||
this.bindings = this.bindings.add(element);
|
||||
}
|
||||
|
||||
$.each(handlers, function (event, handler) {
|
||||
function handlerProxy() {
|
||||
// Allow widgets to customize the disabled handling
|
||||
// - disabled as an array instead of boolean
|
||||
// - disabled class as method for disabling individual parts
|
||||
if (
|
||||
!suppressDisabledCheck &&
|
||||
(instance.options.disabled === true ||
|
||||
$(this).hasClass('ui-state-disabled'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
return (typeof handler === 'string'
|
||||
? instance[handler]
|
||||
: handler
|
||||
).apply(instance, arguments);
|
||||
}
|
||||
|
||||
// Copy the guid so direct unbinding works
|
||||
if (typeof handler !== 'string') {
|
||||
handlerProxy.guid = handler.guid =
|
||||
handler.guid || handlerProxy.guid || $.guid++;
|
||||
}
|
||||
|
||||
var match = event.match(/^([\w:-]*)\s*(.*)$/);
|
||||
var eventName = match[1] + instance.eventNamespace;
|
||||
var selector = match[2];
|
||||
|
||||
if (selector) {
|
||||
delegateElement.on(eventName, selector, handlerProxy);
|
||||
} else {
|
||||
element.on(eventName, handlerProxy);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_off: function (element, eventName) {
|
||||
eventName =
|
||||
(eventName || '').split(' ').join(this.eventNamespace + ' ') +
|
||||
this.eventNamespace;
|
||||
element.off(eventName);
|
||||
|
||||
// Clear the stack to avoid memory leaks (#10056)
|
||||
this.bindings = $(this.bindings.not(element).get());
|
||||
this.focusable = $(this.focusable.not(element).get());
|
||||
this.hoverable = $(this.hoverable.not(element).get());
|
||||
},
|
||||
|
||||
_delay: function (handler, delay) {
|
||||
var instance = this;
|
||||
function handlerProxy() {
|
||||
return (typeof handler === 'string'
|
||||
? instance[handler]
|
||||
: handler
|
||||
).apply(instance, arguments);
|
||||
}
|
||||
return setTimeout(handlerProxy, delay || 0);
|
||||
},
|
||||
|
||||
_hoverable: function (element) {
|
||||
this.hoverable = this.hoverable.add(element);
|
||||
this._on(element, {
|
||||
mouseenter: function (event) {
|
||||
this._addClass($(event.currentTarget), null, 'ui-state-hover');
|
||||
},
|
||||
mouseleave: function (event) {
|
||||
this._removeClass($(event.currentTarget), null, 'ui-state-hover');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_focusable: function (element) {
|
||||
this.focusable = this.focusable.add(element);
|
||||
this._on(element, {
|
||||
focusin: function (event) {
|
||||
this._addClass($(event.currentTarget), null, 'ui-state-focus');
|
||||
},
|
||||
focusout: function (event) {
|
||||
this._removeClass($(event.currentTarget), null, 'ui-state-focus');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_trigger: function (type, event, data) {
|
||||
var prop, orig;
|
||||
var callback = this.options[type];
|
||||
|
||||
data = data || {};
|
||||
event = $.Event(event);
|
||||
event.type = (type === this.widgetEventPrefix
|
||||
? type
|
||||
: this.widgetEventPrefix + type
|
||||
).toLowerCase();
|
||||
|
||||
// The original event may come from any element
|
||||
// so we need to reset the target on the new event
|
||||
event.target = this.element[0];
|
||||
|
||||
// Copy original event properties over to the new event
|
||||
orig = event.originalEvent;
|
||||
if (orig) {
|
||||
for (prop in orig) {
|
||||
if (!(prop in event)) {
|
||||
event[prop] = orig[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.element.trigger(event, data);
|
||||
return !(
|
||||
($.isFunction(callback) &&
|
||||
callback.apply(this.element[0], [event].concat(data)) === false) ||
|
||||
event.isDefaultPrevented()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
$.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) {
|
||||
$.Widget.prototype['_' + method] = function (element, options, callback) {
|
||||
if (typeof options === 'string') {
|
||||
options = { effect: options };
|
||||
}
|
||||
|
||||
var hasOptions;
|
||||
var effectName = !options
|
||||
? method
|
||||
: options === true || typeof options === 'number'
|
||||
? defaultEffect
|
||||
: options.effect || defaultEffect;
|
||||
|
||||
options = options || {};
|
||||
if (typeof options === 'number') {
|
||||
options = { duration: options };
|
||||
}
|
||||
|
||||
hasOptions = !$.isEmptyObject(options);
|
||||
options.complete = callback;
|
||||
|
||||
if (options.delay) {
|
||||
element.delay(options.delay);
|
||||
}
|
||||
|
||||
if (hasOptions && $.effects && $.effects.effect[effectName]) {
|
||||
element[method](options);
|
||||
} else if (effectName !== method && element[effectName]) {
|
||||
element[effectName](options.duration, options.easing, callback);
|
||||
} else {
|
||||
element.queue(function (next) {
|
||||
$(this)[method]();
|
||||
if (callback) {
|
||||
callback.call(element[0]);
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
MIT License
|
||||
|
||||
Copyright © 2011 Sebastian Tschan, https://blueimp.net
|
||||
|
||||
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,12 @@
|
|||
/* global module, require */
|
||||
|
||||
module.exports = require('./load-image')
|
||||
|
||||
require('./load-image-scale')
|
||||
require('./load-image-meta')
|
||||
require('./load-image-fetch')
|
||||
require('./load-image-exif')
|
||||
require('./load-image-exif-map')
|
||||
require('./load-image-iptc')
|
||||
require('./load-image-iptc-map')
|
||||
require('./load-image-orientation')
|
||||
|
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* JavaScript Load Image Exif Map
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Exif tags mapping based on
|
||||
* https://github.com/jseidelin/exif-js
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-exif'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-exif'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.ExifMap.prototype.tags = {
|
||||
// =================
|
||||
// TIFF tags (IFD0):
|
||||
// =================
|
||||
0x0100: 'ImageWidth',
|
||||
0x0101: 'ImageHeight',
|
||||
0x8769: 'ExifIFDPointer',
|
||||
0x8825: 'GPSInfoIFDPointer',
|
||||
0xa005: 'InteroperabilityIFDPointer',
|
||||
0x0102: 'BitsPerSample',
|
||||
0x0103: 'Compression',
|
||||
0x0106: 'PhotometricInterpretation',
|
||||
0x0112: 'Orientation',
|
||||
0x0115: 'SamplesPerPixel',
|
||||
0x011c: 'PlanarConfiguration',
|
||||
0x0212: 'YCbCrSubSampling',
|
||||
0x0213: 'YCbCrPositioning',
|
||||
0x011a: 'XResolution',
|
||||
0x011b: 'YResolution',
|
||||
0x0128: 'ResolutionUnit',
|
||||
0x0111: 'StripOffsets',
|
||||
0x0116: 'RowsPerStrip',
|
||||
0x0117: 'StripByteCounts',
|
||||
0x0201: 'JPEGInterchangeFormat',
|
||||
0x0202: 'JPEGInterchangeFormatLength',
|
||||
0x012d: 'TransferFunction',
|
||||
0x013e: 'WhitePoint',
|
||||
0x013f: 'PrimaryChromaticities',
|
||||
0x0211: 'YCbCrCoefficients',
|
||||
0x0214: 'ReferenceBlackWhite',
|
||||
0x0132: 'DateTime',
|
||||
0x010e: 'ImageDescription',
|
||||
0x010f: 'Make',
|
||||
0x0110: 'Model',
|
||||
0x0131: 'Software',
|
||||
0x013b: 'Artist',
|
||||
0x8298: 'Copyright',
|
||||
// ==================
|
||||
// Exif Sub IFD tags:
|
||||
// ==================
|
||||
0x9000: 'ExifVersion', // EXIF version
|
||||
0xa000: 'FlashpixVersion', // Flashpix format version
|
||||
0xa001: 'ColorSpace', // Color space information tag
|
||||
0xa002: 'PixelXDimension', // Valid width of meaningful image
|
||||
0xa003: 'PixelYDimension', // Valid height of meaningful image
|
||||
0xa500: 'Gamma',
|
||||
0x9101: 'ComponentsConfiguration', // Information about channels
|
||||
0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel
|
||||
0x927c: 'MakerNote', // Any desired information written by the manufacturer
|
||||
0x9286: 'UserComment', // Comments by user
|
||||
0xa004: 'RelatedSoundFile', // Name of related sound file
|
||||
0x9003: 'DateTimeOriginal', // Date and time when the original image was generated
|
||||
0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally
|
||||
0x9290: 'SubSecTime', // Fractions of seconds for DateTime
|
||||
0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal
|
||||
0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized
|
||||
0x829a: 'ExposureTime', // Exposure time (in seconds)
|
||||
0x829d: 'FNumber',
|
||||
0x8822: 'ExposureProgram', // Exposure program
|
||||
0x8824: 'SpectralSensitivity', // Spectral sensitivity
|
||||
0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2
|
||||
0x8828: 'OECF', // Optoelectric conversion factor
|
||||
0x8830: 'SensitivityType',
|
||||
0x8831: 'StandardOutputSensitivity',
|
||||
0x8832: 'RecommendedExposureIndex',
|
||||
0x8833: 'ISOSpeed',
|
||||
0x8834: 'ISOSpeedLatitudeyyy',
|
||||
0x8835: 'ISOSpeedLatitudezzz',
|
||||
0x9201: 'ShutterSpeedValue', // Shutter speed
|
||||
0x9202: 'ApertureValue', // Lens aperture
|
||||
0x9203: 'BrightnessValue', // Value of brightness
|
||||
0x9204: 'ExposureBias', // Exposure bias
|
||||
0x9205: 'MaxApertureValue', // Smallest F number of lens
|
||||
0x9206: 'SubjectDistance', // Distance to subject in meters
|
||||
0x9207: 'MeteringMode', // Metering mode
|
||||
0x9208: 'LightSource', // Kind of light source
|
||||
0x9209: 'Flash', // Flash status
|
||||
0x9214: 'SubjectArea', // Location and area of main subject
|
||||
0x920a: 'FocalLength', // Focal length of the lens in mm
|
||||
0xa20b: 'FlashEnergy', // Strobe energy in BCPS
|
||||
0xa20c: 'SpatialFrequencyResponse',
|
||||
0xa20e: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit
|
||||
0xa20f: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit
|
||||
0xa210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution
|
||||
0xa214: 'SubjectLocation', // Location of subject in image
|
||||
0xa215: 'ExposureIndex', // Exposure index selected on camera
|
||||
0xa217: 'SensingMethod', // Image sensor type
|
||||
0xa300: 'FileSource', // Image source (3 == DSC)
|
||||
0xa301: 'SceneType', // Scene type (1 == directly photographed)
|
||||
0xa302: 'CFAPattern', // Color filter array geometric pattern
|
||||
0xa401: 'CustomRendered', // Special processing
|
||||
0xa402: 'ExposureMode', // Exposure mode
|
||||
0xa403: 'WhiteBalance', // 1 = auto white balance, 2 = manual
|
||||
0xa404: 'DigitalZoomRatio', // Digital zoom ratio
|
||||
0xa405: 'FocalLengthIn35mmFilm',
|
||||
0xa406: 'SceneCaptureType', // Type of scene
|
||||
0xa407: 'GainControl', // Degree of overall image gain adjustment
|
||||
0xa408: 'Contrast', // Direction of contrast processing applied by camera
|
||||
0xa409: 'Saturation', // Direction of saturation processing applied by camera
|
||||
0xa40a: 'Sharpness', // Direction of sharpness processing applied by camera
|
||||
0xa40b: 'DeviceSettingDescription',
|
||||
0xa40c: 'SubjectDistanceRange', // Distance to subject
|
||||
0xa420: 'ImageUniqueID', // Identifier assigned uniquely to each image
|
||||
0xa430: 'CameraOwnerName',
|
||||
0xa431: 'BodySerialNumber',
|
||||
0xa432: 'LensSpecification',
|
||||
0xa433: 'LensMake',
|
||||
0xa434: 'LensModel',
|
||||
0xa435: 'LensSerialNumber',
|
||||
// ==============
|
||||
// GPS Info tags:
|
||||
// ==============
|
||||
0x0000: 'GPSVersionID',
|
||||
0x0001: 'GPSLatitudeRef',
|
||||
0x0002: 'GPSLatitude',
|
||||
0x0003: 'GPSLongitudeRef',
|
||||
0x0004: 'GPSLongitude',
|
||||
0x0005: 'GPSAltitudeRef',
|
||||
0x0006: 'GPSAltitude',
|
||||
0x0007: 'GPSTimeStamp',
|
||||
0x0008: 'GPSSatellites',
|
||||
0x0009: 'GPSStatus',
|
||||
0x000a: 'GPSMeasureMode',
|
||||
0x000b: 'GPSDOP',
|
||||
0x000c: 'GPSSpeedRef',
|
||||
0x000d: 'GPSSpeed',
|
||||
0x000e: 'GPSTrackRef',
|
||||
0x000f: 'GPSTrack',
|
||||
0x0010: 'GPSImgDirectionRef',
|
||||
0x0011: 'GPSImgDirection',
|
||||
0x0012: 'GPSMapDatum',
|
||||
0x0013: 'GPSDestLatitudeRef',
|
||||
0x0014: 'GPSDestLatitude',
|
||||
0x0015: 'GPSDestLongitudeRef',
|
||||
0x0016: 'GPSDestLongitude',
|
||||
0x0017: 'GPSDestBearingRef',
|
||||
0x0018: 'GPSDestBearing',
|
||||
0x0019: 'GPSDestDistanceRef',
|
||||
0x001a: 'GPSDestDistance',
|
||||
0x001b: 'GPSProcessingMethod',
|
||||
0x001c: 'GPSAreaInformation',
|
||||
0x001d: 'GPSDateStamp',
|
||||
0x001e: 'GPSDifferential',
|
||||
0x001f: 'GPSHPositioningError'
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.stringValues = {
|
||||
ExposureProgram: {
|
||||
0: 'Undefined',
|
||||
1: 'Manual',
|
||||
2: 'Normal program',
|
||||
3: 'Aperture priority',
|
||||
4: 'Shutter priority',
|
||||
5: 'Creative program',
|
||||
6: 'Action program',
|
||||
7: 'Portrait mode',
|
||||
8: 'Landscape mode'
|
||||
},
|
||||
MeteringMode: {
|
||||
0: 'Unknown',
|
||||
1: 'Average',
|
||||
2: 'CenterWeightedAverage',
|
||||
3: 'Spot',
|
||||
4: 'MultiSpot',
|
||||
5: 'Pattern',
|
||||
6: 'Partial',
|
||||
255: 'Other'
|
||||
},
|
||||
LightSource: {
|
||||
0: 'Unknown',
|
||||
1: 'Daylight',
|
||||
2: 'Fluorescent',
|
||||
3: 'Tungsten (incandescent light)',
|
||||
4: 'Flash',
|
||||
9: 'Fine weather',
|
||||
10: 'Cloudy weather',
|
||||
11: 'Shade',
|
||||
12: 'Daylight fluorescent (D 5700 - 7100K)',
|
||||
13: 'Day white fluorescent (N 4600 - 5400K)',
|
||||
14: 'Cool white fluorescent (W 3900 - 4500K)',
|
||||
15: 'White fluorescent (WW 3200 - 3700K)',
|
||||
17: 'Standard light A',
|
||||
18: 'Standard light B',
|
||||
19: 'Standard light C',
|
||||
20: 'D55',
|
||||
21: 'D65',
|
||||
22: 'D75',
|
||||
23: 'D50',
|
||||
24: 'ISO studio tungsten',
|
||||
255: 'Other'
|
||||
},
|
||||
Flash: {
|
||||
0x0000: 'Flash did not fire',
|
||||
0x0001: 'Flash fired',
|
||||
0x0005: 'Strobe return light not detected',
|
||||
0x0007: 'Strobe return light detected',
|
||||
0x0009: 'Flash fired, compulsory flash mode',
|
||||
0x000d: 'Flash fired, compulsory flash mode, return light not detected',
|
||||
0x000f: 'Flash fired, compulsory flash mode, return light detected',
|
||||
0x0010: 'Flash did not fire, compulsory flash mode',
|
||||
0x0018: 'Flash did not fire, auto mode',
|
||||
0x0019: 'Flash fired, auto mode',
|
||||
0x001d: 'Flash fired, auto mode, return light not detected',
|
||||
0x001f: 'Flash fired, auto mode, return light detected',
|
||||
0x0020: 'No flash function',
|
||||
0x0041: 'Flash fired, red-eye reduction mode',
|
||||
0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
|
||||
0x0047: 'Flash fired, red-eye reduction mode, return light detected',
|
||||
0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
|
||||
0x004d: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
|
||||
0x004f: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
|
||||
0x0059: 'Flash fired, auto mode, red-eye reduction mode',
|
||||
0x005d: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
|
||||
0x005f: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
|
||||
},
|
||||
SensingMethod: {
|
||||
1: 'Undefined',
|
||||
2: 'One-chip color area sensor',
|
||||
3: 'Two-chip color area sensor',
|
||||
4: 'Three-chip color area sensor',
|
||||
5: 'Color sequential area sensor',
|
||||
7: 'Trilinear sensor',
|
||||
8: 'Color sequential linear sensor'
|
||||
},
|
||||
SceneCaptureType: {
|
||||
0: 'Standard',
|
||||
1: 'Landscape',
|
||||
2: 'Portrait',
|
||||
3: 'Night scene'
|
||||
},
|
||||
SceneType: {
|
||||
1: 'Directly photographed'
|
||||
},
|
||||
CustomRendered: {
|
||||
0: 'Normal process',
|
||||
1: 'Custom process'
|
||||
},
|
||||
WhiteBalance: {
|
||||
0: 'Auto white balance',
|
||||
1: 'Manual white balance'
|
||||
},
|
||||
GainControl: {
|
||||
0: 'None',
|
||||
1: 'Low gain up',
|
||||
2: 'High gain up',
|
||||
3: 'Low gain down',
|
||||
4: 'High gain down'
|
||||
},
|
||||
Contrast: {
|
||||
0: 'Normal',
|
||||
1: 'Soft',
|
||||
2: 'Hard'
|
||||
},
|
||||
Saturation: {
|
||||
0: 'Normal',
|
||||
1: 'Low saturation',
|
||||
2: 'High saturation'
|
||||
},
|
||||
Sharpness: {
|
||||
0: 'Normal',
|
||||
1: 'Soft',
|
||||
2: 'Hard'
|
||||
},
|
||||
SubjectDistanceRange: {
|
||||
0: 'Unknown',
|
||||
1: 'Macro',
|
||||
2: 'Close view',
|
||||
3: 'Distant view'
|
||||
},
|
||||
FileSource: {
|
||||
3: 'DSC'
|
||||
},
|
||||
ComponentsConfiguration: {
|
||||
0: '',
|
||||
1: 'Y',
|
||||
2: 'Cb',
|
||||
3: 'Cr',
|
||||
4: 'R',
|
||||
5: 'G',
|
||||
6: 'B'
|
||||
},
|
||||
Orientation: {
|
||||
1: 'top-left',
|
||||
2: 'top-right',
|
||||
3: 'bottom-right',
|
||||
4: 'bottom-left',
|
||||
5: 'left-top',
|
||||
6: 'right-top',
|
||||
7: 'right-bottom',
|
||||
8: 'left-bottom'
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.getText = function (id) {
|
||||
var value = this.get(id)
|
||||
switch (id) {
|
||||
case 'LightSource':
|
||||
case 'Flash':
|
||||
case 'MeteringMode':
|
||||
case 'ExposureProgram':
|
||||
case 'SensingMethod':
|
||||
case 'SceneCaptureType':
|
||||
case 'SceneType':
|
||||
case 'CustomRendered':
|
||||
case 'WhiteBalance':
|
||||
case 'GainControl':
|
||||
case 'Contrast':
|
||||
case 'Saturation':
|
||||
case 'Sharpness':
|
||||
case 'SubjectDistanceRange':
|
||||
case 'FileSource':
|
||||
case 'Orientation':
|
||||
return this.stringValues[id][value]
|
||||
case 'ExifVersion':
|
||||
case 'FlashpixVersion':
|
||||
if (!value) return
|
||||
return String.fromCharCode(value[0], value[1], value[2], value[3])
|
||||
case 'ComponentsConfiguration':
|
||||
if (!value) return
|
||||
return (
|
||||
this.stringValues[id][value[0]] +
|
||||
this.stringValues[id][value[1]] +
|
||||
this.stringValues[id][value[2]] +
|
||||
this.stringValues[id][value[3]]
|
||||
)
|
||||
case 'GPSVersionID':
|
||||
if (!value) return
|
||||
return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]
|
||||
}
|
||||
return String(value)
|
||||
}
|
||||
;(function (exifMapPrototype) {
|
||||
var tags = exifMapPrototype.tags
|
||||
var map = exifMapPrototype.map
|
||||
var prop
|
||||
// Map the tag names to tags:
|
||||
for (prop in tags) {
|
||||
if (Object.prototype.hasOwnProperty.call(tags, prop)) {
|
||||
map[tags[prop]] = prop
|
||||
}
|
||||
}
|
||||
})(loadImage.ExifMap.prototype)
|
||||
|
||||
loadImage.ExifMap.prototype.getAll = function () {
|
||||
var map = {}
|
||||
var prop
|
||||
var id
|
||||
for (prop in this) {
|
||||
if (Object.prototype.hasOwnProperty.call(this, prop)) {
|
||||
id = this.tags[prop]
|
||||
if (id) {
|
||||
map[id] = this.getText(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* JavaScript Load Image Exif Parser
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-meta'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.ExifMap = function () {
|
||||
return this
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.map = {
|
||||
Orientation: 0x0112
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.get = function (id) {
|
||||
return this[id] || this[this.map[id]]
|
||||
}
|
||||
|
||||
loadImage.getExifThumbnail = function (dataView, offset, length) {
|
||||
if (!length || offset + length > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid thumbnail data.')
|
||||
return
|
||||
}
|
||||
return loadImage.createObjectURL(
|
||||
new Blob([dataView.buffer.slice(offset, offset + length)])
|
||||
)
|
||||
}
|
||||
|
||||
loadImage.exifTagTypes = {
|
||||
// byte, 8-bit unsigned int:
|
||||
1: {
|
||||
getValue: function (dataView, dataOffset) {
|
||||
return dataView.getUint8(dataOffset)
|
||||
},
|
||||
size: 1
|
||||
},
|
||||
// ascii, 8-bit byte:
|
||||
2: {
|
||||
getValue: function (dataView, dataOffset) {
|
||||
return String.fromCharCode(dataView.getUint8(dataOffset))
|
||||
},
|
||||
size: 1,
|
||||
ascii: true
|
||||
},
|
||||
// short, 16 bit int:
|
||||
3: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getUint16(dataOffset, littleEndian)
|
||||
},
|
||||
size: 2
|
||||
},
|
||||
// long, 32 bit int:
|
||||
4: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getUint32(dataOffset, littleEndian)
|
||||
},
|
||||
size: 4
|
||||
},
|
||||
// rational = two long values, first is numerator, second is denominator:
|
||||
5: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return (
|
||||
dataView.getUint32(dataOffset, littleEndian) /
|
||||
dataView.getUint32(dataOffset + 4, littleEndian)
|
||||
)
|
||||
},
|
||||
size: 8
|
||||
},
|
||||
// slong, 32 bit signed int:
|
||||
9: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getInt32(dataOffset, littleEndian)
|
||||
},
|
||||
size: 4
|
||||
},
|
||||
// srational, two slongs, first is numerator, second is denominator:
|
||||
10: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return (
|
||||
dataView.getInt32(dataOffset, littleEndian) /
|
||||
dataView.getInt32(dataOffset + 4, littleEndian)
|
||||
)
|
||||
},
|
||||
size: 8
|
||||
}
|
||||
}
|
||||
// undefined, 8-bit byte, value depending on field:
|
||||
loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1]
|
||||
|
||||
loadImage.getExifValue = function (
|
||||
dataView,
|
||||
tiffOffset,
|
||||
offset,
|
||||
type,
|
||||
length,
|
||||
littleEndian
|
||||
) {
|
||||
var tagType = loadImage.exifTagTypes[type]
|
||||
var tagSize
|
||||
var dataOffset
|
||||
var values
|
||||
var i
|
||||
var str
|
||||
var c
|
||||
if (!tagType) {
|
||||
console.log('Invalid Exif data: Invalid tag type.')
|
||||
return
|
||||
}
|
||||
tagSize = tagType.size * length
|
||||
// Determine if the value is contained in the dataOffset bytes,
|
||||
// or if the value at the dataOffset is a pointer to the actual data:
|
||||
dataOffset =
|
||||
tagSize > 4
|
||||
? tiffOffset + dataView.getUint32(offset + 8, littleEndian)
|
||||
: offset + 8
|
||||
if (dataOffset + tagSize > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid data offset.')
|
||||
return
|
||||
}
|
||||
if (length === 1) {
|
||||
return tagType.getValue(dataView, dataOffset, littleEndian)
|
||||
}
|
||||
values = []
|
||||
for (i = 0; i < length; i += 1) {
|
||||
values[i] = tagType.getValue(
|
||||
dataView,
|
||||
dataOffset + i * tagType.size,
|
||||
littleEndian
|
||||
)
|
||||
}
|
||||
if (tagType.ascii) {
|
||||
str = ''
|
||||
// Concatenate the chars:
|
||||
for (i = 0; i < values.length; i += 1) {
|
||||
c = values[i]
|
||||
// Ignore the terminating NULL byte(s):
|
||||
if (c === '\u0000') {
|
||||
break
|
||||
}
|
||||
str += c
|
||||
}
|
||||
return str
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
loadImage.parseExifTag = function (
|
||||
dataView,
|
||||
tiffOffset,
|
||||
offset,
|
||||
littleEndian,
|
||||
data
|
||||
) {
|
||||
var tag = dataView.getUint16(offset, littleEndian)
|
||||
data.exif[tag] = loadImage.getExifValue(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
offset,
|
||||
dataView.getUint16(offset + 2, littleEndian), // tag type
|
||||
dataView.getUint32(offset + 4, littleEndian), // tag length
|
||||
littleEndian
|
||||
)
|
||||
}
|
||||
|
||||
loadImage.parseExifTags = function (
|
||||
dataView,
|
||||
tiffOffset,
|
||||
dirOffset,
|
||||
littleEndian,
|
||||
data
|
||||
) {
|
||||
var tagsNumber, dirEndOffset, i
|
||||
if (dirOffset + 6 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid directory offset.')
|
||||
return
|
||||
}
|
||||
tagsNumber = dataView.getUint16(dirOffset, littleEndian)
|
||||
dirEndOffset = dirOffset + 2 + 12 * tagsNumber
|
||||
if (dirEndOffset + 4 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid directory size.')
|
||||
return
|
||||
}
|
||||
for (i = 0; i < tagsNumber; i += 1) {
|
||||
this.parseExifTag(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
dirOffset + 2 + 12 * i, // tag offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
// Return the offset to the next directory:
|
||||
return dataView.getUint32(dirEndOffset, littleEndian)
|
||||
}
|
||||
|
||||
loadImage.parseExifData = function (dataView, offset, length, data, options) {
|
||||
if (options.disableExif) {
|
||||
return
|
||||
}
|
||||
var tiffOffset = offset + 10
|
||||
var littleEndian
|
||||
var dirOffset
|
||||
var thumbnailData
|
||||
// Check for the ASCII code for "Exif" (0x45786966):
|
||||
if (dataView.getUint32(offset + 4) !== 0x45786966) {
|
||||
// No Exif data, might be XMP data instead
|
||||
return
|
||||
}
|
||||
if (tiffOffset + 8 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid segment size.')
|
||||
return
|
||||
}
|
||||
// Check for the two null bytes:
|
||||
if (dataView.getUint16(offset + 8) !== 0x0000) {
|
||||
console.log('Invalid Exif data: Missing byte alignment offset.')
|
||||
return
|
||||
}
|
||||
// Check the byte alignment:
|
||||
switch (dataView.getUint16(tiffOffset)) {
|
||||
case 0x4949:
|
||||
littleEndian = true
|
||||
break
|
||||
case 0x4d4d:
|
||||
littleEndian = false
|
||||
break
|
||||
default:
|
||||
console.log('Invalid Exif data: Invalid byte alignment marker.')
|
||||
return
|
||||
}
|
||||
// Check for the TIFF tag marker (0x002A):
|
||||
if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {
|
||||
console.log('Invalid Exif data: Missing TIFF marker.')
|
||||
return
|
||||
}
|
||||
// Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
|
||||
dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)
|
||||
// Create the exif object to store the tags:
|
||||
data.exif = new loadImage.ExifMap()
|
||||
// Parse the tags of the main image directory and retrieve the
|
||||
// offset to the next directory, usually the thumbnail directory:
|
||||
dirOffset = loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + dirOffset,
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
if (dirOffset && !options.disableExifThumbnail) {
|
||||
thumbnailData = { exif: {} }
|
||||
dirOffset = loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + dirOffset,
|
||||
littleEndian,
|
||||
thumbnailData
|
||||
)
|
||||
// Check for JPEG Thumbnail offset:
|
||||
if (thumbnailData.exif[0x0201]) {
|
||||
data.exif.Thumbnail = loadImage.getExifThumbnail(
|
||||
dataView,
|
||||
tiffOffset + thumbnailData.exif[0x0201],
|
||||
thumbnailData.exif[0x0202] // Thumbnail data length
|
||||
)
|
||||
}
|
||||
}
|
||||
// Check for Exif Sub IFD Pointer:
|
||||
if (data.exif[0x8769] && !options.disableExifSub) {
|
||||
loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + data.exif[0x8769], // directory offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
// Check for GPS Info IFD Pointer:
|
||||
if (data.exif[0x8825] && !options.disableExifGps) {
|
||||
loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + data.exif[0x8825], // directory offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Registers the Exif parser for the APP1 JPEG meta data segment:
|
||||
loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)
|
||||
|
||||
// Adds the following properties to the parseMetaData callback data:
|
||||
// * exif: The exif tags, parsed by the parseExifData method
|
||||
|
||||
// Adds the following options to the parseMetaData method:
|
||||
// * disableExif: Disables Exif parsing.
|
||||
// * disableExifThumbnail: Disables parsing of the Exif Thumbnail.
|
||||
// * disableExifSub: Disables parsing of the Exif Sub IFD.
|
||||
// * disableExifGps: Disables parsing of the Exif GPS Info IFD.
|
||||
})
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* JavaScript Load Image Fetch
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2017, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-meta'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
if (typeof fetch !== 'undefined' && typeof Request !== 'undefined') {
|
||||
loadImage.fetchBlob = function (url, callback, options) {
|
||||
if (loadImage.hasMetaOption(options)) {
|
||||
fetch(new Request(url, options))
|
||||
.then(function (response) {
|
||||
return response.blob()
|
||||
})
|
||||
.then(callback)
|
||||
.catch(function (err) {
|
||||
console.log(err) // eslint-disable-line no-console
|
||||
callback()
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
// Check for XHR2 support:
|
||||
typeof XMLHttpRequest !== 'undefined' &&
|
||||
typeof ProgressEvent !== 'undefined'
|
||||
) {
|
||||
loadImage.fetchBlob = function (url, callback, options) {
|
||||
if (loadImage.hasMetaOption(options)) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = options || {}
|
||||
var req = new XMLHttpRequest()
|
||||
req.open(options.method || 'GET', url)
|
||||
if (options.headers) {
|
||||
Object.keys(options.headers).forEach(function (key) {
|
||||
req.setRequestHeader(key, options.headers[key])
|
||||
})
|
||||
}
|
||||
req.withCredentials = options.credentials === 'include'
|
||||
req.responseType = 'blob'
|
||||
req.onload = function () {
|
||||
callback(req.response)
|
||||
}
|
||||
req.onerror = req.onabort = req.ontimeout = function (e) {
|
||||
console.log(e) // eslint-disable-line no-console
|
||||
callback()
|
||||
}
|
||||
req.send(options.body)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* JavaScript Load Image IPTC Map
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* Copyright 2018, Dave Bevan
|
||||
*
|
||||
* IPTC tags mapping based on
|
||||
* https://github.com/jseidelin/exif-js
|
||||
* https://iptc.org/standards/photo-metadata
|
||||
* http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-iptc'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-iptc'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.IptcMap.prototype.tags = {
|
||||
// ==========
|
||||
// IPTC tags:
|
||||
// ==========
|
||||
0x03: 'ObjectType',
|
||||
0x04: 'ObjectAttribute',
|
||||
0x05: 'ObjectName',
|
||||
0x07: 'EditStatus',
|
||||
0x08: 'EditorialUpdate',
|
||||
0x0a: 'Urgency',
|
||||
0x0c: 'SubjectRef',
|
||||
0x0f: 'Category',
|
||||
0x14: 'SupplCategory',
|
||||
0x16: 'FixtureID',
|
||||
0x19: 'Keywords',
|
||||
0x1a: 'ContentLocCode',
|
||||
0x1b: 'ContentLocName',
|
||||
0x1e: 'ReleaseDate',
|
||||
0x23: 'ReleaseTime',
|
||||
0x25: 'ExpirationDate',
|
||||
0x26: 'ExpirationTime',
|
||||
0x28: 'SpecialInstructions',
|
||||
0x2a: 'ActionAdvised',
|
||||
0x2d: 'RefService',
|
||||
0x2f: 'RefDate',
|
||||
0x32: 'RefNumber',
|
||||
0x37: 'DateCreated',
|
||||
0x3c: 'TimeCreated',
|
||||
0x3e: 'DigitalCreationDate',
|
||||
0x3f: 'DigitalCreationTime',
|
||||
0x41: 'OriginatingProgram',
|
||||
0x46: 'ProgramVersion',
|
||||
0x4b: 'ObjectCycle',
|
||||
0x50: 'Byline',
|
||||
0x55: 'BylineTitle',
|
||||
0x5a: 'City',
|
||||
0x5c: 'Sublocation',
|
||||
0x5f: 'State',
|
||||
0x64: 'CountryCode',
|
||||
0x65: 'CountryName',
|
||||
0x67: 'OrigTransRef',
|
||||
0x69: 'Headline',
|
||||
0x6e: 'Credit',
|
||||
0x73: 'Source',
|
||||
0x74: 'CopyrightNotice',
|
||||
0x76: 'Contact',
|
||||
0x78: 'Caption',
|
||||
0x7a: 'WriterEditor',
|
||||
0x82: 'ImageType',
|
||||
0x83: 'ImageOrientation',
|
||||
0x87: 'LanguageID'
|
||||
|
||||
// We don't record these tags:
|
||||
//
|
||||
// 0x00: 'RecordVersion',
|
||||
// 0x7d: 'RasterizedCaption',
|
||||
// 0x96: 'AudioType',
|
||||
// 0x97: 'AudioSamplingRate',
|
||||
// 0x98: 'AudioSamplingRes',
|
||||
// 0x99: 'AudioDuration',
|
||||
// 0x9a: 'AudioOutcue',
|
||||
// 0xc8: 'PreviewFileFormat',
|
||||
// 0xc9: 'PreviewFileFormatVer',
|
||||
// 0xca: 'PreviewData'
|
||||
}
|
||||
|
||||
loadImage.IptcMap.prototype.getText = function (id) {
|
||||
var value = this.get(id)
|
||||
return String(value)
|
||||
}
|
||||
;(function (iptcMapPrototype) {
|
||||
var tags = iptcMapPrototype.tags
|
||||
var map = iptcMapPrototype.map || {}
|
||||
var prop
|
||||
// Map the tag names to tags:
|
||||
for (prop in tags) {
|
||||
if (Object.prototype.hasOwnProperty.call(tags, prop)) {
|
||||
map[tags[prop]] = prop
|
||||
}
|
||||
}
|
||||
})(loadImage.IptcMap.prototype)
|
||||
|
||||
loadImage.IptcMap.prototype.getAll = function () {
|
||||
var map = {}
|
||||
var prop
|
||||
var id
|
||||
for (prop in this) {
|
||||
if (Object.prototype.hasOwnProperty.call(this, prop)) {
|
||||
id = this.tags[prop]
|
||||
if (id) {
|
||||
map[id] = this.getText(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* JavaScript Load Image IPTC Parser
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* Copyright 2018, Dave Bevan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require, Buffer */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-meta'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.IptcMap = function () {
|
||||
return this
|
||||
}
|
||||
|
||||
loadImage.IptcMap.prototype.map = {
|
||||
ObjectName: 0x5
|
||||
}
|
||||
|
||||
loadImage.IptcMap.prototype.get = function (id) {
|
||||
return this[id] || this[this.map[id]]
|
||||
}
|
||||
|
||||
loadImage.parseIptcTags = function (
|
||||
dataView,
|
||||
startOffset,
|
||||
sectionLength,
|
||||
data
|
||||
) {
|
||||
/**
|
||||
* Retrieves string for the given Buffer and range
|
||||
*
|
||||
* @param {Buffer} buffer IPTC buffer
|
||||
* @param {number} start Range start
|
||||
* @param {number} length Range length
|
||||
* @returns {string} String value
|
||||
*/
|
||||
function getStringFromDB(buffer, start, length) {
|
||||
var outstr = ''
|
||||
for (var n = start; n < start + length; n++) {
|
||||
outstr += String.fromCharCode(buffer.getUint8(n))
|
||||
}
|
||||
return outstr
|
||||
}
|
||||
var fieldValue, dataSize, segmentType
|
||||
var segmentStartPos = startOffset
|
||||
while (segmentStartPos < startOffset + sectionLength) {
|
||||
// we currently handle the 2: class of iptc tag
|
||||
if (
|
||||
dataView.getUint8(segmentStartPos) === 0x1c &&
|
||||
dataView.getUint8(segmentStartPos + 1) === 0x02
|
||||
) {
|
||||
segmentType = dataView.getUint8(segmentStartPos + 2)
|
||||
// only store data for known tags
|
||||
if (segmentType in data.iptc.tags) {
|
||||
dataSize = dataView.getInt16(segmentStartPos + 3)
|
||||
fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize)
|
||||
// Check if we already stored a value with this name
|
||||
if (Object.prototype.hasOwnProperty.call(data.iptc, segmentType)) {
|
||||
// Value already stored with this name, create multivalue field
|
||||
if (data.iptc[segmentType] instanceof Array) {
|
||||
data.iptc[segmentType].push(fieldValue)
|
||||
} else {
|
||||
data.iptc[segmentType] = [data.iptc[segmentType], fieldValue]
|
||||
}
|
||||
} else {
|
||||
data.iptc[segmentType] = fieldValue
|
||||
}
|
||||
}
|
||||
}
|
||||
segmentStartPos++
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.parseIptcData = function (dataView, offset, length, data, options) {
|
||||
if (options.disableIptc) {
|
||||
return
|
||||
}
|
||||
var markerLength = offset + length
|
||||
// Found '8BIM<EOT><EOT>' ?
|
||||
var isFieldSegmentStart = function (dataView, offset) {
|
||||
return (
|
||||
dataView.getUint32(offset) === 0x3842494d &&
|
||||
dataView.getUint16(offset + 4) === 0x0404
|
||||
)
|
||||
}
|
||||
// Hunt forward, looking for the correct IPTC block signature:
|
||||
// Reference: https://metacpan.org/pod/distribution/Image-MetaData-JPEG/lib/Image/MetaData/JPEG/Structures.pod#Structure-of-a-Photoshop-style-APP13-segment
|
||||
// From https://github.com/exif-js/exif-js/blob/master/exif.js ~ line 474 on
|
||||
while (offset + 8 < markerLength) {
|
||||
if (isFieldSegmentStart(dataView, offset)) {
|
||||
var nameHeaderLength = dataView.getUint8(offset + 7)
|
||||
if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1
|
||||
// Check for pre photoshop 6 format
|
||||
if (nameHeaderLength === 0) {
|
||||
// Always 4
|
||||
nameHeaderLength = 4
|
||||
}
|
||||
var startOffset = offset + 8 + nameHeaderLength
|
||||
if (startOffset > markerLength) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Invalid IPTC data: Invalid segment offset.')
|
||||
break
|
||||
}
|
||||
var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength)
|
||||
if (offset + sectionLength > markerLength) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Invalid IPTC data: Invalid segment size.')
|
||||
break
|
||||
}
|
||||
// Create the iptc object to store the tags:
|
||||
data.iptc = new loadImage.IptcMap()
|
||||
// Parse the tags
|
||||
return loadImage.parseIptcTags(
|
||||
dataView,
|
||||
startOffset,
|
||||
sectionLength,
|
||||
data
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
offset++
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('No IPTC data at this offset - could be XMP')
|
||||
}
|
||||
|
||||
// Registers this IPTC parser for the APP13 JPEG meta data segment:
|
||||
loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData)
|
||||
|
||||
// Adds the following properties to the parseMetaData callback data:
|
||||
// * iptc: The iptc tags, parsed by the parseIptcData method
|
||||
|
||||
// Adds the following options to the parseMetaData method:
|
||||
// * disableIptc: Disables IPTC parsing.
|
||||
})
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* JavaScript Load Image Meta
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Image meta data handling implementation
|
||||
* based on the help and contribution of
|
||||
* Achim Stöhr.
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require, DataView, Uint8Array */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var hasblobSlice =
|
||||
typeof Blob !== 'undefined' &&
|
||||
(Blob.prototype.slice ||
|
||||
Blob.prototype.webkitSlice ||
|
||||
Blob.prototype.mozSlice)
|
||||
|
||||
loadImage.blobSlice =
|
||||
hasblobSlice &&
|
||||
function () {
|
||||
var slice = this.slice || this.webkitSlice || this.mozSlice
|
||||
return slice.apply(this, arguments)
|
||||
}
|
||||
|
||||
loadImage.metaDataParsers = {
|
||||
jpeg: {
|
||||
0xffe1: [], // APP1 marker
|
||||
0xffed: [] // APP13 marker
|
||||
}
|
||||
}
|
||||
|
||||
// Parses image meta data and calls the callback with an object argument
|
||||
// with the following properties:
|
||||
// * imageHead: The complete image head as ArrayBuffer (Uint8Array for IE10)
|
||||
// The options argument accepts an object and supports the following
|
||||
// properties:
|
||||
// * maxMetaDataSize: Defines the maximum number of bytes to parse.
|
||||
// * disableImageHead: Disables creating the imageHead property.
|
||||
loadImage.parseMetaData = function (file, callback, options, data) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = options || {}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
data = data || {}
|
||||
var that = this
|
||||
// 256 KiB should contain all EXIF/ICC/IPTC segments:
|
||||
var maxMetaDataSize = options.maxMetaDataSize || 262144
|
||||
var noMetaData = !(
|
||||
typeof DataView !== 'undefined' &&
|
||||
file &&
|
||||
file.size >= 12 &&
|
||||
file.type === 'image/jpeg' &&
|
||||
loadImage.blobSlice
|
||||
)
|
||||
if (
|
||||
noMetaData ||
|
||||
!loadImage.readFile(
|
||||
loadImage.blobSlice.call(file, 0, maxMetaDataSize),
|
||||
function (e) {
|
||||
if (e.target.error) {
|
||||
// FileReader error
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(e.target.error)
|
||||
callback(data)
|
||||
return
|
||||
}
|
||||
// Note on endianness:
|
||||
// Since the marker and length bytes in JPEG files are always
|
||||
// stored in big endian order, we can leave the endian parameter
|
||||
// of the DataView methods undefined, defaulting to big endian.
|
||||
var buffer = e.target.result
|
||||
var dataView = new DataView(buffer)
|
||||
var offset = 2
|
||||
var maxOffset = dataView.byteLength - 4
|
||||
var headLength = offset
|
||||
var markerBytes
|
||||
var markerLength
|
||||
var parsers
|
||||
var i
|
||||
// Check for the JPEG marker (0xffd8):
|
||||
if (dataView.getUint16(0) === 0xffd8) {
|
||||
while (offset < maxOffset) {
|
||||
markerBytes = dataView.getUint16(offset)
|
||||
// Search for APPn (0xffeN) and COM (0xfffe) markers,
|
||||
// which contain application-specific meta-data like
|
||||
// Exif, ICC and IPTC data and text comments:
|
||||
if (
|
||||
(markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||
|
||||
markerBytes === 0xfffe
|
||||
) {
|
||||
// The marker bytes (2) are always followed by
|
||||
// the length bytes (2), indicating the length of the
|
||||
// marker segment, which includes the length bytes,
|
||||
// but not the marker bytes, so we add 2:
|
||||
markerLength = dataView.getUint16(offset + 2) + 2
|
||||
if (offset + markerLength > dataView.byteLength) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Invalid meta data: Invalid segment size.')
|
||||
break
|
||||
}
|
||||
parsers = loadImage.metaDataParsers.jpeg[markerBytes]
|
||||
if (parsers) {
|
||||
for (i = 0; i < parsers.length; i += 1) {
|
||||
parsers[i].call(
|
||||
that,
|
||||
dataView,
|
||||
offset,
|
||||
markerLength,
|
||||
data,
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
offset += markerLength
|
||||
headLength = offset
|
||||
} else {
|
||||
// Not an APPn or COM marker, probably safe to
|
||||
// assume that this is the end of the meta data
|
||||
break
|
||||
}
|
||||
}
|
||||
// Meta length must be longer than JPEG marker (2)
|
||||
// plus APPn marker (2), followed by length bytes (2):
|
||||
if (!options.disableImageHead && headLength > 6) {
|
||||
if (buffer.slice) {
|
||||
data.imageHead = buffer.slice(0, headLength)
|
||||
} else {
|
||||
// Workaround for IE10, which does not yet
|
||||
// support ArrayBuffer.slice:
|
||||
data.imageHead = new Uint8Array(buffer).subarray(0, headLength)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Invalid JPEG file: Missing JPEG marker.')
|
||||
}
|
||||
callback(data)
|
||||
},
|
||||
'readAsArrayBuffer'
|
||||
)
|
||||
) {
|
||||
callback(data)
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if meta data should be loaded automatically:
|
||||
loadImage.hasMetaOption = function (options) {
|
||||
return options && options.meta
|
||||
}
|
||||
|
||||
var originalTransform = loadImage.transform
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
if (loadImage.hasMetaOption(options)) {
|
||||
loadImage.parseMetaData(
|
||||
file,
|
||||
function (data) {
|
||||
originalTransform.call(loadImage, img, options, callback, file, data)
|
||||
},
|
||||
options,
|
||||
data
|
||||
)
|
||||
} else {
|
||||
originalTransform.apply(loadImage, arguments)
|
||||
}
|
||||
}
|
||||
})
|
||||
188
wwwroot/BackEnd/assets/vendor/blueimp-load-image/js/load-image-orientation.js
vendored
Normal file
188
wwwroot/BackEnd/assets/vendor/blueimp-load-image/js/load-image-orientation.js
vendored
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* JavaScript Load Image Orientation
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-scale', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(
|
||||
require('./load-image'),
|
||||
require('./load-image-scale'),
|
||||
require('./load-image-meta')
|
||||
)
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var originalHasCanvasOption = loadImage.hasCanvasOption
|
||||
var originalHasMetaOption = loadImage.hasMetaOption
|
||||
var originalTransformCoordinates = loadImage.transformCoordinates
|
||||
var originalGetTransformedOptions = loadImage.getTransformedOptions
|
||||
|
||||
// Determines if the target image should be a canvas element:
|
||||
loadImage.hasCanvasOption = function (options) {
|
||||
return (
|
||||
!!options.orientation || originalHasCanvasOption.call(loadImage, options)
|
||||
)
|
||||
}
|
||||
|
||||
// Determines if meta data should be loaded automatically:
|
||||
loadImage.hasMetaOption = function (options) {
|
||||
return (
|
||||
(options && options.orientation === true) ||
|
||||
originalHasMetaOption.call(loadImage, options)
|
||||
)
|
||||
}
|
||||
|
||||
// Transform image orientation based on
|
||||
// the given EXIF orientation option:
|
||||
loadImage.transformCoordinates = function (canvas, options) {
|
||||
originalTransformCoordinates.call(loadImage, canvas, options)
|
||||
var ctx = canvas.getContext('2d')
|
||||
var width = canvas.width
|
||||
var height = canvas.height
|
||||
var styleWidth = canvas.style.width
|
||||
var styleHeight = canvas.style.height
|
||||
var orientation = options.orientation
|
||||
if (!orientation || orientation > 8) {
|
||||
return
|
||||
}
|
||||
if (orientation > 4) {
|
||||
canvas.width = height
|
||||
canvas.height = width
|
||||
canvas.style.width = styleHeight
|
||||
canvas.style.height = styleWidth
|
||||
}
|
||||
switch (orientation) {
|
||||
case 2:
|
||||
// horizontal flip
|
||||
ctx.translate(width, 0)
|
||||
ctx.scale(-1, 1)
|
||||
break
|
||||
case 3:
|
||||
// 180° rotate left
|
||||
ctx.translate(width, height)
|
||||
ctx.rotate(Math.PI)
|
||||
break
|
||||
case 4:
|
||||
// vertical flip
|
||||
ctx.translate(0, height)
|
||||
ctx.scale(1, -1)
|
||||
break
|
||||
case 5:
|
||||
// vertical flip + 90 rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.scale(1, -1)
|
||||
break
|
||||
case 6:
|
||||
// 90° rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.translate(0, -height)
|
||||
break
|
||||
case 7:
|
||||
// horizontal flip + 90 rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.translate(width, -height)
|
||||
ctx.scale(-1, 1)
|
||||
break
|
||||
case 8:
|
||||
// 90° rotate left
|
||||
ctx.rotate(-0.5 * Math.PI)
|
||||
ctx.translate(-width, 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms coordinate and dimension options
|
||||
// based on the given orientation option:
|
||||
loadImage.getTransformedOptions = function (img, opts, data) {
|
||||
var options = originalGetTransformedOptions.call(loadImage, img, opts)
|
||||
var orientation = options.orientation
|
||||
var newOptions
|
||||
var i
|
||||
if (orientation === true && data && data.exif) {
|
||||
orientation = data.exif.get('Orientation')
|
||||
}
|
||||
if (!orientation || orientation > 8 || orientation === 1) {
|
||||
return options
|
||||
}
|
||||
newOptions = {}
|
||||
for (i in options) {
|
||||
if (Object.prototype.hasOwnProperty.call(options, i)) {
|
||||
newOptions[i] = options[i]
|
||||
}
|
||||
}
|
||||
newOptions.orientation = orientation
|
||||
switch (orientation) {
|
||||
case 2:
|
||||
// horizontal flip
|
||||
newOptions.left = options.right
|
||||
newOptions.right = options.left
|
||||
break
|
||||
case 3:
|
||||
// 180° rotate left
|
||||
newOptions.left = options.right
|
||||
newOptions.top = options.bottom
|
||||
newOptions.right = options.left
|
||||
newOptions.bottom = options.top
|
||||
break
|
||||
case 4:
|
||||
// vertical flip
|
||||
newOptions.top = options.bottom
|
||||
newOptions.bottom = options.top
|
||||
break
|
||||
case 5:
|
||||
// vertical flip + 90 rotate right
|
||||
newOptions.left = options.top
|
||||
newOptions.top = options.left
|
||||
newOptions.right = options.bottom
|
||||
newOptions.bottom = options.right
|
||||
break
|
||||
case 6:
|
||||
// 90° rotate right
|
||||
newOptions.left = options.top
|
||||
newOptions.top = options.right
|
||||
newOptions.right = options.bottom
|
||||
newOptions.bottom = options.left
|
||||
break
|
||||
case 7:
|
||||
// horizontal flip + 90 rotate right
|
||||
newOptions.left = options.bottom
|
||||
newOptions.top = options.right
|
||||
newOptions.right = options.top
|
||||
newOptions.bottom = options.left
|
||||
break
|
||||
case 8:
|
||||
// 90° rotate left
|
||||
newOptions.left = options.bottom
|
||||
newOptions.top = options.left
|
||||
newOptions.right = options.top
|
||||
newOptions.bottom = options.right
|
||||
break
|
||||
}
|
||||
if (newOptions.orientation > 4) {
|
||||
newOptions.maxWidth = options.maxHeight
|
||||
newOptions.maxHeight = options.maxWidth
|
||||
newOptions.minWidth = options.minHeight
|
||||
newOptions.minHeight = options.minWidth
|
||||
newOptions.sourceWidth = options.sourceHeight
|
||||
newOptions.sourceHeight = options.sourceWidth
|
||||
}
|
||||
return newOptions
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* JavaScript Load Image Scaling
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, module, require */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
})(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var originalTransform = loadImage.transform
|
||||
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
originalTransform.call(
|
||||
loadImage,
|
||||
loadImage.scale(img, options, data),
|
||||
options,
|
||||
callback,
|
||||
file,
|
||||
data
|
||||
)
|
||||
}
|
||||
|
||||
// Transform image coordinates, allows to override e.g.
|
||||
// the canvas orientation based on the orientation option,
|
||||
// gets canvas, options passed as arguments:
|
||||
loadImage.transformCoordinates = function () {}
|
||||
|
||||
// Returns transformed options, allows to override e.g.
|
||||
// maxWidth, maxHeight and crop options based on the aspectRatio.
|
||||
// gets img, options passed as arguments:
|
||||
loadImage.getTransformedOptions = function (img, options) {
|
||||
var aspectRatio = options.aspectRatio
|
||||
var newOptions
|
||||
var i
|
||||
var width
|
||||
var height
|
||||
if (!aspectRatio) {
|
||||
return options
|
||||
}
|
||||
newOptions = {}
|
||||
for (i in options) {
|
||||
if (Object.prototype.hasOwnProperty.call(options, i)) {
|
||||
newOptions[i] = options[i]
|
||||
}
|
||||
}
|
||||
newOptions.crop = true
|
||||
width = img.naturalWidth || img.width
|
||||
height = img.naturalHeight || img.height
|
||||
if (width / height > aspectRatio) {
|
||||
newOptions.maxWidth = height * aspectRatio
|
||||
newOptions.maxHeight = height
|
||||
} else {
|
||||
newOptions.maxWidth = width
|
||||
newOptions.maxHeight = width / aspectRatio
|
||||
}
|
||||
return newOptions
|
||||
}
|
||||
|
||||
// Canvas render method, allows to implement a different rendering algorithm:
|
||||
loadImage.renderImageToCanvas = function (
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
destX,
|
||||
destY,
|
||||
destWidth,
|
||||
destHeight,
|
||||
options
|
||||
) {
|
||||
var ctx = canvas.getContext('2d')
|
||||
if (options.imageSmoothingEnabled === false) {
|
||||
ctx.imageSmoothingEnabled = false
|
||||
} else if (options.imageSmoothingQuality) {
|
||||
ctx.imageSmoothingQuality = options.imageSmoothingQuality
|
||||
}
|
||||
ctx.drawImage(
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
destX,
|
||||
destY,
|
||||
destWidth,
|
||||
destHeight
|
||||
)
|
||||
return canvas
|
||||
}
|
||||
|
||||
// Determines if the target image should be a canvas element:
|
||||
loadImage.hasCanvasOption = function (options) {
|
||||
return options.canvas || options.crop || !!options.aspectRatio
|
||||
}
|
||||
|
||||
// Scales and/or crops the given image (img or canvas HTML element)
|
||||
// using the given options.
|
||||
// Returns a canvas object if the browser supports canvas
|
||||
// and the hasCanvasOption method returns true or a canvas
|
||||
// object is passed as image, else the scaled image:
|
||||
loadImage.scale = function (img, options, data) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = options || {}
|
||||
var canvas = document.createElement('canvas')
|
||||
var useCanvas =
|
||||
img.getContext ||
|
||||
(loadImage.hasCanvasOption(options) && canvas.getContext)
|
||||
var width = img.naturalWidth || img.width
|
||||
var height = img.naturalHeight || img.height
|
||||
var destWidth = width
|
||||
var destHeight = height
|
||||
var maxWidth
|
||||
var maxHeight
|
||||
var minWidth
|
||||
var minHeight
|
||||
var sourceWidth
|
||||
var sourceHeight
|
||||
var sourceX
|
||||
var sourceY
|
||||
var pixelRatio
|
||||
var downsamplingRatio
|
||||
var tmp
|
||||
/**
|
||||
* Scales up image dimensions
|
||||
*/
|
||||
function scaleUp() {
|
||||
var scale = Math.max(
|
||||
(minWidth || destWidth) / destWidth,
|
||||
(minHeight || destHeight) / destHeight
|
||||
)
|
||||
if (scale > 1) {
|
||||
destWidth *= scale
|
||||
destHeight *= scale
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Scales down image dimensions
|
||||
*/
|
||||
function scaleDown() {
|
||||
var scale = Math.min(
|
||||
(maxWidth || destWidth) / destWidth,
|
||||
(maxHeight || destHeight) / destHeight
|
||||
)
|
||||
if (scale < 1) {
|
||||
destWidth *= scale
|
||||
destHeight *= scale
|
||||
}
|
||||
}
|
||||
if (useCanvas) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = loadImage.getTransformedOptions(img, options, data)
|
||||
sourceX = options.left || 0
|
||||
sourceY = options.top || 0
|
||||
if (options.sourceWidth) {
|
||||
sourceWidth = options.sourceWidth
|
||||
if (options.right !== undefined && options.left === undefined) {
|
||||
sourceX = width - sourceWidth - options.right
|
||||
}
|
||||
} else {
|
||||
sourceWidth = width - sourceX - (options.right || 0)
|
||||
}
|
||||
if (options.sourceHeight) {
|
||||
sourceHeight = options.sourceHeight
|
||||
if (options.bottom !== undefined && options.top === undefined) {
|
||||
sourceY = height - sourceHeight - options.bottom
|
||||
}
|
||||
} else {
|
||||
sourceHeight = height - sourceY - (options.bottom || 0)
|
||||
}
|
||||
destWidth = sourceWidth
|
||||
destHeight = sourceHeight
|
||||
}
|
||||
maxWidth = options.maxWidth
|
||||
maxHeight = options.maxHeight
|
||||
minWidth = options.minWidth
|
||||
minHeight = options.minHeight
|
||||
if (useCanvas && maxWidth && maxHeight && options.crop) {
|
||||
destWidth = maxWidth
|
||||
destHeight = maxHeight
|
||||
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
|
||||
if (tmp < 0) {
|
||||
sourceHeight = (maxHeight * sourceWidth) / maxWidth
|
||||
if (options.top === undefined && options.bottom === undefined) {
|
||||
sourceY = (height - sourceHeight) / 2
|
||||
}
|
||||
} else if (tmp > 0) {
|
||||
sourceWidth = (maxWidth * sourceHeight) / maxHeight
|
||||
if (options.left === undefined && options.right === undefined) {
|
||||
sourceX = (width - sourceWidth) / 2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.contain || options.cover) {
|
||||
minWidth = maxWidth = maxWidth || minWidth
|
||||
minHeight = maxHeight = maxHeight || minHeight
|
||||
}
|
||||
if (options.cover) {
|
||||
scaleDown()
|
||||
scaleUp()
|
||||
} else {
|
||||
scaleUp()
|
||||
scaleDown()
|
||||
}
|
||||
}
|
||||
if (useCanvas) {
|
||||
pixelRatio = options.pixelRatio
|
||||
if (pixelRatio > 1) {
|
||||
canvas.style.width = destWidth + 'px'
|
||||
canvas.style.height = destHeight + 'px'
|
||||
destWidth *= pixelRatio
|
||||
destHeight *= pixelRatio
|
||||
canvas.getContext('2d').scale(pixelRatio, pixelRatio)
|
||||
}
|
||||
downsamplingRatio = options.downsamplingRatio
|
||||
if (
|
||||
downsamplingRatio > 0 &&
|
||||
downsamplingRatio < 1 &&
|
||||
destWidth < sourceWidth &&
|
||||
destHeight < sourceHeight
|
||||
) {
|
||||
while (sourceWidth * downsamplingRatio > destWidth) {
|
||||
canvas.width = sourceWidth * downsamplingRatio
|
||||
canvas.height = sourceHeight * downsamplingRatio
|
||||
loadImage.renderImageToCanvas(
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
canvas.width,
|
||||
canvas.height,
|
||||
options
|
||||
)
|
||||
sourceX = 0
|
||||
sourceY = 0
|
||||
sourceWidth = canvas.width
|
||||
sourceHeight = canvas.height
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
img = document.createElement('canvas')
|
||||
img.width = sourceWidth
|
||||
img.height = sourceHeight
|
||||
loadImage.renderImageToCanvas(
|
||||
img,
|
||||
canvas,
|
||||
0,
|
||||
0,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
canvas.width = destWidth
|
||||
canvas.height = destHeight
|
||||
loadImage.transformCoordinates(canvas, options)
|
||||
return loadImage.renderImageToCanvas(
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
destWidth,
|
||||
destHeight,
|
||||
options
|
||||
)
|
||||
}
|
||||
img.width = destWidth
|
||||
img.height = destHeight
|
||||
return img
|
||||
}
|
||||
})
|
||||
File diff suppressed because one or more lines are too long
1
wwwroot/BackEnd/assets/vendor/blueimp-load-image/js/load-image.all.min.js.map
vendored
Normal file
1
wwwroot/BackEnd/assets/vendor/blueimp-load-image/js/load-image.all.min.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* JavaScript Load Image
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, webkitURL, module */
|
||||
|
||||
;(function ($) {
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Loads an image for a given File object.
|
||||
* Invokes the callback with an img or optional canvas element
|
||||
* (if supported by the browser) as parameter:.
|
||||
*
|
||||
* @param {File|Blob|string} file File or Blob object or image URL
|
||||
* @param {Function} [callback] Image load event callback
|
||||
* @param {object} [options] Options object
|
||||
* @returns {HTMLImageElement|HTMLCanvasElement|FileReader} image object
|
||||
*/
|
||||
function loadImage(file, callback, options) {
|
||||
var img = document.createElement('img')
|
||||
var url
|
||||
img.onerror = function (event) {
|
||||
return loadImage.onerror(img, event, file, callback, options)
|
||||
}
|
||||
img.onload = function (event) {
|
||||
return loadImage.onload(img, event, file, callback, options)
|
||||
}
|
||||
if (typeof file === 'string') {
|
||||
loadImage.fetchBlob(
|
||||
file,
|
||||
function (blob) {
|
||||
if (blob && loadImage.isInstanceOf('Blob', blob)) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
file = blob
|
||||
url = loadImage.createObjectURL(file)
|
||||
} else {
|
||||
url = file
|
||||
if (options && options.crossOrigin) {
|
||||
img.crossOrigin = options.crossOrigin
|
||||
}
|
||||
}
|
||||
img.src = url
|
||||
},
|
||||
options
|
||||
)
|
||||
return img
|
||||
} else if (
|
||||
loadImage.isInstanceOf('Blob', file) ||
|
||||
// Files are also Blob instances, but some browsers
|
||||
// (Firefox 3.6) support the File API but not Blobs:
|
||||
loadImage.isInstanceOf('File', file)
|
||||
) {
|
||||
url = img._objectURL = loadImage.createObjectURL(file)
|
||||
if (url) {
|
||||
img.src = url
|
||||
return img
|
||||
}
|
||||
return loadImage.readFile(file, function (e) {
|
||||
var target = e.target
|
||||
if (target && target.result) {
|
||||
img.src = target.result
|
||||
} else if (callback) {
|
||||
callback(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// The check for URL.revokeObjectURL fixes an issue with Opera 12,
|
||||
// which provides URL.createObjectURL but doesn't properly implement it:
|
||||
var urlAPI =
|
||||
($.createObjectURL && $) ||
|
||||
($.URL && URL.revokeObjectURL && URL) ||
|
||||
($.webkitURL && webkitURL)
|
||||
|
||||
/**
|
||||
* Helper function to revoke an object URL
|
||||
*
|
||||
* @param {HTMLImageElement} img Image element
|
||||
* @param {object} [options] Options object
|
||||
*/
|
||||
function revokeHelper(img, options) {
|
||||
if (img._objectURL && !(options && options.noRevoke)) {
|
||||
loadImage.revokeObjectURL(img._objectURL)
|
||||
delete img._objectURL
|
||||
}
|
||||
}
|
||||
|
||||
// If the callback given to this function returns a blob, it is used as image
|
||||
// source instead of the original url and overrides the file argument used in
|
||||
// the onload and onerror event callbacks:
|
||||
loadImage.fetchBlob = function (url, callback) {
|
||||
callback()
|
||||
}
|
||||
|
||||
loadImage.isInstanceOf = function (type, obj) {
|
||||
// Cross-frame instanceof check
|
||||
return Object.prototype.toString.call(obj) === '[object ' + type + ']'
|
||||
}
|
||||
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
callback(img, data)
|
||||
}
|
||||
|
||||
loadImage.onerror = function (img, event, file, callback, options) {
|
||||
revokeHelper(img, options)
|
||||
if (callback) {
|
||||
callback.call(img, event)
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.onload = function (img, event, file, callback, options) {
|
||||
revokeHelper(img, options)
|
||||
if (callback) {
|
||||
loadImage.transform(img, options, callback, file, {
|
||||
originalWidth: img.naturalWidth || img.width,
|
||||
originalHeight: img.naturalHeight || img.height
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.createObjectURL = function (file) {
|
||||
return urlAPI ? urlAPI.createObjectURL(file) : false
|
||||
}
|
||||
|
||||
loadImage.revokeObjectURL = function (url) {
|
||||
return urlAPI ? urlAPI.revokeObjectURL(url) : false
|
||||
}
|
||||
|
||||
// Loads a given File object via FileReader interface,
|
||||
// invokes the callback with the event object (load or error).
|
||||
// The result can be read via event.target.result:
|
||||
loadImage.readFile = function (file, callback, method) {
|
||||
if ($.FileReader) {
|
||||
var fileReader = new FileReader()
|
||||
fileReader.onload = fileReader.onerror = callback
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
method = method || 'readAsDataURL'
|
||||
if (fileReader[method]) {
|
||||
fileReader[method](file)
|
||||
return fileReader
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return loadImage
|
||||
})
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = loadImage
|
||||
} else {
|
||||
$.loadImage = loadImage
|
||||
}
|
||||
})((typeof window !== 'undefined' && window) || this)
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
|
||||
af.js
|
||||
----------------
|
||||
af.js
|
||||
|
||||
ar.js
|
||||
----------------
|
||||
ar.js
|
||||
|
||||
az.js
|
||||
----------------
|
||||
az.js
|
||||
|
||||
bg.js
|
||||
----------------
|
||||
bg.js
|
||||
|
||||
bn.js
|
||||
----------------
|
||||
bn.js
|
||||
|
||||
bs.js
|
||||
----------------
|
||||
bs.js
|
||||
|
||||
ca.js
|
||||
----------------
|
||||
ca.js
|
||||
|
||||
cs.js
|
||||
----------------
|
||||
cs.js
|
||||
|
||||
da.js
|
||||
----------------
|
||||
da.js
|
||||
|
||||
de.js
|
||||
----------------
|
||||
de.js
|
||||
|
||||
dsb.js
|
||||
----------------
|
||||
dsb.js
|
||||
|
||||
el.js
|
||||
----------------
|
||||
el.js
|
||||
|
||||
en.js
|
||||
----------------
|
||||
en.js
|
||||
|
||||
es.js
|
||||
----------------
|
||||
es.js
|
||||
|
||||
et.js
|
||||
----------------
|
||||
et.js
|
||||
|
||||
eu.js
|
||||
----------------
|
||||
eu.js
|
||||
|
||||
fa.js
|
||||
----------------
|
||||
fa.js
|
||||
|
||||
fi.js
|
||||
----------------
|
||||
fi.js
|
||||
|
||||
fr.js
|
||||
----------------
|
||||
fr.js
|
||||
|
||||
gl.js
|
||||
----------------
|
||||
gl.js
|
||||
|
||||
he.js
|
||||
----------------
|
||||
he.js
|
||||
|
||||
hi.js
|
||||
----------------
|
||||
hi.js
|
||||
|
||||
hr.js
|
||||
----------------
|
||||
hr.js
|
||||
|
||||
hsb.js
|
||||
----------------
|
||||
hsb.js
|
||||
|
||||
hu.js
|
||||
----------------
|
||||
hu.js
|
||||
|
||||
hy.js
|
||||
----------------
|
||||
hy.js
|
||||
|
||||
id.js
|
||||
----------------
|
||||
id.js
|
||||
|
||||
is.js
|
||||
----------------
|
||||
is.js
|
||||
|
||||
it.js
|
||||
----------------
|
||||
it.js
|
||||
|
||||
ja.js
|
||||
----------------
|
||||
ja.js
|
||||
|
||||
ka.js
|
||||
----------------
|
||||
ka.js
|
||||
|
||||
km.js
|
||||
----------------
|
||||
km.js
|
||||
|
||||
ko.js
|
||||
----------------
|
||||
ko.js
|
||||
|
||||
lt.js
|
||||
----------------
|
||||
lt.js
|
||||
|
||||
lv.js
|
||||
----------------
|
||||
lv.js
|
||||
|
||||
mk.js
|
||||
----------------
|
||||
mk.js
|
||||
|
||||
ms.js
|
||||
----------------
|
||||
ms.js
|
||||
|
||||
nb.js
|
||||
----------------
|
||||
nb.js
|
||||
|
||||
ne.js
|
||||
----------------
|
||||
ne.js
|
||||
|
||||
nl.js
|
||||
----------------
|
||||
nl.js
|
||||
|
||||
pl.js
|
||||
----------------
|
||||
pl.js
|
||||
|
||||
ps.js
|
||||
----------------
|
||||
ps.js
|
||||
|
||||
pt-BR.js
|
||||
----------------
|
||||
pt-BR.js
|
||||
|
||||
pt.js
|
||||
----------------
|
||||
pt.js
|
||||
|
||||
ro.js
|
||||
----------------
|
||||
ro.js
|
||||
|
||||
ru.js
|
||||
----------------
|
||||
ru.js
|
||||
|
||||
sk.js
|
||||
----------------
|
||||
sk.js
|
||||
|
||||
sl.js
|
||||
----------------
|
||||
sl.js
|
||||
|
||||
sq.js
|
||||
----------------
|
||||
sq.js
|
||||
|
||||
sr-Cyrl.js
|
||||
----------------
|
||||
sr-Cyrl.js
|
||||
|
||||
sr.js
|
||||
----------------
|
||||
sr.js
|
||||
|
||||
sv.js
|
||||
----------------
|
||||
sv.js
|
||||
|
||||
th.js
|
||||
----------------
|
||||
th.js
|
||||
|
||||
tk.js
|
||||
----------------
|
||||
tk.js
|
||||
|
||||
tr.js
|
||||
----------------
|
||||
tr.js
|
||||
|
||||
uk.js
|
||||
----------------
|
||||
uk.js
|
||||
|
||||
vi.js
|
||||
----------------
|
||||
vi.js
|
||||
|
||||
zh-CN.js
|
||||
----------------
|
||||
zh-CN.js
|
||||
|
||||
zh-TW.js
|
||||
----------------
|
||||
zh-TW.js
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها میتوانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجهای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}();
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||
|
||||
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue