diff --git a/.idea/.idea.AGSS/.idea/.gitignore b/.idea/.idea.AGSS/.idea/.gitignore new file mode 100644 index 0000000..d46111d --- /dev/null +++ b/.idea/.idea.AGSS/.idea/.gitignore @@ -0,0 +1,13 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# Rider 忽略的文件 +/projectSettingsUpdater.xml +/modules.xml +/.idea.AGSS.iml +/contentModel.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.AGSS/.idea/material_theme_project_new.xml b/.idea/.idea.AGSS/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..0c66deb --- /dev/null +++ b/.idea/.idea.AGSS/.idea/material_theme_project_new.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.AGSS/.idea/sqldialects.xml b/.idea/.idea.AGSS/.idea/sqldialects.xml new file mode 100644 index 0000000..219889c --- /dev/null +++ b/.idea/.idea.AGSS/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AGSS/AGSS.http b/AGSS/AGSS.http index 7b67830..e69de29 100644 --- a/AGSS/AGSS.http +++ b/AGSS/AGSS.http @@ -1,6 +0,0 @@ -@AGSS_HostAddress = http://localhost:5200 - -GET {{AGSS_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs index 25f1832..99034d9 100644 --- a/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs @@ -6,16 +6,19 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using AGSS.Models.Entities; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AGSS.Areas.Identity.Pages.Account { @@ -111,7 +114,7 @@ namespace AGSS.Areas.Identity.Pages.Account ReturnUrl = returnUrl; } - public async Task OnPostAsync(string returnUrl = null) + public async Task OnPostAsync([FromServices] IOptions jwtOptions,string returnUrl = null) { returnUrl ??= Url.Content("~/"); @@ -125,12 +128,20 @@ namespace AGSS.Areas.Identity.Pages.Account if (result.Succeeded) { _logger.LogInformation("User logged in."); - var user = await _userManager.FindByEmailAsync(Input.Email); + + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); var roles = await _userManager.GetRolesAsync(user); - var token = _jwt.GenerateJwtToken(user,roles); - - var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}"; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value); + + + var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}"; return Redirect(frontendCallback); } diff --git a/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml b/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml index fefa57f..62a62a3 100644 --- a/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml +++ b/AGSS/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml @@ -49,5 +49,8 @@ @section Scripts { - + @await Html.PartialAsync("_ValidationScriptsPartial") + + + } diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml b/AGSS/Areas/Identity/Pages/Account/Register.cshtml index 1fb3d03..eba2f18 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml @@ -12,21 +12,31 @@

创建新账户。


+
+ + + +
- +
- +
+
+ + + +
diff --git a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs index 8a449c6..a5310f8 100644 --- a/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Security.Claims; using System.Text; using System.Text.Encodings.Web; using System.Threading; @@ -14,12 +15,14 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using AGSS.Models.Entities; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AGSS.Areas.Identity.Pages.Account { @@ -104,6 +107,15 @@ namespace AGSS.Areas.Identity.Pages.Account [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } + + + [MaxLength(10)] + public string Sex { get; set; } + + + [MaxLength(10)] + public string UserName { get; set; } + } @@ -113,25 +125,33 @@ namespace AGSS.Areas.Identity.Pages.Account ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } - public async Task OnPostAsync(string returnUrl = null) + public async Task OnPostAsync([FromServices] IOptions jwtOptions,string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var user = CreateUser(); - - await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); + user.Id = Guid.NewGuid().ToString(); + user.Sex = Input.Sex; + await _userStore.SetUserNameAsync(user, Input.UserName, CancellationToken.None); await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); + // var roles = await _userManager.GetRolesAsync(user); + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); var roles = await _userManager.GetRolesAsync(user); - var token = _jwt.GenerateJwtToken(user,roles); - - var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}"; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value); + var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}"; return Redirect(frontendCallback); } diff --git a/AGSS/Controllers/Admin/AdminDictionaryController.cs b/AGSS/Controllers/Admin/AdminDictionaryController.cs new file mode 100644 index 0000000..45bc88b --- /dev/null +++ b/AGSS/Controllers/Admin/AdminDictionaryController.cs @@ -0,0 +1,203 @@ +using System; +using AGSS.Models.Entities; +using AGSS.Models.Template; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using System.Linq; +using System.Threading.Tasks; +using AGSS.DbSet; + +namespace AGSS.Controllers.Admin +{ + + [Route("api/v1/[controller]/[action]")] + public class AdminDictionaryController : ControllerBase + { + private readonly ApplicationDbContext _dbContext; + private readonly UserManager _userManager; + + public AdminDictionaryController(ApplicationDbContext dbContext, UserManager userManager) + { + _dbContext = dbContext; + _userManager = userManager; + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task GetParentDictionaries([FromBody] string label) + { + + + // 确保 label 不是 null + label ??= string.Empty; + + var parentDictionaries = _dbContext.Dictionaries.Where(d => d.ParentId == null && (string.IsNullOrEmpty(label) || d.Label.Contains(label))).ToList(); + return Ok(new ReturnTemplate(200, "查询成功", parentDictionaries)); + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task AddParentDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Label和Value", null)); + } + + dictionary.Uuid = Guid.NewGuid().ToString(); + dictionary.CreateTime = DateTime.UtcNow; + dictionary.CreateUserId = _userManager.GetUserId(User); + + _dbContext.Dictionaries.Add(dictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "添加父级字典成功", dictionary)); + } + + [HttpPut] + [Authorize(Roles = "Admin")] + public async Task UpdateParentDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid和Label", null)); + } + + var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId == null); + if (existingDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null)); + } + + existingDictionary.Label = dictionary.Label; + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "更新父级字典成功", existingDictionary)); + } + + [HttpDelete] + [Authorize(Roles = "Admin")] + public async Task DeleteParentDictionary([FromBody] string uuid) + { + + + if (string.IsNullOrWhiteSpace(uuid)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null)); + } + + var parentDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId == null); + if (parentDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null)); + } + + _dbContext.Dictionaries.RemoveRange(_dbContext.Dictionaries.Where(d => d.ParentId == uuid)); + _dbContext.Dictionaries.Remove(parentDictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "删除父级字典成功", null)); + } + + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task CreateChildDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.ParentId) || string.IsNullOrWhiteSpace(dictionary.ParentValue) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供ParentId、ParentValue、Label和Value", null)); + } + + dictionary.Uuid = Guid.NewGuid().ToString(); + dictionary.CreateTime = DateTime.UtcNow; + dictionary.CreateUserId = _userManager.GetUserId(User); + + _dbContext.Dictionaries.Add(dictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "创建子级字典成功", dictionary)); + } + + [HttpPut] + [Authorize(Roles = "Admin")] + public async Task UpdateChildDictionary([FromBody] DictionaryModel dictionary) + { + + + if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid、Label和Value", null)); + } + + var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId != null); + if (existingDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null)); + } + + existingDictionary.Label = dictionary.Label; + existingDictionary.LabelEn = dictionary.LabelEn; + existingDictionary.Remark = dictionary.Remark; + existingDictionary.Value = dictionary.Value; + existingDictionary.Tag = dictionary.Tag; + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "更新子级字典成功", existingDictionary)); + } + + [HttpDelete] + [Authorize(Roles = "Admin")] + public async Task DeleteChildDictionary([FromBody] string uuid) + { + + if (string.IsNullOrWhiteSpace(uuid)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null)); + } + + var childDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId != null); + if (childDictionary == null) + { + return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null)); + } + + _dbContext.Dictionaries.Remove(childDictionary); + await _dbContext.SaveChangesAsync(); + + return Ok(new ReturnTemplate(200, "删除子级字典成功", null)); + } + + [HttpPost] + public IActionResult GetChildDictionaries([FromBody] ChildDictionaryRequest request) + { + if (string.IsNullOrWhiteSpace(request.Value)) + { + return Ok(new ReturnTemplate(400, "请求参数无效,请提供Value", null)); + } + + var childDictionaries = _dbContext.Dictionaries + .Where(d => d.ParentValue == request.Value && + (request.Tag == null || (!string.IsNullOrEmpty(d.Tag) && d.Tag.Contains("," + request.Tag + ",")))) + .ToList(); + + if (request.Tag != null) + { + childDictionaries = childDictionaries.Where(d => !string.IsNullOrEmpty(d.Tag)).ToList(); + } + + return Ok(new ReturnTemplate(200, "查询成功", childDictionaries)); + } + public class ChildDictionaryRequest + { + public string Value { get; set; } + public string Tag { get; set; } + } + } +} \ No newline at end of file diff --git a/AGSS/Controllers/Admin/AdminRoleControllers.cs b/AGSS/Controllers/Admin/AdminRoleControllers.cs index 007b861..09bcf08 100644 --- a/AGSS/Controllers/Admin/AdminRoleControllers.cs +++ b/AGSS/Controllers/Admin/AdminRoleControllers.cs @@ -1,38 +1,75 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AGSS.Models; +using AGSS.Models.DTOs; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; namespace AGSS.Controllers.Admin; -[Authorize(Roles = "Admin")] +/// +/// 控制器类,用于管理角色相关的操作,包括添加角色、分配角色给用户以及通过角色查询用户。 +/// 该控制器仅限具有"Admin"角色的用户访问。 +/// +[Authorize] [Route("api/v1/[controller]/[action]")] public class AdminRoleControllers:ControllerBase { - - private readonly RoleManager _roleManager; - private readonly UserManager _userManager; // Assuming UserModel is the type of user + /// + /// 用户服务实例,用于执行与用户相关的操作。 + /// 该服务提供了一系列方法来处理用户的查询和更新等操作, + /// 包括但不限于获取用户详细信息、修改用户资料等功能。 + /// + private readonly UserService _userService; - public AdminRoleControllers(RoleManager roleManager, UserManager userManager) + public AdminRoleControllers(UserService userService, RoleManager roleManager, UserManager userManager) { + _userService = userService; _roleManager = roleManager; _userManager = userManager; } - [HttpPost] - public async Task AddRole([FromBody] RoleModel role) - { - if (role == null || string.IsNullOrWhiteSpace(role.Name)) - { - - return Ok(new ReturnTemplate(400,"创建失败,请提供名字","")); - } + /// + /// 角色管理器,用于处理角色相关的操作,如创建、查询等。 + /// 此角色管理器实例主要用于与RoleModel类型的实体进行交互, + /// 支持添加新角色、为用户分配角色等功能。 + /// + private readonly RoleManager _roleManager; - var result = await _roleManager.CreateAsync(role); + /// + /// 用户管理器实例,用于处理用户相关的操作如添加角色、查询用户等。 + /// 此实例通过依赖注入的方式在构造函数中初始化,并在整个控制器生命周期内可用。 + /// + private readonly UserManager _userManager; // Assuming UserModel is the type of user + + /// + /// 管理员角色控制器,用于处理与角色相关的操作,如添加角色、分配角色给用户以及通过角色查询用户。 + /// 该控制器下的所有方法都需要管理员权限才能访问。 + /// + + + /// + /// 添加新角色 + /// + /// 要添加的角色信息 + /// 返回操作结果,包含状态码、消息和数据 + [HttpPost] + public async Task AddRole(string rolename,string normalizedname) + { + + + + var result = await _roleManager.CreateAsync(new RoleModel(){Id = Guid.Empty.ToString(),Name = rolename,NormalizedName = normalizedname}); if (result.Succeeded) { - return Ok(new ReturnTemplate(200,"创建成功",role)); + return Ok(new ReturnTemplate(200,"创建成功","")); } else @@ -40,6 +77,13 @@ public class AdminRoleControllers:ControllerBase return Ok(new ReturnTemplate(StatusCodes.Status500InternalServerError,"创建失败","Failed to create role: " + string.Join(", ", result.Errors.Select(e => e.Description)))); } } + + /// + /// 为指定用户分配角色 + /// + /// 用户的唯一标识符 + /// 要分配的角色名称 + /// 返回一个包含操作结果的ReturnTemplate对象,其中Code表示状态码,Msg表示消息,Data表示附加数据(如果有的话) [HttpPost] public async Task EndowRole(string userId, string roleName) { @@ -58,7 +102,7 @@ public class AdminRoleControllers:ControllerBase var result = await _userManager.AddToRoleAsync(user, role.Name); if (result.Succeeded) { - return Ok(new ReturnTemplate(200, "角色分配成功", user)); + return Ok(new ReturnTemplate(200, "现在该用户已经被赋予这个角色了", user)); } else { @@ -67,25 +111,98 @@ public class AdminRoleControllers:ControllerBase } -/// -/// 通过角色查询用户,支持分页 -/// -/// + /// + /// 删除指定用户。 + /// + /// 要删除的用户的唯一标识符。 + /// 返回操作结果,包含状态码、消息和数据。如果删除成功,则返回200状态码;如果用户ID为空或未找到指定用户,则分别返回400或404状态码;若删除过程中出现错误,则返回500状态码并附带错误信息。 + [HttpPost] + public async Task DelUser(string userId) + { + if (string.IsNullOrWhiteSpace(userId)) + { + return Ok(new ReturnTemplate(400, "你打算拿个空的Id来骗我吗?", null)); + } + + var user = await _userManager.FindByIdAsync(userId); + if (user == null) + { + return Ok(new ReturnTemplate(404, "你输了个假的用户吧......", null)); + } + + // 删除用户 + var result = await _userManager.DeleteAsync(user); + if (result.Succeeded) + { + return Ok(new ReturnTemplate(200, "用户删除成功,不要留念这个用户哦~", null)); + } + else + { + return StatusCode(500, new ReturnTemplate(500, "发生了一些不可预料的错误,555", result.Errors)); + } + } + + + [HttpPost] + public async Task SetMenu([FromBody]MenuRequest request) + { + if (string.IsNullOrWhiteSpace(request.Id) || string.IsNullOrWhiteSpace(request.MenuName)) + { + return Ok(new ReturnTemplate(400, "请求参数无效(有的参数是空的哦~)", "")); + } + var user=await _userManager.FindByIdAsync(request.Id); + if (user==null) + { + return Ok(new ReturnTemplate(404, "Sorry,你输入的用户我们找不到!", "")); + } + user.MenuCode = request.MenuCode; + user.MenuName = request.MenuName; + var result= await _userManager.UpdateAsync(user); + if (result.Succeeded) + { + return Ok(new ReturnTemplate(200, "配置成功啦!", "")); + } + else + { + return StatusCode(500, new ReturnTemplate(500, "删除用户时发生错误,原因请看ErrorResult", result.Errors)); + } + + + } + [HttpGet] + public async Task AllRole() + { + + return Ok(new ReturnTemplate(200,"查询成功啦!", _roleManager.Roles.ToList())); + + } + + + + /// + /// 通过角色查询用户,支持分页 + /// + /// 包含角色名称、页码和每页大小的请求对象 + /// 返回包含总用户数和当前页用户的响应对象 [HttpPost] public async Task SearchUserFromRole([FromBody] SearchUserFromRoleRequest request) { + + + + + IList usersInRole = null; if (string.IsNullOrWhiteSpace(request.RoleName)) { - return Ok(new ReturnTemplate(400, "角色名称不能为空", null)); + usersInRole = await _userService.GetUsersProfileByUserNameAsync(request.UserName); } - - var role = await _roleManager.FindByNameAsync(request.RoleName); - if (role == null) + else { - return Ok(new ReturnTemplate(400, "角色不存在", null)); + var usersInRole1 = await _userService.GetUsersProfileInRoleAsync(request.RoleName); + usersInRole = usersInRole1.Where(a => a.UserName.Contains(request.UserName)).ToList(); + } - var usersInRole = await _userManager.GetUsersInRoleAsync(role.Name); var totalUsers = usersInRole.Count; var pagedUsers = usersInRole @@ -102,16 +219,48 @@ public class AdminRoleControllers:ControllerBase return Ok(new ReturnTemplate(200, "查询成功", response)); } + /// + /// 用于通过角色名称查询用户列表的请求模型。支持分页功能。 + /// public class SearchUserFromRoleRequest { + + + public string UserName { get; set; } + /// + /// 表示角色的名称。此属性用于指定或获取与用户管理相关的角色名称。 + /// 在进行角色分配、查询等操作时,需要提供正确的角色名称以确保操作的成功执行。 + /// public string RoleName { get; set; } + + /// + /// 表示当前请求的页码,默认为1。用于分页查询用户时指定从哪一页开始获取数据。 + /// public int Page { get; set; } = 1; + + /// + /// 每页显示的用户数量。默认值为10。 + /// 该属性用于分页查询中指定每一页应包含的用户条目数。 + /// public int PageSize { get; set; } = 10; } + /// + /// 表示通过角色查询用户后返回的响应数据。 + /// 该类用于封装查询结果,包括总用户数和分页后的用户列表。 + /// public class SearchUserFromRoleResponse { + /// + /// 表示属于特定角色的用户总数。 + /// + /// 此属性用于分页查询中,返回匹配给定角色名称的所有用户的数量。 public int TotalCount { get; set; } - public List Users { get; set; } + + /// + /// 表示属于特定角色的用户列表。该属性用于存储和返回在给定角色下的所有用户。 + /// + /// 此列表通常作为查询结果的一部分,例如通过角色名搜索用户时返回的数据。 + public List Users { get; set; } } } \ No newline at end of file diff --git a/AGSS/Controllers/User/UserControllers.cs b/AGSS/Controllers/User/UserControllers.cs index 1eb57b6..41c9f14 100644 --- a/AGSS/Controllers/User/UserControllers.cs +++ b/AGSS/Controllers/User/UserControllers.cs @@ -1,45 +1,59 @@ +using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; namespace AGSS.Controllers.User; +/// +/// 用户控制器,提供与用户相关的API接口。 +/// +/// 此控制器需要授权才能访问其方法。 [Authorize] [Route("api/v1/[controller]/[action]")] public class UserControllers:ControllerBase -{ - +{ + /// + /// 用户服务实例,用于执行与用户相关的操作。 + /// 该服务提供了一系列方法来处理用户的查询和更新等操作, + /// 包括但不限于获取用户详细信息、修改用户资料等功能。 + /// private readonly UserService _userService; + /// + /// 用户控制器,提供用户相关操作的API接口。 + /// public UserControllers(UserService userService, UserManager userManager) { _userService = userService; - } + } - - + /// + /// 获取当前登录用户的个人信息。 + /// + /// 返回一个包含状态码、消息和用户信息的ReturnTemplate对象。如果成功,状态码为200;如果失败,状态码为500。 [HttpGet] public async Task My() { + + + + string userId = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value; - if (string.IsNullOrEmpty(userId)) - { - return Ok(new ReturnTemplate(500,"获取用户失败(JWT解析错误)",null)); - } try { var userProfile = await _userService.GetUserProfileAsync(userId); - return Ok(new ReturnTemplate(200,"获取成功!",userProfile)); + return Ok(new ReturnTemplate(200, "获取成功!", userProfile)); } catch (ArgumentException ex) { return NotFound(ex.Message); } - } } \ No newline at end of file diff --git a/AGSS/DbSet/UserSet.cs b/AGSS/DbSet/UserSet.cs index 6d1fb54..a2dbb4d 100644 --- a/AGSS/DbSet/UserSet.cs +++ b/AGSS/DbSet/UserSet.cs @@ -9,6 +9,7 @@ namespace AGSS.DbSet public override DbSet Users { get; set; } public override DbSet Roles { get; set; } + public DbSet Dictionaries { get; set; } public ApplicationDbContext(DbContextOptions options) : base(options) @@ -20,6 +21,11 @@ namespace AGSS.DbSet { base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasKey(d => d.Uuid); // 假设 Id 是 DictionaryModel 的主键字段 + + // 在这里添加额外的配置,如果需要的话 // 例如: // modelBuilder.Entity().ToTable("CustomUsers"); diff --git a/AGSS/Migrations/20250702100149_Initial.Designer.cs b/AGSS/Migrations/20250702100149_Initial.Designer.cs deleted file mode 100644 index fb2159a..0000000 --- a/AGSS/Migrations/20250702100149_Initial.Designer.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250702100149_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("Password") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250702100149_Initial.cs b/AGSS/Migrations/20250702100149_Initial.cs deleted file mode 100644 index ba17990..0000000 --- a/AGSS/Migrations/20250702100149_Initial.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "UserModels", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - AuthId = table.Column(type: "text", nullable: false), - Email = table.Column(type: "text", nullable: false), - Password = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UserModels", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "UserModels"); - } - } -} diff --git a/AGSS/Migrations/20250702110815_usernew.Designer.cs b/AGSS/Migrations/20250702110815_usernew.Designer.cs deleted file mode 100644 index 4d069d8..0000000 --- a/AGSS/Migrations/20250702110815_usernew.Designer.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250702110815_usernew")] - partial class usernew - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250702110815_usernew.cs b/AGSS/Migrations/20250702110815_usernew.cs deleted file mode 100644 index 31a4115..0000000 --- a/AGSS/Migrations/20250702110815_usernew.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class usernew : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Email", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Password", - table: "UserModels"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Email", - table: "UserModels", - type: "text", - nullable: false, - defaultValue: ""); - - migrationBuilder.AddColumn( - name: "Password", - table: "UserModels", - type: "text", - nullable: false, - defaultValue: ""); - } - } -} diff --git a/AGSS/Migrations/20250705081221_newuser.Designer.cs b/AGSS/Migrations/20250705081221_newuser.Designer.cs deleted file mode 100644 index d2c8e0b..0000000 --- a/AGSS/Migrations/20250705081221_newuser.Designer.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250705081221_newuser")] - partial class newuser - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("Sex") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250705081221_newuser.cs b/AGSS/Migrations/20250705081221_newuser.cs deleted file mode 100644 index 1dfddc2..0000000 --- a/AGSS/Migrations/20250705081221_newuser.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class newuser : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "AuthId", - table: "UserModels", - type: "character varying(50)", - maxLength: 50, - nullable: false, - oldClrType: typeof(string), - oldType: "text"); - - migrationBuilder.AddColumn( - name: "Birthday", - table: "UserModels", - type: "character varying(20)", - maxLength: 20, - nullable: true); - - migrationBuilder.AddColumn( - name: "Config", - table: "UserModels", - type: "character varying(200)", - maxLength: 200, - nullable: true); - - migrationBuilder.AddColumn( - name: "Description", - table: "UserModels", - type: "character varying(100)", - maxLength: 100, - nullable: true); - - migrationBuilder.AddColumn( - name: "JobCode", - table: "UserModels", - type: "character varying(10)", - maxLength: 10, - nullable: true); - - migrationBuilder.AddColumn( - name: "JobName", - table: "UserModels", - type: "character varying(10)", - maxLength: 10, - nullable: true); - - migrationBuilder.AddColumn( - name: "Sex", - table: "UserModels", - type: "character varying(20)", - maxLength: 20, - nullable: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Birthday", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Config", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Description", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "JobCode", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "JobName", - table: "UserModels"); - - migrationBuilder.DropColumn( - name: "Sex", - table: "UserModels"); - - migrationBuilder.AlterColumn( - name: "AuthId", - table: "UserModels", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "character varying(50)", - oldMaxLength: 50); - } - } -} diff --git a/AGSS/Migrations/20250708111442_user.Designer.cs b/AGSS/Migrations/20250708111442_user.Designer.cs deleted file mode 100644 index f618b64..0000000 --- a/AGSS/Migrations/20250708111442_user.Designer.cs +++ /dev/null @@ -1,300 +0,0 @@ -// -using System; -using AGSS.DbSet; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20250708111442_user")] - partial class user - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("PhoneNumber") - .HasColumnType("text"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("Sex") - .HasColumnType("text"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("AGSS.Models.Entities.UserModel", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Migrations/20250709054553_userrole.cs b/AGSS/Migrations/20250709054553_userrole.cs deleted file mode 100644 index 47a1543..0000000 --- a/AGSS/Migrations/20250709054553_userrole.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AGSS.Migrations -{ - /// - public partial class userrole : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/AGSS/Migrations/20250709054553_userrole.Designer.cs b/AGSS/Migrations/20250709144855_Initial.Designer.cs similarity index 96% rename from AGSS/Migrations/20250709054553_userrole.Designer.cs rename to AGSS/Migrations/20250709144855_Initial.Designer.cs index 47bab85..19047eb 100644 --- a/AGSS/Migrations/20250709054553_userrole.Designer.cs +++ b/AGSS/Migrations/20250709144855_Initial.Designer.cs @@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace AGSS.Migrations { [DbContext(typeof(ApplicationDbContext))] - [Migration("20250709054553_userrole")] - partial class userrole + [Migration("20250709144855_Initial")] + partial class Initial { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -96,6 +96,14 @@ namespace AGSS.Migrations b.Property("LockoutEnd") .HasColumnType("timestamp with time zone"); + b.Property("MenuCode") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MenuName") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + b.Property("NormalizedEmail") .HasMaxLength(256) .HasColumnType("character varying(256)"); diff --git a/AGSS/Migrations/20250708111442_user.cs b/AGSS/Migrations/20250709144855_Initial.cs similarity index 97% rename from AGSS/Migrations/20250708111442_user.cs rename to AGSS/Migrations/20250709144855_Initial.cs index bcc2e1d..5ad0b31 100644 --- a/AGSS/Migrations/20250708111442_user.cs +++ b/AGSS/Migrations/20250709144855_Initial.cs @@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace AGSS.Migrations { /// - public partial class user : Migration + public partial class Initial : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -37,6 +37,8 @@ namespace AGSS.Migrations JobCode = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), JobName = table.Column(type: "character varying(10)", maxLength: 10, nullable: true), Birthday = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), + MenuCode = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + MenuName = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), UserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), NormalizedUserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), Email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), diff --git a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs index 74624bb..57eb2fc 100644 --- a/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/AGSS/Migrations/ApplicationDbContextModelSnapshot.cs @@ -22,6 +22,51 @@ namespace AGSS.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("AGSS.Models.Entities.DictionaryModel", b => + { + b.Property("Uuid") + .HasColumnType("text"); + + b.Property("CreateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreateUserId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LabelEn") + .IsRequired() + .HasColumnType("text"); + + b.Property("ParentId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ParentValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Remark") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tag") + .IsRequired() + .HasColumnType("text"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Uuid"); + + b.ToTable("Dictionaries"); + }); + modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b => { b.Property("Id") @@ -93,6 +138,14 @@ namespace AGSS.Migrations b.Property("LockoutEnd") .HasColumnType("timestamp with time zone"); + b.Property("MenuCode") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MenuName") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + b.Property("NormalizedEmail") .HasMaxLength(256) .HasColumnType("character varying(256)"); diff --git a/AGSS/Migrations/DBContextModelSnapshot.cs b/AGSS/Migrations/DBContextModelSnapshot.cs deleted file mode 100644 index e76171d..0000000 --- a/AGSS/Migrations/DBContextModelSnapshot.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -using System; -using AGSS.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace AGSS.Migrations -{ - [DbContext(typeof(DBContext))] - partial class DBContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("AGSS.Models.Entities.UserModel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AuthId") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Birthday") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Config") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Description") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("JobCode") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("JobName") - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("Sex") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("Id"); - - b.ToTable("UserModels"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/AGSS/Models/DBContext.cs b/AGSS/Models/DBContext.cs deleted file mode 100644 index f49ba8b..0000000 --- a/AGSS/Models/DBContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AGSS.Models.Entities; -using Microsoft.EntityFrameworkCore; - -namespace AGSS.Models; - -public class DBContext : DbContext -{ - public DBContext(DbContextOptions options) - : base(options) - { - } - - -} \ No newline at end of file diff --git a/AGSS/Models/DTOs/DictionaryDto.cs b/AGSS/Models/DTOs/DictionaryDto.cs new file mode 100644 index 0000000..9558932 --- /dev/null +++ b/AGSS/Models/DTOs/DictionaryDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace AGSS.Models.DTOs +{ + public class DictionaryDto + { + public string Uuid { get; set; } + public string ParentId { get; set; } + public string ParentValue { get; set; } + public string Label { get; set; } + public string LabelEn { get; set; } + public string Remark { get; set; } + public string Value { get; set; } + public string Tag { get; set; } + } +} diff --git a/AGSS/Models/DTOs/MenuRequest.cs b/AGSS/Models/DTOs/MenuRequest.cs new file mode 100644 index 0000000..b8a76c2 --- /dev/null +++ b/AGSS/Models/DTOs/MenuRequest.cs @@ -0,0 +1,8 @@ +namespace AGSS.Models.DTOs; + +public struct MenuRequest +{ + public string Id { get; set; } + public string MenuName { get; set; } + public string? MenuCode { get; set; } +} \ No newline at end of file diff --git a/AGSS/Models/DTOs/UserProfile.cs b/AGSS/Models/DTOs/UserProfile.cs index 063ab64..4c47f59 100644 --- a/AGSS/Models/DTOs/UserProfile.cs +++ b/AGSS/Models/DTOs/UserProfile.cs @@ -11,4 +11,6 @@ public class UserProfile public string? JobCode { get; set; } public string? JobName { get; set; } public string? Birthday { get; set; } + public string? MenuCode { get; set; } + public string? MenuName { get; set; } } diff --git a/AGSS/Models/Entities/DictionaryModel.cs b/AGSS/Models/Entities/DictionaryModel.cs new file mode 100644 index 0000000..77269e1 --- /dev/null +++ b/AGSS/Models/Entities/DictionaryModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +namespace AGSS.Models.Entities +{ + public class DictionaryModel + { + public string Uuid { get; set; } + public string ParentId { get; set; } + public string ParentValue { get; set; } + public string Label { get; set; } + public string LabelEn { get; set; } + public string Remark { get; set; } + public string Value { get; set; } + public string Tag { get; set; } + public DateTime CreateTime { get; set; } + public string CreateUserId { get; set; } + } +} diff --git a/AGSS/Models/Entities/JwtModel.cs b/AGSS/Models/Entities/JwtModel.cs new file mode 100644 index 0000000..6882ed9 --- /dev/null +++ b/AGSS/Models/Entities/JwtModel.cs @@ -0,0 +1,9 @@ +namespace asg_form +{ + public class JWTOptions + { + public string SigningKey { get; set; } + public int ExpireSeconds { get; set; } + } + +} diff --git a/AGSS/Models/Entities/User.cs b/AGSS/Models/Entities/User.cs index 7949e56..242326c 100644 --- a/AGSS/Models/Entities/User.cs +++ b/AGSS/Models/Entities/User.cs @@ -5,8 +5,7 @@ namespace AGSS.Models.Entities; public class UserModel:IdentityUser { - - public string? Sex { get; set; } + public string? Sex { get; set; } [MaxLength(100)] public string? Description { get; set; } [MaxLength(200)] @@ -17,6 +16,10 @@ public class UserModel:IdentityUser public string? JobName { get; set; } [MaxLength(20)] public string? Birthday { get; set; } + [MaxLength(500)] + public string? MenuCode { get; set; } + [MaxLength(500)] + public string? MenuName { get; set; } } diff --git a/AGSS/Program.cs b/AGSS/Program.cs index e68de46..3e306db 100644 --- a/AGSS/Program.cs +++ b/AGSS/Program.cs @@ -4,7 +4,9 @@ using AGSS.DbSet; using AGSS.Models; using AGSS.Models.Entities; using AGSS.Models.Template; +using AGSS.Services; using AGSS.Utilities; +using asg_form; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -33,49 +35,48 @@ builder.Services.AddDbContext(opt => opt.UseNpgsql(builder.Configuration.GetConnectionString("DBContext"))); // Identity 配置 -builder.Services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders() - .AddDefaultUI(); +builder.Services.AddIdentityCore(options => +{ + options.Password.RequireDigit = false; + options.Password.RequireLowercase = false; + options.Password.RequireNonAlphanumeric = false; + options.Password.RequireUppercase = false; + options.Password.RequiredLength = 6; + options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider; + options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider; +}) +.AddRoles() +.AddEntityFrameworkStores() +.AddDefaultUI() +; // 注册 UserService - builder.Services.AddScoped(); + // builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); -builder.Services.AddAuthentication(options => + + + +builder.Services.Configure(builder.Configuration.GetSection("JWT")); + +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(x => { - options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(options => - { - options.TokenValidationParameters = new TokenValidationParameters + var jwtOpt = builder.Configuration.GetSection("JWT").Get(); + byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt.SigningKey); + var secKey = new SymmetricSecurityKey(keyBytes); + x.TokenValidationParameters = new() { - ValidateIssuer = true, - ValidateAudience = true, + ValidateIssuer = false, + ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, - ValidIssuer = builder.Configuration["Jwt:Issuer"], - ValidAudience = builder.Configuration["Jwt:Audience"], - IssuerSigningKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) + IssuerSigningKey = secKey }; - options.Events = new JwtBearerEvents - { - OnChallenge = context => - { - context.HandleResponse(); - context.Response.StatusCode = 200; - context.Response.ContentType = "application/json"; - return context.Response.WriteAsJsonAsync(new ReturnTemplate(401, "你提供了一个错误的Token,所以我们无法验证你的身份,唔......", null)); - } - }; - }).AddMicrosoftAccount(microsoftOptions => - { - microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"]; - microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"]; - }); + }) + .AddCookie("Identity.External").AddCookie("Identity.Application"); diff --git a/AGSS/Services/UserService.cs b/AGSS/Services/UserService.cs index f688a12..440d43b 100644 --- a/AGSS/Services/UserService.cs +++ b/AGSS/Services/UserService.cs @@ -1,6 +1,9 @@ using AGSS.Models; using AGSS.Models.Entities; using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace AGSS.Services; public class UserService { @@ -29,7 +32,98 @@ public class UserService Config = user.Config, JobCode = user.JobCode, JobName = user.JobName, - Birthday = user.Birthday + Birthday = user.Birthday, + MenuCode = user.MenuCode, + MenuName = user.MenuName }; } -} + + + public async Task> GetUsersProfileInRoleAsync(string roleName) + { + var usersInRole = await _userManager.GetUsersInRoleAsync(roleName); + if (usersInRole == null || !usersInRole.Any()) + { + throw new ArgumentException("No users found in the specified role"); + } + + var userProfiles = new List(); + foreach (var user in usersInRole) + { + userProfiles.Add(new UserProfile + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + Sex = user.Sex, + Description = user.Description, + Config = user.Config, + JobCode = user.JobCode, + JobName = user.JobName, + Birthday = user.Birthday, + MenuCode = user.MenuCode, + MenuName = user.MenuName + }); + } + + // Assuming you want to return a single UserProfile, you might need to adjust this logic + // For now, returning the first user's profile + return userProfiles; + } + + + public async Task> GetUsersProfileByUserNameAsync(string userName) + { + var users = await _userManager.Users + .Where(u => u.UserName.Contains(userName)) + .Select(u => new UserProfile + { + Id = u.Id, + UserName = u.UserName, + Email = u.Email, + Sex = u.Sex, + Description = u.Description, + Config = u.Config, + JobCode = u.JobCode, + JobName = u.JobName, + Birthday = u.Birthday, + MenuCode = u.MenuCode, + MenuName = u.MenuName + }) + .ToListAsync(); + + if (users == null || !users.Any()) + { + throw new ArgumentException("No users found with the specified username"); + } + + return users; + } + + public async Task> GetUsersProfileAllAsync() + { + var users = await _userManager.Users + .Select(u => new UserProfile + { + Id = u.Id, + UserName = u.UserName, + Email = u.Email, + Sex = u.Sex, + Description = u.Description, + Config = u.Config, + JobCode = u.JobCode, + JobName = u.JobName, + Birthday = u.Birthday, + MenuCode = u.MenuCode, + MenuName = u.MenuName + }) + .ToListAsync(); + + if (users == null || !users.Any()) + { + throw new ArgumentException("No users found"); + } + + return users; + } +} \ No newline at end of file diff --git a/AGSS/Utilities/Jwt.cs b/AGSS/Utilities/Jwt.cs index b97fbdc..ed86907 100644 --- a/AGSS/Utilities/Jwt.cs +++ b/AGSS/Utilities/Jwt.cs @@ -2,23 +2,19 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using AGSS.Models.Entities; +using asg_form; using Microsoft.IdentityModel.Tokens; namespace AGSS.Utilities; public class Jwt { - private readonly IConfiguration _configuration; + - public Jwt(IConfiguration configuration) + public string BuildToken(IEnumerable claims, JWTOptions options) { - _configuration = configuration; - } - - public string BuildToken(IEnumerable claims) - { - DateTime expires = DateTime.Now.AddDays(int.Parse(_configuration["Jwt:ExpireMinutes"])); - byte[] keyBytes = Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]); + DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds); + byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey); var secKey = new SymmetricSecurityKey(keyBytes); var credentials = new SigningCredentials(secKey, @@ -27,18 +23,4 @@ public class Jwt signingCredentials: credentials, claims: claims); return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); } - - public async Task GenerateJwtToken(UserModel user,IList roles) - { - var claims = new List(); - claims.Add(new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString())); - claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); - // var roles = await user.GetRolesAsync(user); - foreach (string role in roles) - { - claims.Add(new Claim(ClaimTypes.Role, role)); - } - string jwtToken = BuildToken(claims); - return jwtToken; - } } \ No newline at end of file diff --git a/AGSS/Utilities/LINQ.cs b/AGSS/Utilities/LINQ.cs new file mode 100644 index 0000000..467e000 --- /dev/null +++ b/AGSS/Utilities/LINQ.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AGSS.Utilities; + +public static class LINQ +{ + /// + /// 从给定的序列中分页获取元素。 + /// + /// 序列中的元素类型。 + /// 要从中分页的源序列。 + /// 请求的页码,从0开始。 + /// 每页包含的元素数量。 + /// 返回指定页码和页大小对应的子序列。 + /// 如果source为null。 + /// 如果pageIndex是负数或者pageSize是非正数。 + public static IEnumerable Paginate(this IEnumerable source, int pageIndex, int pageSize) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex), "Page index must be non-negative."); + if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize), "Page size must be positive."); + + return source.Skip(pageIndex * pageSize).Take(pageSize); + } +} \ No newline at end of file diff --git a/AGSS/appsettings.Development.json b/AGSS/appsettings.Development.json index f061d7b..021d945 100644 --- a/AGSS/appsettings.Development.json +++ b/AGSS/appsettings.Development.json @@ -15,9 +15,10 @@ }, "AllowedHosts": "*", "Jwt": { + "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", - "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" + "SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" }, "ConnectionStrings": { "DBContext": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=luolan12323;" diff --git a/AGSS/appsettings.json b/AGSS/appsettings.json index f595462..6e8922d 100644 --- a/AGSS/appsettings.json +++ b/AGSS/appsettings.json @@ -14,10 +14,11 @@ }, "AllowedHosts": "*", - "Jwt": { + "JWT": { + "ExpireMinutes": "4", "Issuer": "https://api.zeronode.cn/api", "Audience": "https://api.zeronode.cn/api", - "Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" + "SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak" }, "ConnectionStrings": { "DBContext": "Host=1Panel-postgresql-auKB;Port=5432;Database=zeronode;Username=zeronode;Password=luolan12323;" diff --git a/AGSS/wwwroot/js/qr.js b/AGSS/wwwroot/js/qr.js new file mode 100644 index 0000000..ce04581 --- /dev/null +++ b/AGSS/wwwroot/js/qr.js @@ -0,0 +1,9 @@ +window.addEventListener("load", () => { + const uri = document.getElementById("qrCodeData").getAttribute('data-url'); + new QRCode(document.getElementById("qrCode"), + { + text: uri, + width: 150, + height: 150 + }); +}); \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/.gitignore b/AGSS/wwwroot/lib/qrcode/.gitignore new file mode 100644 index 0000000..f4bd643 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/.gitignore @@ -0,0 +1,4 @@ +.DS_Store + +.idea +.project diff --git a/AGSS/wwwroot/lib/qrcode/LICENSE b/AGSS/wwwroot/lib/qrcode/LICENSE new file mode 100644 index 0000000..93c3323 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/LICENSE @@ -0,0 +1,14 @@ +The MIT License (MIT) +--------------------- +Copyright (c) 2012 davidshimjs + +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. \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/README.md b/AGSS/wwwroot/lib/qrcode/README.md new file mode 100644 index 0000000..5e2d2dc --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/README.md @@ -0,0 +1,46 @@ +# QRCode.js +QRCode.js is javascript library for making QRCode. QRCode.js supports Cross-browser with HTML5 Canvas and table tag in DOM. +QRCode.js has no dependencies. + +## Basic Usages +``` +
+ +``` + +or with some options + +``` +
+ +``` + +and you can use some methods + +``` +qrcode.clear(); // clear the code. +qrcode.makeCode("http://naver.com"); // make another code. +``` + +## Browser Compatibility +IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC. + +## License +MIT License + +## Contact +twitter @davidshimjs + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/davidshimjs/qrcodejs/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/AGSS/wwwroot/lib/qrcode/bower.json b/AGSS/wwwroot/lib/qrcode/bower.json new file mode 100644 index 0000000..0509be6 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/bower.json @@ -0,0 +1,18 @@ +{ + "name": "qrcode.js", + "version": "0.0.1", + "homepage": "https://github.com/davidshimjs/qrcodejs", + "authors": [ + "Sangmin Shim", "Sangmin Shim (http://jaguarjs.com)" + ], + "description": "Cross-browser QRCode generator for javascript", + "main": "qrcode.js", + "ignore": [ + "bower_components", + "node_modules", + "index.html", + "index.svg", + "jquery.min.js", + "qrcode.min.js" + ] +} diff --git a/AGSS/wwwroot/lib/qrcode/index-svg.html b/AGSS/wwwroot/lib/qrcode/index-svg.html new file mode 100644 index 0000000..025a135 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index-svg.html @@ -0,0 +1,47 @@ + + + + Cross-Browser QRCode generator for Javascript + + + + + + + + + + + + + diff --git a/AGSS/wwwroot/lib/qrcode/index.html b/AGSS/wwwroot/lib/qrcode/index.html new file mode 100644 index 0000000..fc16f3d --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index.html @@ -0,0 +1,44 @@ + + + +Cross-Browser QRCode generator for Javascript + + + + + + +
+
+ + + \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/index.svg b/AGSS/wwwroot/lib/qrcode/index.svg new file mode 100644 index 0000000..fabe56a --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/index.svg @@ -0,0 +1,37 @@ + + + + + +
+ +
+ + + +
+
diff --git a/AGSS/wwwroot/lib/qrcode/jquery.min.js b/AGSS/wwwroot/lib/qrcode/jquery.min.js new file mode 100644 index 0000000..2740cc4 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.ajQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/AGSS/wwwroot/lib/qrcode/qrcode.js b/AGSS/wwwroot/lib/qrcode/qrcode.js new file mode 100644 index 0000000..5507c15 --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['
']; + + for (var row = 0; row < nCount; row++) { + aHTML.push(''); + + for (var col = 0; col < nCount; col++) { + aHTML.push(''); + } + + aHTML.push(''); + } + + aHTML.push('
'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/AGSS/wwwroot/lib/qrcode/qrcode.min.js b/AGSS/wwwroot/lib/qrcode/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/AGSS/wwwroot/lib/qrcode/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/script.sql b/script.sql index df7c096..73a8d5b 100644 --- a/script.sql +++ b/script.sql @@ -1,6 +1,105 @@ -START TRANSACTION; +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL, + CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") +); + +START TRANSACTION; +CREATE TABLE "AspNetRoles" ( + "Id" text NOT NULL, + "Name" character varying(256), + "NormalizedName" character varying(256), + "ConcurrencyStamp" text, + CONSTRAINT "PK_AspNetRoles" PRIMARY KEY ("Id") +); + +CREATE TABLE "AspNetUsers" ( + "Id" text NOT NULL, + "Sex" text, + "Description" character varying(100), + "Config" character varying(200), + "JobCode" character varying(10), + "JobName" character varying(10), + "Birthday" character varying(20), + "MenuCode" character varying(500), + "MenuName" character varying(500), + "UserName" character varying(256), + "NormalizedUserName" character varying(256), + "Email" character varying(256), + "NormalizedEmail" character varying(256), + "EmailConfirmed" boolean NOT NULL, + "PasswordHash" text, + "SecurityStamp" text, + "ConcurrencyStamp" text, + "PhoneNumber" text, + "PhoneNumberConfirmed" boolean NOT NULL, + "TwoFactorEnabled" boolean NOT NULL, + "LockoutEnd" timestamp with time zone, + "LockoutEnabled" boolean NOT NULL, + "AccessFailedCount" integer NOT NULL, + CONSTRAINT "PK_AspNetUsers" PRIMARY KEY ("Id") +); + +CREATE TABLE "AspNetRoleClaims" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY, + "RoleId" text NOT NULL, + "ClaimType" text, + "ClaimValue" text, + CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY ("Id"), + CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserClaims" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY, + "UserId" text NOT NULL, + "ClaimType" text, + "ClaimValue" text, + CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id"), + CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserLogins" ( + "LoginProvider" text NOT NULL, + "ProviderKey" text NOT NULL, + "ProviderDisplayName" text, + "UserId" text NOT NULL, + CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey"), + CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserRoles" ( + "UserId" text NOT NULL, + "RoleId" text NOT NULL, + CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId"), + CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserTokens" ( + "UserId" text NOT NULL, + "LoginProvider" text NOT NULL, + "Name" text NOT NULL, + "Value" text, + CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name"), + CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" ("RoleId"); + +CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" ("NormalizedName"); + +CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" ("UserId"); + +CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" ("UserId"); + +CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" ("RoleId"); + +CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail"); + +CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); + INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") -VALUES ('20250709054553_userrole', '9.0.6'); +VALUES ('20250709144855_Initial', '9.0.6'); COMMIT;