diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..0380893c80 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +node_modules +npm-debug.log +Dockerfile* +docker-compose* +.dockerignore +.git +.gitignore +.env +*/bin +*/obj +README.md +LICENSE +.vscode +.vs \ No newline at end of file diff --git a/.gitignore b/.gitignore index cd63ac2e6c..9d3c3957aa 100644 --- a/.gitignore +++ b/.gitignore @@ -285,3 +285,12 @@ framework/test/Volo\.Abp\.AspNetCore\.Mvc\.UI\.Bootstrap\.Demo/package-lock\.jso modules/blogging/app/Volo\.BloggingTestApp/package-lock\.json templates/mvc/src/MyCompanyName\.MyProjectName\.Web/package-lock\.json +samples/MicroserviceDemo/applications/AuthServer.Host/Logs/logs.txt +samples/MicroserviceDemo/microservices/IdentityService.Host/Logs/logs.txt +samples/MicroserviceDemo/applications/BackendAdminApp.Host/Logs/logs.txt +samples/MicroserviceDemo/microservices/ProductService.Host/Logs/logs.txt +samples/MicroserviceDemo/gateways/InternalGateway.Host/Logs/logs.txt +samples/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/Logs/logs.txt +samples/MicroserviceDemo/applications/PublicWebSite.Host/Logs/logs.txt +samples/MicroserviceDemo/gateways/PublicWebSiteGateway.Host/Logs/logs.txt +samples/MicroserviceDemo/microservices/BloggingService.Host/Logs/logs.txt diff --git a/README.md b/README.md index 5074216c59..f6304ad5b3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ABP -[![Build Status](http://vjenkins.dynu.net:5480/job/abp/badge/icon)](http://vjenkins.dynu.net:5480/blue/organizations/jenkins/abp/activity) +[![Build Status](http://vjenkins.dynu.net:5480/job/abp/badge/icon)](http://ci.volosoft.com:5480/blue/organizations/jenkins/abp/activity) This project is the next generation of the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) web application framework. See [the announcement](https://abp.io/blog/abp/Abp-vNext-Announcement). @@ -22,7 +22,7 @@ See the documentation. #### Pre Requirements -- Visual Studio 2017 15.7.0+ +- Visual Studio 2017 15.9.0+ #### Framework diff --git a/abp_io/src/Volo.AbpWebSite.Application/Volo.AbpWebSite.Application.csproj b/abp_io/src/Volo.AbpWebSite.Application/Volo.AbpWebSite.Application.csproj index ec07e51ed1..4a5c64eb64 100644 --- a/abp_io/src/Volo.AbpWebSite.Application/Volo.AbpWebSite.Application.csproj +++ b/abp_io/src/Volo.AbpWebSite.Application/Volo.AbpWebSite.Application.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.2 diff --git a/abp_io/src/Volo.AbpWebSite.Domain/Volo.AbpWebSite.Domain.csproj b/abp_io/src/Volo.AbpWebSite.Domain/Volo.AbpWebSite.Domain.csproj index b0ac5294bc..b0c9926b35 100644 --- a/abp_io/src/Volo.AbpWebSite.Domain/Volo.AbpWebSite.Domain.csproj +++ b/abp_io/src/Volo.AbpWebSite.Domain/Volo.AbpWebSite.Domain.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.2 @@ -12,7 +12,7 @@ - + diff --git a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.Designer.cs b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.Designer.cs new file mode 100644 index 0000000000..9a3dd1e999 --- /dev/null +++ b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.Designer.cs @@ -0,0 +1,826 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.AbpWebSite.EntityFrameworkCore; + +namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations +{ + [DbContext(typeof(AbpWebSiteDbContext))] + [Migration("20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties")] + partial class Added_ConcurrencyStamp_IsDeleted_ExtraProperties + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.4-rtm-31024") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("Description") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("Regex") + .HasMaxLength(512); + + b.Property("RegexDescription") + .HasMaxLength(128); + + b.Property("Required"); + + b.Property("ValueType"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasMaxLength(1024); + + b.Property("RoleId"); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnName("AccessFailedCount") + .HasDefaultValue(0); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .HasColumnName("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("LockoutEnabled") + .HasDefaultValue(false); + + b.Property("LockoutEnd"); + + b.Property("Name") + .HasColumnName("Name") + .HasMaxLength(64); + + b.Property("NormalizedEmail") + .HasColumnName("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .IsRequired() + .HasColumnName("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnName("PasswordHash") + .HasMaxLength(256); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasDefaultValue(false); + + b.Property("SecurityStamp") + .IsRequired() + .HasColumnName("SecurityStamp") + .HasMaxLength(256); + + b.Property("Surname") + .HasColumnName("Surname") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("TwoFactorEnabled") + .HasDefaultValue(false); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasMaxLength(1024); + + b.Property("TenantId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId"); + + b.Property("LoginProvider") + .HasMaxLength(64); + + b.Property("ProviderDisplayName") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196); + + b.Property("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.Property("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider") + .HasMaxLength(64); + + b.Property("Name") + .HasMaxLength(128); + + b.Property("TenantId"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("ProviderKey") + .HasMaxLength(64); + + b.Property("ProviderName") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Blogging.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnName("Description") + .HasMaxLength(1024); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasColumnName("Name") + .HasMaxLength(256); + + b.Property("ShortName") + .IsRequired() + .HasColumnName("ShortName") + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("BlgBlogs"); + }); + + modelBuilder.Entity("Volo.Blogging.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); + + b.Property("PostId") + .HasColumnName("PostId"); + + b.Property("RepliedCommentId") + .HasColumnName("RepliedCommentId"); + + b.Property("Text") + .IsRequired() + .HasColumnName("Text") + .HasMaxLength(1024); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("RepliedCommentId"); + + b.ToTable("BlgComments"); + }); + + modelBuilder.Entity("Volo.Blogging.Posts.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BlogId") + .HasColumnName("BlogId"); + + b.Property("ConcurrencyStamp"); + + b.Property("Content") + .HasColumnName("Content") + .HasMaxLength(1048576); + + b.Property("CoverImage") + .IsRequired() + .HasColumnName("CoverImage"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); + + b.Property("ReadCount"); + + b.Property("Title") + .IsRequired() + .HasColumnName("Title") + .HasMaxLength(512); + + b.Property("Url") + .IsRequired() + .HasColumnName("Url") + .HasMaxLength(64); + + b.HasKey("Id"); + + b.HasIndex("BlogId"); + + b.ToTable("BlgPosts"); + }); + + modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b => + { + b.Property("PostId") + .HasColumnName("PostId"); + + b.Property("TagId") + .HasColumnName("TagId"); + + b.Property("CreationTime"); + + b.Property("CreatorId"); + + b.HasKey("PostId", "TagId"); + + b.HasIndex("TagId"); + + b.ToTable("BlgPostTags"); + }); + + modelBuilder.Entity("Volo.Blogging.Tagging.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BlogId"); + + b.Property("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnName("Description") + .HasMaxLength(512); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasColumnName("Name") + .HasMaxLength(64); + + b.Property("UsageCount") + .HasColumnName("UsageCount"); + + b.HasKey("Id"); + + b.ToTable("BlgTags"); + }); + + modelBuilder.Entity("Volo.Blogging.Users.BlogUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp"); + + b.Property("Email") + .HasColumnName("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasColumnName("Name") + .HasMaxLength(64); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasDefaultValue(false); + + b.Property("Surname") + .HasColumnName("Surname") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.ToTable("BlgUsers"); + }); + + modelBuilder.Entity("Volo.Docs.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); + + b.Property("DefaultDocumentName") + .IsRequired() + .HasMaxLength(128); + + b.Property("DocumentStoreType"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("Format"); + + b.Property("LatestVersionBranchName") + .HasMaxLength(128); + + b.Property("MainWebsiteUrl"); + + b.Property("MinimumVersion"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("NavigationDocumentName") + .IsRequired() + .HasMaxLength(128); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("DocsProjects"); + }); + + modelBuilder.Entity("Volo.Utils.SolutionTemplating.DownloadInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationDuration"); + + b.Property("CreationTime") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnName("CreatorId"); + + b.Property("DatabaseProvider"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("ProjectName") + .IsRequired() + .HasMaxLength(128); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(42); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20); + + b.HasKey("Id"); + + b.ToTable("Downloads"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole") + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Blogging.Comments.Comment", b => + { + b.HasOne("Volo.Blogging.Posts.Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Volo.Blogging.Comments.Comment") + .WithMany() + .HasForeignKey("RepliedCommentId"); + }); + + modelBuilder.Entity("Volo.Blogging.Posts.Post", b => + { + b.HasOne("Volo.Blogging.Blogs.Blog") + .WithMany() + .HasForeignKey("BlogId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b => + { + b.HasOne("Volo.Blogging.Posts.Post") + .WithMany("Tags") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Volo.Blogging.Tagging.Tag") + .WithMany() + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.cs b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.cs new file mode 100644 index 0000000000..c354338499 --- /dev/null +++ b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/20181227114311_Added_ConcurrencyStamp_IsDeleted_ExtraProperties.cs @@ -0,0 +1,77 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations +{ + public partial class Added_ConcurrencyStamp_IsDeleted_ExtraProperties : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "AbpUsers", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool)); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpUsers", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 256); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpRoles", + maxLength: 256, + nullable: false, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.AddColumn( + name: "ConcurrencyStamp", + table: "AbpClaimTypes", + maxLength: 256, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "ExtraProperties", + table: "AbpClaimTypes", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ConcurrencyStamp", + table: "AbpClaimTypes"); + + migrationBuilder.DropColumn( + name: "ExtraProperties", + table: "AbpClaimTypes"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "AbpUsers", + nullable: false, + oldClrType: typeof(bool), + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpUsers", + maxLength: 256, + nullable: false, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpRoles", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 256); + } + } +} diff --git a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/AbpWebSiteDbContextModelSnapshot.cs b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/AbpWebSiteDbContextModelSnapshot.cs index f1af866317..b997aae5ca 100644 --- a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/AbpWebSiteDbContextModelSnapshot.cs +++ b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Migrations/AbpWebSiteDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.1.1-rtm-30846") + .HasAnnotation("ProductVersion", "2.1.4-rtm-31024") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); @@ -24,9 +24,18 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + b.Property("Description") .HasMaxLength(256); + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + b.Property("IsStatic"); b.Property("Name") @@ -53,7 +62,11 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("ConcurrencyStamp"); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); b.Property("ExtraProperties") .HasColumnName("ExtraProperties"); @@ -118,17 +131,20 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations .HasDefaultValue(0); b.Property("ConcurrencyStamp") - .IsRequired() - .HasColumnName("ConcurrencyStamp") - .HasMaxLength(256); + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); - b.Property("CreationTime"); + b.Property("CreationTime") + .HasColumnName("CreationTime"); - b.Property("CreatorId"); + b.Property("CreatorId") + .HasColumnName("CreatorId"); - b.Property("DeleterId"); + b.Property("DeleterId") + .HasColumnName("DeleterId"); - b.Property("DeletionTime"); + b.Property("DeletionTime") + .HasColumnName("DeletionTime"); b.Property("Email") .HasColumnName("Email") @@ -142,11 +158,16 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations b.Property("ExtraProperties") .HasColumnName("ExtraProperties"); - b.Property("IsDeleted"); + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasDefaultValue(false); - b.Property("LastModificationTime"); + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime"); - b.Property("LastModifierId"); + b.Property("LastModifierId") + .HasColumnName("LastModifierId"); b.Property("LockoutEnabled") .ValueGeneratedOnAdd() @@ -641,7 +662,9 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("ConcurrencyStamp"); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); b.Property("DefaultDocumentName") .IsRequired() @@ -685,13 +708,16 @@ namespace Volo.AbpWebSite.EntityFrameworkCore.Migrations .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); b.Property("ConcurrencyStamp") - .IsConcurrencyToken(); + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp"); b.Property("CreationDuration"); - b.Property("CreationTime"); + b.Property("CreationTime") + .HasColumnName("CreationTime"); - b.Property("CreatorId"); + b.Property("CreatorId") + .HasColumnName("CreatorId"); b.Property("DatabaseProvider"); diff --git a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Volo.AbpWebSite.EntityFrameworkCore.csproj b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Volo.AbpWebSite.EntityFrameworkCore.csproj index 892d56593c..936a8cca19 100644 --- a/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Volo.AbpWebSite.EntityFrameworkCore.csproj +++ b/abp_io/src/Volo.AbpWebSite.EntityFrameworkCore/Volo.AbpWebSite.EntityFrameworkCore.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.2 @@ -11,7 +11,7 @@ - + diff --git a/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs b/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs index d0f5369ff2..e1c30e0a26 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs +++ b/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs @@ -1,22 +1,20 @@ -using System.Globalization; -using System.IO; +using System.IO; using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Volo.Abp; using Volo.Abp.Account.Web; -using Volo.Abp.AspNetCore.Modularity; using Volo.Abp.AspNetCore.Mvc.UI; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Autofac; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; @@ -24,12 +22,14 @@ using Volo.Abp.Identity; using Volo.Abp.Identity.Web; using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.PermissionManagement.Identity; using Volo.Abp.Threading; using Volo.Abp.UI; -using Volo.Abp.UI.Navigation; using Volo.Abp.VirtualFileSystem; using Volo.AbpWebSite.Bundling; using Volo.Blogging; +using Volo.Blogging.Files; using Volo.Docs; namespace Volo.AbpWebSite @@ -44,42 +44,46 @@ namespace Volo.AbpWebSite typeof(AbpAccountWebModule), typeof(AbpIdentityApplicationModule), typeof(AbpIdentityWebModule), + typeof(AbpPermissionManagementApplicationModule), + typeof(AbpPermissionManagementDomainIdentityModule), typeof(BloggingApplicationModule), typeof(BloggingWebModule) )] public class AbpWebSiteWebModule : AbpModule { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - context.Services.PreConfigure(options => - { - options.UserSecretsAssembly = typeof(AbpWebSiteWebModule).Assembly; - }); - } - public override void ConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - ConfigureLanguages(context.Services); - ConfigureDatabaseServices(context.Services, configuration); - ConfigureVirtualFileSystem(context.Services, hostingEnvironment); - ConfigureBundles(context.Services); - ConfigureTheme(context.Services); + ConfigureLanguages(); + ConfigureDatabaseServices(configuration); + ConfigureVirtualFileSystem(hostingEnvironment); + ConfigureBundles(); + ConfigureTheme(); + ConfigureBlogging(hostingEnvironment); } - private static void ConfigureLanguages(IServiceCollection services) + private void ConfigureBlogging(IHostingEnvironment hostingEnvironment) { - services.Configure(options => + Configure(options => + { + options.FileUploadLocalFolder = Path.Combine(hostingEnvironment.WebRootPath, "files"); + options.FileUploadUrlRoot = "/files/"; + }); + } + + private void ConfigureLanguages() + { + Configure(options => { options.Languages.Add(new LanguageInfo("en-US", "en-US", "English")); }); } - private static void ConfigureBundles(IServiceCollection services) + private void ConfigureBundles() { - services.Configure(options => + Configure(options => { options .StyleBundles @@ -102,40 +106,40 @@ namespace Volo.AbpWebSite }); } - private static void ConfigureDatabaseServices(IServiceCollection services, IConfigurationRoot configuration) + private void ConfigureDatabaseServices(IConfigurationRoot configuration) { - services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = configuration.GetConnectionString("Default"); }); - services.Configure(options => + Configure(options => { options.UseSqlServer(); }); } - private static void ConfigureVirtualFileSystem(IServiceCollection services, IHostingEnvironment hostingEnvironment) + private void ConfigureVirtualFileSystem(IHostingEnvironment hostingEnvironment) { if (hostingEnvironment.IsDevelopment()) { - services.Configure(options => + Configure(options => { - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Bootstrap", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}docs{0}src{0}Volo.Docs.Domain", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}docs{0}src{0}Volo.Docs.Web", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}blogging{0}src{0}Volo.Blogging.Web", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}account{0}src{0}Volo.Abp.Account.Web", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Bootstrap", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}docs{0}src{0}Volo.Docs.Domain", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}docs{0}src{0}Volo.Docs.Web", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}blogging{0}src{0}Volo.Blogging.Web", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}modules{0}account{0}src{0}Volo.Abp.Account.Web", Path.DirectorySeparatorChar))); }); } } - private void ConfigureTheme(IServiceCollection services) + private void ConfigureTheme() { - services.Configure(options => + Configure(options => { options.Themes.Add(); options.DefaultThemeName = AbpIoTheme.Name; @@ -147,6 +151,8 @@ namespace Volo.AbpWebSite var app = context.GetApplicationBuilder(); var env = context.GetEnvironment(); + app.UseCorrelationId(); + app.UseAbpRequestLocalization(); if (env.IsDevelopment()) @@ -169,29 +175,28 @@ namespace Volo.AbpWebSite app.UseVirtualFiles(); app.UseAuthentication(); - - //TODO: Create an extension method! - app.UseMvc(routes => - { - routes.MapRoute( - name: "defaultWithArea", - template: "{area}/{controller=Home}/{action=Index}/{id?}"); - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); + app.UseMvcWithDefaultRouteAndArea(); - AsyncHelper.RunSync(async () => + using (var scope = context.ServiceProvider.CreateScope()) { - await context.ServiceProvider - .GetRequiredService() - .SeedAsync( - "1q2w3E*", - IdentityPermissions.GetAll() - .Union(BloggingPermissions.GetAll()) - ); - }); + AsyncHelper.RunSync(async () => + { + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync( + "1q2w3E*" + ); + + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync( + RolePermissionValueProvider.ProviderName, + "admin", + IdentityPermissions.GetAll().Union(BloggingPermissions.GetAll()) + ); + }); + } } } } diff --git a/abp_io/src/Volo.AbpWebSite.Web/CorrelationIdLogEventEnricher.cs b/abp_io/src/Volo.AbpWebSite.Web/CorrelationIdLogEventEnricher.cs new file mode 100644 index 0000000000..ee7b0bd248 --- /dev/null +++ b/abp_io/src/Volo.AbpWebSite.Web/CorrelationIdLogEventEnricher.cs @@ -0,0 +1,28 @@ +using Serilog.Core; +using Serilog.Events; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Tracing; + +namespace Volo.AbpWebSite +{ + //This is for trial for now + public class CorrelationIdLogEventEnricher : ILogEventEnricher, ITransientDependency + { + private readonly ICorrelationIdProvider _correlationIdProvider; + + public CorrelationIdLogEventEnricher(ICorrelationIdProvider correlationIdProvider) + { + _correlationIdProvider = correlationIdProvider; + } + + public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) + { + logEvent.AddOrUpdateProperty( + new LogEventProperty( + "CorrelationId", + new ScalarValue("CorrId:" + _correlationIdProvider.Get()) + ) + ); + } + } +} \ No newline at end of file diff --git a/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml b/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml index bf74126618..010209c690 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml +++ b/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml @@ -195,34 +195,34 @@

-
+
 
                     
-<abp-card>
-    <img abp-card-image="Top" src="~/images/my-dog.png" />
-    <abp-card-body>
-        <abp-card-title>Card title</abp-card-title>
-        <abp-card-text>
-            <p>
-                This is a sample card component built by ABP bootstrap
-                card tag helper. ABP has tag helper wrappers for most of 
-                the bootstrap components.
-            </p>
-        </abp-card-text>
-        <a abp-button="Primary" href="#">Go somewhere &rarr;</a>
-    </abp-card-body>
-</abp-card>
+                    <abp-card>
+                        <img abp-card-image="Top" src="~/images/my-dog.png" />
+                        <abp-card-body>
+                            <abp-card-title>Card title</abp-card-title>
+                            <abp-card-text>
+                                <p>
+                                    This is a sample card component built by ABP bootstrap
+                                    card tag helper. ABP has tag helper wrappers for most of 
+                                    the bootstrap components.
+                                </p>
+                            </abp-card-text>
+                            <a abp-button="Primary" href="#">Go somewhere &rarr;</a>
+                        </abp-card-body>
+                    </abp-card>
                         
                     
-
+
-
+
@@ -265,7 +265,7 @@
-
+
 
                     
@@ -300,12 +300,12 @@ public class PersonModel
                     
-
+
-
+
diff --git a/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml b/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml index c3d877b425..8c25d6592b 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml +++ b/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml @@ -26,8 +26,7 @@ Github
  • -
  • diff --git a/abp_io/src/Volo.AbpWebSite.Web/Program.cs b/abp_io/src/Volo.AbpWebSite.Web/Program.cs index 0ae7a19900..7b458c66de 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Program.cs +++ b/abp_io/src/Volo.AbpWebSite.Web/Program.cs @@ -1,13 +1,37 @@ -using System.IO; +using System; +using System.IO; using Microsoft.AspNetCore.Hosting; +using Serilog; +using Serilog.Events; namespace Volo.AbpWebSite { public class Program { - public static void Main(string[] args) + public static int Main(string[] args) { - BuildWebHostInternal(args).Run(); + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() //TODO: Should be configurable! + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .CreateLogger(); + + try + { + Log.Information("Starting web host."); + BuildWebHostInternal(args).Run(); + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } } internal static IWebHost BuildWebHostInternal(string[] args) => @@ -16,6 +40,7 @@ namespace Volo.AbpWebSite .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup() + .UseSerilog() .Build(); } } diff --git a/abp_io/src/Volo.AbpWebSite.Web/Startup.cs b/abp_io/src/Volo.AbpWebSite.Web/Startup.cs index 471337df1c..ce76e2aa8c 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Startup.cs +++ b/abp_io/src/Volo.AbpWebSite.Web/Startup.cs @@ -3,7 +3,6 @@ using System.Text; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Serilog; using Volo.Abp; namespace Volo.AbpWebSite @@ -15,6 +14,7 @@ namespace Volo.AbpWebSite services.AddApplication(options => { options.UseAutofac(); + options.Configuration.UserSecretsAssembly = typeof(AbpWebSiteWebModule).Assembly; }); return services.BuildServiceProviderFromFactory(); @@ -22,15 +22,6 @@ namespace Volo.AbpWebSite public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { - loggerFactory - .AddConsole() - .AddDebug() - .AddSerilog(new LoggerConfiguration() - .Enrich.FromLogContext() - .WriteTo.File("Logs/logs.txt") - .CreateLogger() - ); - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); app.InitializeApplication(); diff --git a/abp_io/src/Volo.AbpWebSite.Web/Volo.AbpWebSite.Web.csproj b/abp_io/src/Volo.AbpWebSite.Web/Volo.AbpWebSite.Web.csproj index 06fad8f448..b434646d99 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Volo.AbpWebSite.Web.csproj +++ b/abp_io/src/Volo.AbpWebSite.Web/Volo.AbpWebSite.Web.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.2 Volo.AbpWebSite $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; true @@ -9,13 +9,13 @@ true true false - true + c140514f-e488-4c99-8b9a-fabee0f53ce0 - - + + @@ -31,6 +31,8 @@ + + @@ -38,7 +40,7 @@ Always - + Always diff --git a/abp_io/src/Volo.AbpWebSite.Web/package-lock.json b/abp_io/src/Volo.AbpWebSite.Web/package-lock.json new file mode 100644 index 0000000000..5e26238da6 --- /dev/null +++ b/abp_io/src/Volo.AbpWebSite.Web/package-lock.json @@ -0,0 +1,2758 @@ +{ + "name": "volo.aspnetzero.support", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@abp/anchor-js": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/anchor-js/-/anchor-js-0.5.1.tgz", + "integrity": "sha512-9N/iPP9tDdq9lKRNFQuqRL+QYSv5fq789KgHHGG1/MqExJ6KTPcqUDHvQ53kz96pUgJA+Fyn3dpwgPqLVYI3Yg==", + "requires": { + "@abp/core": "^0.4.9", + "anchor-js": "^4.1.1" + } + }, + "@abp/aspnetcore.mvc.ui": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-0.4.9.tgz", + "integrity": "sha512-AveMEi6WRQmD1tM9yVNLAe6ffcbtoL3ZGQKTPA95Q+dy5xBXVg4Y8jdhxawNPK64KYArhfrVkQDfa4mq3pW5Qw==", + "requires": { + "ansi-colors": "^1.1.0", + "extend-object": "^1.0.0", + "gulp": "^3.9.1", + "merge-stream": "^1.0.1", + "path": "^0.12.7", + "rimraf": "^2.6.2" + } + }, + "@abp/aspnetcore.mvc.ui.theme.basic": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-0.4.9.tgz", + "integrity": "sha512-g3Zby8x8+vWw3oTJsSPasjm4tv7BG4270PEf7jK9w925+lIyKYHn6UxOcFbSU2pi9mJTnaF+Fk/rScIcdxwZZw==", + "requires": { + "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.9" + } + }, + "@abp/aspnetcore.mvc.ui.theme.shared": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-0.4.9.tgz", + "integrity": "sha512-Fe4UfQ215Pz2V6D5HUYhDJFeJWjKLcv2gsZfOheWLlOBgYh274pdnUIwceoZ4Btpa9aPECLG+LAH4dTbs8vjRg==", + "requires": { + "@abp/aspnetcore.mvc.ui": "^0.4.9", + "@abp/bootstrap": "^0.4.9", + "@abp/datatables.net-bs4": "^0.4.9", + "@abp/font-awesome": "^0.4.9", + "@abp/jquery-form": "^0.4.9", + "@abp/jquery-validation-unobtrusive": "^0.4.9", + "@abp/lodash": "^0.4.9", + "@abp/select2": "^0.4.9", + "@abp/sweetalert": "^0.4.9", + "@abp/timeago": "^0.4.9", + "@abp/toastr": "^0.4.9" + } + }, + "@abp/blogging": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/blogging/-/blogging-0.4.9.tgz", + "integrity": "sha512-cMFLekebHCM1ZAGPxcli3yzEy0kq1nV8ZuV9JbaczoiC/KDOnBp8CWq61CwLxgnfZpVIO5RTdtDye9pDtBJdmg==", + "requires": { + "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.9", + "@abp/owl.carousel": "^0.4.9", + "@abp/tui-editor": "^0.4.9" + } + }, + "@abp/bootstrap": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/bootstrap/-/bootstrap-0.4.9.tgz", + "integrity": "sha512-A7lDHo43KnqjINo0xWECx/WzNQe3vqvE3GPv6uXq3KDi+gStQLAFBq3bVcVW/kSxiquDQ/tuCLRpE0qlhoobag==", + "requires": { + "@abp/core": "^0.4.9", + "bootstrap": "^4.1.1" + } + }, + "@abp/clipboard": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/clipboard/-/clipboard-0.5.1.tgz", + "integrity": "sha512-efOPloVL0moRqGpAMA7DU5o+vzzu7ipGOFcG9nOfDD6uGY9AsOztFc71GwIFrtwADvJSiJHD6OfEIfR++dCT0w==", + "requires": { + "@abp/core": "^0.4.9", + "clipboard": "^2.0.4" + } + }, + "@abp/codemirror": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/codemirror/-/codemirror-0.4.9.tgz", + "integrity": "sha512-bjuKZKLHyBzr6lWZ5Fh4Io/6u0OILkwsB9LJAZ3cHnDkmBEIRlnQBmuGxCkQ3D0sXcFWrLoqb2FAB9djLxCnUQ==", + "requires": { + "@abp/core": "^0.4.9", + "codemirror": "^5.38.0" + } + }, + "@abp/core": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/core/-/core-0.4.9.tgz", + "integrity": "sha512-JbibIPDz0w/C9YhexNagMD763qbZCclcHLVlTpKEZUcxzp6rZXwPR6ekh/PnvzD0R7wmHOh+bHl0hs5JSdy3oA==" + }, + "@abp/datatables.net": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/datatables.net/-/datatables.net-0.4.9.tgz", + "integrity": "sha512-URimiGMFBusEMo9aAadLFCossbYyrN2R6+6YrQ+heqxdheCPmm2wupsXSFoUBHBhD0tzF4rY+OL//oOg3Wtg4g==", + "requires": { + "@abp/core": "^0.4.9", + "datatables.net": "^1.10.16" + } + }, + "@abp/datatables.net-bs4": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/datatables.net-bs4/-/datatables.net-bs4-0.4.9.tgz", + "integrity": "sha512-Dsz0fy2haBz3dl2MLXWjW2bhDBzp1cpWXSXj8TEEzYazjhyoqBy6AiFlEnRCqO49KZD6Ps1cONSRxx4c4On9Lg==", + "requires": { + "@abp/datatables.net": "^0.4.9", + "datatables.net-bs4": "^1.10.16" + } + }, + "@abp/docs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/docs/-/docs-0.5.1.tgz", + "integrity": "sha512-3pGYnxZxm2kYPfu2EwDF0QinsNTym2cWlYAo7mVUBuReTPMhwHYtgrE7AX3nCVv1iAo6ltW+mebonGt1s5yXzA==", + "requires": { + "@abp/anchor-js": "^0.5.1", + "@abp/clipboard": "^0.5.1", + "@abp/malihu-custom-scrollbar-plugin": "^0.5.1", + "@abp/popper.js": "^0.5.1", + "@abp/prismjs": "^0.5.1" + } + }, + "@abp/font-awesome": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/font-awesome/-/font-awesome-0.4.9.tgz", + "integrity": "sha512-H4H/PJeSypoq++jP7eqS3y5jpbPIglUByPymHnho7U84gO06tZBUIoK00zyLACUVLzNztWANhmVqyA6OaHQ6xQ==", + "requires": { + "@abp/core": "^0.4.9", + "font-awesome": "^4.7.0" + } + }, + "@abp/highlight.js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/highlight.js/-/highlight.js-0.4.9.tgz", + "integrity": "sha512-bsXgtOAJ8O4W3AO9arIxwLCC1JZABlZtoB55Pk5WjGiu8mhWiB4+HCXqWtSBE2qXwSLoDBE2FS5KAtIPfGfn+g==", + "requires": { + "@abp/core": "^0.4.9" + } + }, + "@abp/jquery": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery/-/jquery-0.4.9.tgz", + "integrity": "sha512-Lte2rfDhcVXRA18mJMyPs0oFoiX/7x10F9cwMyX4+8e9QulA0dg+MjJZ4HIbxRoKvaYPz0AdE5VZ511folFeTg==", + "requires": { + "@abp/core": "^0.4.9", + "jquery": "^3.3.1" + } + }, + "@abp/jquery-form": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-form/-/jquery-form-0.4.9.tgz", + "integrity": "sha512-T1LzHNO+L/ATSfsaSu9H5rq9oUGjjBrwcJBVQhWRuGbB/Nsv1t4CdCPZHqbYBsn3ji/6T9C80FMdL+s4iOfy8A==", + "requires": { + "@abp/jquery": "^0.4.9", + "jquery-form": "^4.2.2" + } + }, + "@abp/jquery-validation": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-validation/-/jquery-validation-0.4.9.tgz", + "integrity": "sha512-8C58G9BTYszW6E0EO6NYqXLEbABXt/yGlOqAFCkPiLVfUcoC6uARqkgIgNVnE99ZUeSmluNsYeCczP0Qb0yNzg==", + "requires": { + "@abp/jquery": "^0.4.9", + "jquery-validation": "^1.17.0" + } + }, + "@abp/jquery-validation-unobtrusive": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-0.4.9.tgz", + "integrity": "sha512-GR62QEPexX4uLcqF3y72V39nlx/70C7ubeaIxS1ZEq+0wGklwAiyq1p19qpB5Cuj2GJL+vFrIig5w+B79P2iAw==", + "requires": { + "@abp/jquery-validation": "^0.4.9", + "jquery-validation-unobtrusive": "^3.2.9" + } + }, + "@abp/lodash": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/lodash/-/lodash-0.4.9.tgz", + "integrity": "sha512-/itYbXQL145WigKIGpnyWgARml7QGie7xqhC1WZG5iUkdqLx+4YBXesdzGFykthDewiQNz8mB2gPk64d376AAw==", + "requires": { + "@abp/core": "^0.4.9", + "lodash": "^4.17.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + } + } + }, + "@abp/malihu-custom-scrollbar-plugin": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-0.5.1.tgz", + "integrity": "sha512-i9XorWsWcqb3tbbiwvE4OQCfXXJO38HlkQgvlwzxshB8xDcS9v/JL5fAAvM/Cr66fB2zybsrCseq9QcBXL+yCQ==", + "requires": { + "@abp/core": "^0.4.9", + "malihu-custom-scrollbar-plugin": "^3.1.5" + } + }, + "@abp/markdown-it": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/markdown-it/-/markdown-it-0.4.9.tgz", + "integrity": "sha512-leaY6Iom4zCW9RcZWIZbiYTM8NTmSYSa2Xiq7FW2MzhDCATXbcqV1+EqNAAFBERHAJoq0Hyz2AkIP510L+hz6Q==", + "requires": { + "@abp/core": "^0.4.9", + "markdown-it": "^8.4.1" + } + }, + "@abp/owl.carousel": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/owl.carousel/-/owl.carousel-0.4.9.tgz", + "integrity": "sha512-pgRcdbN1u6vaN6wOfNN9z6Id70va93kGTCBNVY43fJec1ghIq/evpBNp29ef5x9b0lcfe4DhmNb3CFaLbikr0w==", + "requires": { + "@abp/core": "^0.4.9", + "owl.carousel": "^2.3.4" + } + }, + "@abp/popper.js": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/popper.js/-/popper.js-0.5.1.tgz", + "integrity": "sha512-qS97hQQtG78mVPRvmZZtBb7Vu905NpThl9PN3jPWWDiVbOV2/d+BXCTRhTRbfdup3C5cmGdntjaGxfcxlxHt1Q==", + "requires": { + "@abp/core": "^0.4.9", + "popper.js": "^1.14.6" + } + }, + "@abp/prismjs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/prismjs/-/prismjs-0.5.1.tgz", + "integrity": "sha512-DxoidAVV8LmtgFonbzGJEfszQDUaHEQc+/bcJtyQCuv5l+uflVnpAH+6W8IAErt5N96a0RJbeV9ZBXjIhqOzpA==", + "requires": { + "@abp/core": "^0.4.9", + "prismjs": "^1.15.0" + } + }, + "@abp/select2": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/select2/-/select2-0.4.9.tgz", + "integrity": "sha512-AaJHWy9fkP/LqVkruZGfvzgdZXyT96/FpnflUpoNPXjuvVRptkJpd/BQiWjpyjS+qzuZ+m3X9dms0d0lAyFKYA==", + "requires": { + "@abp/core": "^0.4.9", + "select2": "^4.0.5" + } + }, + "@abp/sweetalert": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/sweetalert/-/sweetalert-0.4.9.tgz", + "integrity": "sha512-FaxtELo7Um/uasasbOGi1j1XuBtZ819mUo7+6pMSWj2CSAkg2A/RyT9NhYcX8oyGpv188W5CjZfJ1DM0bRH+pQ==", + "requires": { + "@abp/core": "^0.4.9", + "sweetalert": "^2.1.0" + } + }, + "@abp/timeago": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/timeago/-/timeago-0.4.9.tgz", + "integrity": "sha512-RsAyJCl+rEWQL0q0Nx/ijy+iOBYm5IC5Re6y4SQ1jYF/B4n88GM2PFy6kLrE+HHGl5Z5hkWr5OGXmFem50Y3Wg==", + "requires": { + "@abp/jquery": "^0.4.9", + "timeago": "^1.6.3" + } + }, + "@abp/toastr": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/toastr/-/toastr-0.4.9.tgz", + "integrity": "sha512-KjnETa1Og5EIMDw/pIxPoKLTABBcsxBN8BqwIG33ya2+BIRfAI7b0lEMoKK+qmwVwI5dkXZlKFGIUmPtb+zVCw==", + "requires": { + "@abp/jquery": "^0.4.9", + "toastr": "^2.1.4" + } + }, + "@abp/tui-editor": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/tui-editor/-/tui-editor-0.4.9.tgz", + "integrity": "sha512-sIXF/rNX2UyQiDCDmj8pv1FeqtAv9B0NquyBJwWDkaXWQsmJJ3YU/drcJHbzabsYg2tBjzRM/4Bb0+eXYR+Mnw==", + "requires": { + "@abp/codemirror": "^0.4.9", + "@abp/highlight.js": "^0.4.9", + "@abp/jquery": "^0.4.9", + "@abp/markdown-it": "^0.4.9", + "tui-editor": "^1.2.6" + } + }, + "almond": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz", + "integrity": "sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA=" + }, + "anchor-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/anchor-js/-/anchor-js-4.1.1.tgz", + "integrity": "sha512-c2Wl9F1X0C4jkYKLla1SNE2uI6xJrSKsRC7HCCg4yLNQ5sL5D+tDEWrjRaoTuTlMTqBCnF6kOuR3dx59Erxpvw==" + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, + "bootstrap": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz", + "integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "codemirror": { + "version": "5.40.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.40.2.tgz", + "integrity": "sha512-yoWuvEiD3v5vTwdoMc/wu/Ld6dh9K/yEiEBTKOPGM+/pN0gTAqFNtrLHv1IJ1UJvzFpNRvMi92XCi3+8/iIaEw==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "datatables.net": { + "version": "1.10.19", + "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.19.tgz", + "integrity": "sha512-+ljXcI6Pj3PTGy5pesp3E5Dr3x3AV45EZe0o1r0gKENN2gafBKXodVnk2ypKwl2tTmivjxbkiqoWnipTefyBTA==", + "requires": { + "jquery": ">=1.7" + } + }, + "datatables.net-bs4": { + "version": "1.10.19", + "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.19.tgz", + "integrity": "sha512-pgeP17w4aPR7HIxIwuJghfqXULjdg1K6xMUUKDyCERJRSNNK4MRToFfELtIsluLNN555YBK4Kx8nihX5/ZT1Fw==", + "requires": { + "datatables.net": "1.10.19", + "jquery": ">=1.7" + } + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "~1.1.9" + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "requires": { + "once": "~1.3.0" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eve": { + "version": "git://github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1", + "from": "git://github.com/adobe-webplatform/eve.git#eef80ed" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz", + "integrity": "sha1-QlFPhAFdE1bK9Rh5ad+yvBvaCCM=" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fancy-log": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "time-stamp": "^1.0.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "fined": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", + "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flagged-respawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" + }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "requires": { + "globule": "~0.1.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "requires": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "requires": { + "gaze": "^0.5.1" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "requires": { + "find-index": "^0.1.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "requires": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "requires": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } + } + }, + "glogg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz", + "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", + "requires": { + "sparkles": "^1.0.0" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "requires": { + "delegate": "^3.1.2" + } + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "requires": { + "natives": "^1.1.0" + } + }, + "gulp": { + "version": "3.9.1", + "resolved": "http://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "requires": { + "archy": "^1.0.0", + "chalk": "^1.0.0", + "deprecated": "^0.0.1", + "gulp-util": "^3.0.0", + "interpret": "^1.0.0", + "liftoff": "^2.1.0", + "minimist": "^1.1.0", + "orchestrator": "^0.3.0", + "pretty-hrtime": "^1.0.0", + "semver": "^4.1.0", + "tildify": "^1.0.0", + "v8flags": "^2.0.2", + "vinyl-fs": "^0.3.0" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "requires": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "requires": { + "glogg": "^1.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "highlight.js": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz", + "integrity": "sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "jquery": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", + "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" + }, + "jquery-form": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/jquery-form/-/jquery-form-4.2.2.tgz", + "integrity": "sha512-HJTef7DRBSg8ge/RNUw8rUTTtB3l8ozO0OhD16AzDl+eIXp4skgCqRTd9fYPsOzL+pN6+1B9wvbTLGjgikz8Tg==", + "requires": { + "jquery": ">=1.7.2" + } + }, + "jquery-mousewheel": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", + "integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU=" + }, + "jquery-validation": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.18.0.tgz", + "integrity": "sha512-+MK0pvoegfLrJnwtCU6tx305Vgp9HWevpmdVwDf5TthmINkn0wqqLD0bpa75EERlHsBBjMmza//ppx5ZQPnW3Q==", + "requires": { + "jquery": "^1.7 || ^2.0 || ^3.1" + } + }, + "jquery-validation-unobtrusive": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.11.tgz", + "integrity": "sha512-3FQPllaWdD+Aq55zJLGSW39+eXPDz1HhwAvrSwYi8zHQ8DVcu5IJ1HVeTiCl0BnCnrIBvfFU3zEB/DrGdcoRIQ==", + "requires": { + "jquery": ">=1.8", + "jquery-validation": ">=1.16" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "linkify-it": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", + "integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "requires": { + "lodash._root": "^3.0.0" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "malihu-custom-scrollbar-plugin": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz", + "integrity": "sha1-MQzsxeWUFaHCnp37XStuAdZqKe8=", + "requires": { + "jquery-mousewheel": ">=3.0.6" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "requires": { + "duplexer2": "0.0.2" + } + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natives": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", + "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "requires": { + "end-of-stream": "~0.1.5", + "sequencify": "~0.0.7", + "stream-consume": "~0.1.0" + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "owl.carousel": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/owl.carousel/-/owl.carousel-2.3.4.tgz", + "integrity": "sha512-JaDss9+feAvEW8KZppPSpllfposEzQiW+Ytt/Xm5t/3CTJ7YVmkh6RkWixoA2yXk2boIwedYxOvrrppIGzru9A==", + "requires": { + "jquery": ">=1.8.3" + } + }, + "pako": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.3.tgz", + "integrity": "sha1-X1FbDGci4ZgpIK6ABerLC3ynPM8=" + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + }, + "plantuml-encoder": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.2.5.tgz", + "integrity": "sha512-viV7Sz+BJNX/sC3iyebh2VfLyAZKuu3+JuBs2ISms8+zoTGwPqwk3/WEDw/zROmGAJ/xD4sNd8zsBw/YmTo7ng==", + "requires": { + "pako": "1.0.3", + "utf8-bytes": "0.0.1" + } + }, + "popper.js": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz", + "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "prismjs": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz", + "integrity": "sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA==", + "requires": { + "clipboard": "^2.0.0" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "promise-polyfill": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", + "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" + }, + "raphael": { + "version": "git+https://github.com/nhnent/raphael.git#78a6ed3ec269f33b6457b0ec66f8c3d1f2ed70e0", + "from": "git+https://github.com/nhnent/raphael.git#2.2.0-c", + "requires": { + "eve": "git://github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, + "resize-observer-polyfill": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz", + "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==" + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, + "select2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.5.tgz", + "integrity": "sha1-eqxQaSVhmFs007guxV4ib4lg1Ao=", + "requires": { + "almond": "~0.3.1", + "jquery-mousewheel": "~3.1.13" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "squire-rte": { + "version": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd", + "from": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-consume": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "requires": { + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "sweetalert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz", + "integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==", + "requires": { + "es6-object-assign": "^1.1.0", + "promise-polyfill": "^6.0.2" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "timeago": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/timeago/-/timeago-1.6.3.tgz", + "integrity": "sha512-x97d1X1KsNapWJTgCOOAy/59XagYu2WsDTAH/yvPsWi5bqtGbLPaVZBv3HZ3jTpakHR+JGGyrI9qC0yuvIAvnQ==", + "requires": { + "jquery": ">=1.2.3" + } + }, + "tiny-emitter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", + "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==" + }, + "to-mark": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/to-mark/-/to-mark-1.1.3.tgz", + "integrity": "sha512-Wai0j2IPk5vEsuPHgTBjK/xzGwUAmddUbUVLZgAvOiTZKEJwmVHRdEHO3yTta4LxgY4W9761sP1MkAZbYVXcig==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha1-i0O+ZPudDEFIcURvLbjoyk6V8YE=", + "requires": { + "jquery": ">=1.12.0" + } + }, + "tui-chart": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tui-chart/-/tui-chart-3.4.0.tgz", + "integrity": "sha512-gPIJ1SsPhISj/SlzysA9fkLJMlnPV1PLaUE+gxUioZaDtfoZ+TxSE+Vs1rOvoXUUmT/v5+qlH2iM2fkaLvDU0A==", + "requires": { + "babel-polyfill": "^6.26.0", + "raphael": "git+https://github.com/nhnent/raphael.git#78a6ed3ec269f33b6457b0ec66f8c3d1f2ed70e0", + "tui-code-snippet": "^1.4.0" + } + }, + "tui-code-snippet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tui-code-snippet/-/tui-code-snippet-1.4.0.tgz", + "integrity": "sha512-a7XzHRbRDi6Tt4lGcopq6ctQjVrzmnw9JMoTFqur5gczgtw5tmgUqXHjg8D9IonDkzZNq5gYLhkzykx4fmn+GA==" + }, + "tui-color-picker": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tui-color-picker/-/tui-color-picker-2.2.0.tgz", + "integrity": "sha512-oAzMxF19bDExbvv7jVWQBPlrJ8sO3jQe+1rHqKkM4FtpvtGNlJO/ty19LW6pk9CCi1y43cgoG3QUt41ctGmygQ==", + "requires": { + "tui-code-snippet": "^1.3.0" + } + }, + "tui-editor": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/tui-editor/-/tui-editor-1.2.6.tgz", + "integrity": "sha512-sVvs8yx3G1a/+YbR4VxzzfHFxPIPgattai+RDAHaUYeDkRhFPi3LeKN8A89jPyvUhyM8NhZWlhVd8ZTYx9ykNg==", + "requires": { + "codemirror": "^5.33.0", + "highlight.js": "^9.12.0", + "jquery": "^3.3.1", + "markdown-it": "^8.4.0", + "plantuml-encoder": "^1.2.5", + "resize-observer-polyfill": "^1.5.0", + "squire-rte": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd", + "to-mark": "^1.1.2", + "tui-chart": "^3.0.1", + "tui-code-snippet": "^1.3.0", + "tui-color-picker": "^2.2.0" + } + }, + "uc.micro": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz", + "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==" + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" + }, + "utf8-bytes": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/utf8-bytes/-/utf8-bytes-0.0.1.tgz", + "integrity": "sha1-EWsCVEjJtQAIHN+/H01sbDfYg30=" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "requires": { + "user-home": "^1.1.1" + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "requires": { + "defaults": "^1.0.0", + "glob-stream": "^3.1.5", + "glob-watcher": "^0.0.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "strip-bom": "^1.0.0", + "through2": "^0.6.1", + "vinyl": "^0.4.0" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css index 36bfe30a55..ad4f5adca0 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css @@ -600,7 +600,7 @@ span.code-arrow { .docs-page .docs-page-index { display: none; } } -@media (max-width: 767px) { +@media (max-width: 992px) { body { font-size: 14px; } .for-mobile { diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css index b8f9189bf2..524731f0ff 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css @@ -1 +1 @@ -body{position:relative;font-family:'PT Sans',sans-serif;background:url(../assets/tools/bg.jpg) center center no-repeat;background-attachment:fixed;}h1,h2,h3,h4,h5,h6{font-family:'PT Sans Caption',sans-serif;}h1{font-size:2.25em;margin:1.5rem 0 .75rem;}h2{font-size:1.75em;margin:1.5rem 0 .75rem;}h3{font-size:1.5em;margin:1.5rem 0 .75rem;}h4{font-size:1.25em;margin:1.5rem 0 .75rem;}h5{font-size:1em;margin:1.5rem 0 .75rem;}h6{font-size:1em;margin:1.5rem 0 .75rem;}img{max-width:100%;}.navbar{padding:1.75rem 2rem;}.nav-link{padding-left:1rem !important;padding-right:1rem !important;}.navbar-dark .navbar-nav .nav-link{color:#fff;}.text-success{color:#e90052 !important;}a.text-success:hover,a.text-success:focus{color:#e90052 !important;}.bg-success,.btn-success,.badge-success{background-color:#e90052 !important;border-color:#e90052 !important;}.bg-success{background-color:rgba(233,0,82,.8) !important;}.bg-blue,.btn-blue,.badge-blue{background-color:#03abed !important;border-color:#03abed !important;color:#fff;}.bg-blue:hover,.btn-blue:hover,.badge-blue:hover{background-color:#0095d0 !important;border-color:#0095d0 !important;color:#fff !important;}.btn:focus,.btn:active,.btn:visited,a:focus,a:active,a:visited{outline:none !important;box-shadow:none;}.text-primary{color:#38003c !important;}.bg-primary,.btn-primary,.badge-primary{background-color:#38003c !important;border-color:#38003c !important;}.bg-primary{background-color:rgba(56,0,60,.9) !important;}.btn-outline-primary{color:#38003c !important;border-color:#38003c !important;}.btn-outline-primary:hover{background-color:#38003c !important;color:#fff !important;}.dropdown-menu{padding:1rem 0;border-radius:.15rem;border:none;box-shadow:5px 5px 40px rgba(0,0,0,.3);}.dropdown-menu .dropdown-item{padding:.75rem 1.5rem;}#index-video{position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;z-index:-1;}.bg-gradient-horizontal{background:#fff;}@media(min-width:480px){.bg-gradient-horizontal{background:#fff;background:-moz-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:-webkit-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:linear-gradient(to right,#fff 50%,#f2f2f2 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#f2f2f2',GradientType=1);}}.bg-transparency{background:rgba(255,255,255,.9);}.bg-light{background:#eee;}.for-mobile{display:none;}.for-desktop{display:inline-block;}.breadcrumb{background:none;font-size:.85em;border-radius:0;border-bottom:1px solid #f5f5f5;margin:0 -15px;padding:.5rem 0;text-align:center;display:block;}.breadcrumb .breadcrumb-item+.breadcrumb-item{padding-left:.2rem;}.breadcrumb .breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.4rem;color:#eee;content:"|";}.breadcrumb .breadcrumb-item{color:#eee;display:inline-block;}.breadcrumb .breadcrumb-item a{color:#aaa;}.close{font-weight:300;}hr{margin-top:2rem;margin-bottom:2.5rem;border-top:1px solid rgba(0,0,0,.05);}span.with-br-name{font-size:.75em;}span.br-name{display:block;font-size:1.25em;}span.br-name-1{display:block;font-size:1em;}.btn-fifty{display:flex;}.btn-fifty .btn{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%;}.p-responsive{padding:120px 0;}.global-header{display:none;}.global-header .navbar{background:rgba(255,255,255,.2);}.global-header .navbar .products-link{border:1px solid rgba(255,255,255,.75);border-radius:.2rem;margin:0 10px;padding-top:.36rem;padding-bottom:.36rem;}.global-header .navbar .search-item{position:relative;}.global-header .navbar .search-item input.form-control{background:none;border:1px solid rgba(255,255,255,.25);border-radius:.2rem;color:#fff;padding-left:2.5rem;min-width:280px;}.global-header .navbar .search-item input.form-control::-webkit-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control::-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-ms-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item .btn-search{position:absolute;top:-2px;left:-1px;background:none;}header .btn{background:#fff;}header .btn.btn-login,header .btn.btn-logout{border:2px solid #fff;color:#fff;background:transparent;margin-right:6px;}header .btn.btn-login:hover,header .btn.btn-logout:hover{background:#fff;color:#e90052;}.product-header{font-size:1.1rem;}.product-header .navbar-brand{font-size:1.75rem;}.home-logo{width:120px;}.jumbotron-logo{width:240px;margin-bottom:40px;}.forkme{position:fixed;bottom:0;right:0;}.footer-logo{width:140px;}.jumbotron{background:#006bf0;background:-moz-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:-webkit-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:linear-gradient(to right,rgba(56,0,60,.9) 0%,rgba(185,0,74,.78) 100%);margin-top:-120px;border-radius:0;margin-bottom:0;height:90vh;}.jumbotron.jumbocover{padding:120px 0 20px;height:auto;}.jumbotron>.row{height:calc(90vh - 120px);}.jumbotron .abp-version{position:absolute;font-size:11px;right:1px;top:-2px;padding:1px 4px 0;display:inline-block;color:#fff;background:rgba(233,3,82,.7);border-radius:3px;opacity:.8;}.jumbotron .desc-span{font-size:1.4em;font-style:italic;opacity:.7;}.section-with-logos img{margin:25px;max-height:50px;transition:.4s;opacity:.6;-webkit-filter:grayscale(60%);filter:grayscale(60%);}.section-with-logos img:hover{opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}img.subsection-icon{width:64px;height:64px;}.toggle-row{display:none;}.btn-toggle .lessText{display:none;}.btn-toggle .moreText{display:block;}.btn-toggle.less .lessText{display:block;}.btn-toggle.less .moreText{display:none;}.abp-browser{margin:3rem 0 1rem;text-align:left;border-radius:6px;overflow:hidden;}.abp-browser .browser-container{border:1px solid #eee;}.abp-browser .browser-row{padding:4px 10px;background:#e5e5e5;}.abp-browser .browser-row:after{content:"";display:table;clear:both;}.abp-browser .browser-dot{margin-top:2px;margin-right:2px;height:12px;width:12px;background-color:#bbb;border-radius:50%;display:inline-block;}.abp-browser .abp-browser input[type=text]{width:100%;border-radius:3px;border:none;background-color:#fff;margin-top:-8px;height:25px;color:#666;padding:5px;}.abp-browser .browser-bar{width:17px;height:3px;background-color:#aaa;margin:3px 0;display:block;}.abp-browser .browser-content{padding:2rem;background:#f5f5f5;}.abp-browser .bg-primary,.abp-browser .btn-primary,.abp-browser .badge-primary{background-color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary{color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary:hover{background-color:#007bff !important;color:#fff !important;}span.code-arrow{padding:52px 0 18px;display:block;font-size:40px;}.docs-page{background:#f5f7f9;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1.5rem;position:relative;width:270px;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;top:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:calc(100vh - 190px);overflow:hidden;overflow-y:auto;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1.25rem 1.5rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search input.form-control{background:none;border-radius:.2rem;padding-left:2.5rem;width:100%;background:#eeeff2;border:0;font-size:.85em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{position:absolute;top:-5px;left:22px;background:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.913em;list-style:none;padding:0 0 0 20px;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label{margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle{transition:.3s;display:inline-block;width:18px;height:18px;text-align:center;padding:0;line-height:normal;border-radius:50%;margin-right:4px;position:absolute;left:0;top:8px;cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle img{width:14px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle:not(.last-link).opened{transform:rotate(180deg);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#101010;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li label.tree-toggle{top:6px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#38003c;font-weight:bold;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:130px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;font-size:1.2rem;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-text-field{padding:3rem;}.docs-page .docs-page-index{position:relative;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;max-width:270px;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.95em;margin-left:18px;border-left:1px solid #e5e5e5;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:.2rem 0 .2rem 1rem;color:#aaa;line-height:1.1;position:relative;border-left:3px solid transparent;border-radius:0;margin-left:-2px;margin-top:2px;margin-bottom:2px;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{background:none;color:#38003b;border-color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors>.navbar{margin-left:-18px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .docs-inner-anchors .inner-title{padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:underline;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1200px){.container{max-width:1180px;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;height:calc(100vh - 72px);overflow:hidden;overflow-y:auto;position:fixed;top:72px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{top:-14px;left:-2px;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;display:block;margin-right:0;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}.jumbotron{height:calc(100vh + 120px);}.jumbotron.jumbocover{height:auto;padding:160px 0 20px;}.jumbotron hr{display:none;}.jumbotron .btn{margin-bottom:0 !important;}.jumbotron .jumbotron-logo{margin-bottom:0;width:180px;height:62px;margin-top:-30px;}.jumbotron .jlogo-wrapper{height:62px;}}.vs-blog{margin-top:-88px !important;}.abp-account-container{max-width:400px;margin:0 auto;margin-top:-88px !important;}body{background-size:cover;} \ No newline at end of file +body{position:relative;font-family:'PT Sans',sans-serif;background:url(../assets/tools/bg.jpg) center center no-repeat;background-attachment:fixed;}h1,h2,h3,h4,h5,h6{font-family:'PT Sans Caption',sans-serif;}h1{font-size:2.25em;margin:1.5rem 0 .75rem;}h2{font-size:1.75em;margin:1.5rem 0 .75rem;}h3{font-size:1.5em;margin:1.5rem 0 .75rem;}h4{font-size:1.25em;margin:1.5rem 0 .75rem;}h5{font-size:1em;margin:1.5rem 0 .75rem;}h6{font-size:1em;margin:1.5rem 0 .75rem;}img{max-width:100%;}.navbar{padding:1.75rem 2rem;}.nav-link{padding-left:1rem !important;padding-right:1rem !important;}.navbar-dark .navbar-nav .nav-link{color:#fff;}.text-success{color:#e90052 !important;}a.text-success:hover,a.text-success:focus{color:#e90052 !important;}.bg-success,.btn-success,.badge-success{background-color:#e90052 !important;border-color:#e90052 !important;}.bg-success{background-color:rgba(233,0,82,.8) !important;}.bg-blue,.btn-blue,.badge-blue{background-color:#03abed !important;border-color:#03abed !important;color:#fff;}.bg-blue:hover,.btn-blue:hover,.badge-blue:hover{background-color:#0095d0 !important;border-color:#0095d0 !important;color:#fff !important;}.btn:focus,.btn:active,.btn:visited,a:focus,a:active,a:visited{outline:none !important;box-shadow:none;}.text-primary{color:#38003c !important;}.bg-primary,.btn-primary,.badge-primary{background-color:#38003c !important;border-color:#38003c !important;}.bg-primary{background-color:rgba(56,0,60,.9) !important;}.btn-outline-primary{color:#38003c !important;border-color:#38003c !important;}.btn-outline-primary:hover{background-color:#38003c !important;color:#fff !important;}.dropdown-menu{padding:1rem 0;border-radius:.15rem;border:none;box-shadow:5px 5px 40px rgba(0,0,0,.3);}.dropdown-menu .dropdown-item{padding:.75rem 1.5rem;}#index-video{position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;z-index:-1;}.bg-gradient-horizontal{background:#fff;}@media(min-width:480px){.bg-gradient-horizontal{background:#fff;background:-moz-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:-webkit-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:linear-gradient(to right,#fff 50%,#f2f2f2 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#f2f2f2',GradientType=1);}}.bg-transparency{background:rgba(255,255,255,.9);}.bg-light{background:#eee;}.for-mobile{display:none;}.for-desktop{display:inline-block;}.breadcrumb{background:none;font-size:.85em;border-radius:0;border-bottom:1px solid #f5f5f5;margin:0 -15px;padding:.5rem 0;text-align:center;display:block;}.breadcrumb .breadcrumb-item+.breadcrumb-item{padding-left:.2rem;}.breadcrumb .breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.4rem;color:#eee;content:"|";}.breadcrumb .breadcrumb-item{color:#eee;display:inline-block;}.breadcrumb .breadcrumb-item a{color:#aaa;}.close{font-weight:300;}hr{margin-top:2rem;margin-bottom:2.5rem;border-top:1px solid rgba(0,0,0,.05);}span.with-br-name{font-size:.75em;}span.br-name{display:block;font-size:1.25em;}span.br-name-1{display:block;font-size:1em;}.btn-fifty{display:flex;}.btn-fifty .btn{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%;}.p-responsive{padding:120px 0;}.global-header{display:none;}.global-header .navbar{background:rgba(255,255,255,.2);}.global-header .navbar .products-link{border:1px solid rgba(255,255,255,.75);border-radius:.2rem;margin:0 10px;padding-top:.36rem;padding-bottom:.36rem;}.global-header .navbar .search-item{position:relative;}.global-header .navbar .search-item input.form-control{background:none;border:1px solid rgba(255,255,255,.25);border-radius:.2rem;color:#fff;padding-left:2.5rem;min-width:280px;}.global-header .navbar .search-item input.form-control::-webkit-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control::-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-ms-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item .btn-search{position:absolute;top:-2px;left:-1px;background:none;}header .btn{background:#fff;}header .btn.btn-login,header .btn.btn-logout{border:2px solid #fff;color:#fff;background:transparent;margin-right:6px;}header .btn.btn-login:hover,header .btn.btn-logout:hover{background:#fff;color:#e90052;}.product-header{font-size:1.1rem;}.product-header .navbar-brand{font-size:1.75rem;}.home-logo{width:120px;}.jumbotron-logo{width:240px;margin-bottom:40px;}.forkme{position:fixed;bottom:0;right:0;}.footer-logo{width:140px;}.jumbotron{background:#006bf0;background:-moz-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:-webkit-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:linear-gradient(to right,rgba(56,0,60,.9) 0%,rgba(185,0,74,.78) 100%);margin-top:-120px;border-radius:0;margin-bottom:0;height:90vh;}.jumbotron.jumbocover{padding:120px 0 20px;height:auto;}.jumbotron>.row{height:calc(90vh - 120px);}.jumbotron .abp-version{position:absolute;font-size:11px;right:1px;top:-2px;padding:1px 4px 0;display:inline-block;color:#fff;background:rgba(233,3,82,.7);border-radius:3px;opacity:.8;}.jumbotron .desc-span{font-size:1.4em;font-style:italic;opacity:.7;}.section-with-logos img{margin:25px;max-height:50px;transition:.4s;opacity:.6;-webkit-filter:grayscale(60%);filter:grayscale(60%);}.section-with-logos img:hover{opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}img.subsection-icon{width:64px;height:64px;}.toggle-row{display:none;}.btn-toggle .lessText{display:none;}.btn-toggle .moreText{display:block;}.btn-toggle.less .lessText{display:block;}.btn-toggle.less .moreText{display:none;}.abp-browser{margin:3rem 0 1rem;text-align:left;border-radius:6px;overflow:hidden;}.abp-browser .browser-container{border:1px solid #eee;}.abp-browser .browser-row{padding:4px 10px;background:#e5e5e5;}.abp-browser .browser-row:after{content:"";display:table;clear:both;}.abp-browser .browser-dot{margin-top:2px;margin-right:2px;height:12px;width:12px;background-color:#bbb;border-radius:50%;display:inline-block;}.abp-browser .abp-browser input[type=text]{width:100%;border-radius:3px;border:none;background-color:#fff;margin-top:-8px;height:25px;color:#666;padding:5px;}.abp-browser .browser-bar{width:17px;height:3px;background-color:#aaa;margin:3px 0;display:block;}.abp-browser .browser-content{padding:2rem;background:#f5f5f5;}.abp-browser .bg-primary,.abp-browser .btn-primary,.abp-browser .badge-primary{background-color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary{color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary:hover{background-color:#007bff !important;color:#fff !important;}span.code-arrow{padding:52px 0 18px;display:block;font-size:40px;}.docs-page{background:#f5f7f9;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1.5rem;position:relative;width:270px;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;top:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:calc(100vh - 190px);overflow:hidden;overflow-y:auto;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1.25rem 1.5rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search input.form-control{background:none;border-radius:.2rem;padding-left:2.5rem;width:100%;background:#eeeff2;border:0;font-size:.85em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{position:absolute;top:-5px;left:22px;background:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.913em;list-style:none;padding:0 0 0 20px;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label{margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle{transition:.3s;display:inline-block;width:18px;height:18px;text-align:center;padding:0;line-height:normal;border-radius:50%;margin-right:4px;position:absolute;left:0;top:8px;cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle img{width:14px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle:not(.last-link).opened{transform:rotate(180deg);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#101010;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li label.tree-toggle{top:6px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#38003c;font-weight:bold;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:130px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;font-size:1.2rem;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-text-field{padding:3rem;}.docs-page .docs-page-index{position:relative;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;max-width:270px;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.95em;margin-left:18px;border-left:1px solid #e5e5e5;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:.2rem 0 .2rem 1rem;color:#aaa;line-height:1.1;position:relative;border-left:3px solid transparent;border-radius:0;margin-left:-2px;margin-top:2px;margin-bottom:2px;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{background:none;color:#38003b;border-color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors>.navbar{margin-left:-18px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .docs-inner-anchors .inner-title{padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:underline;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1200px){.container{max-width:1180px;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;height:calc(100vh - 72px);overflow:hidden;overflow-y:auto;position:fixed;top:72px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{top:-14px;left:-2px;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;display:block;margin-right:0;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}@media(max-width:992px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}.jumbotron{height:calc(100vh + 120px);}.jumbotron.jumbocover{height:auto;padding:160px 0 20px;}.jumbotron hr{display:none;}.jumbotron .btn{margin-bottom:0 !important;}.jumbotron .jumbotron-logo{margin-bottom:0;width:180px;height:62px;margin-top:-30px;}.jumbotron .jlogo-wrapper{height:62px;}}.vs-blog{margin-top:-88px !important;}.abp-account-container{max-width:400px;margin:0 auto;margin-top:-88px !important;}body{background-size:cover;} \ No newline at end of file diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss index 07bfa1b354..4d9cb4a995 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss @@ -3,7 +3,7 @@ @import "footer.scss"; @import "home.scss"; @import "docs.scss"; -@media (max-width: 767px) { +@media (max-width: 992px) { @import "responsive.scss"; } diff --git a/abp_io/src/Volo.Utils.SolutionTemplating/Volo.Utils.SolutionTemplating.csproj b/abp_io/src/Volo.Utils.SolutionTemplating/Volo.Utils.SolutionTemplating.csproj index f445e989d1..254d8b65c5 100644 --- a/abp_io/src/Volo.Utils.SolutionTemplating/Volo.Utils.SolutionTemplating.csproj +++ b/abp_io/src/Volo.Utils.SolutionTemplating/Volo.Utils.SolutionTemplating.csproj @@ -15,9 +15,9 @@ - + - + diff --git a/build-all.ps1 b/build-all.ps1 index 935cfeb8a9..5d800ebdf9 100644 --- a/build-all.ps1 +++ b/build-all.ps1 @@ -20,7 +20,8 @@ $solutionPaths = ( "abp_io", "templates/module", "templates/service", - "templates/mvc" + "templates/mvc", + "samples/MicroserviceDemo" ) # Build all solutions @@ -31,6 +32,7 @@ foreach ($solutionPath in $solutionPaths) { dotnet build if (-Not $?) { Write-Host ("Build failed for the solution: " + $solutionPath) + Set-Location $rootFolder exit $LASTEXITCODE } } diff --git a/build/build.ps1 b/build/build.ps1 deleted file mode 100644 index c594ce2280..0000000000 --- a/build/build.ps1 +++ /dev/null @@ -1,50 +0,0 @@ -# COMMON PATHS - -$buildFolder = (Get-Item -Path "./" -Verbose).FullName -$slnFolder = Join-Path $buildFolder "../" -$outputFolder = Join-Path $buildFolder "outputs" -$abpDeskFolder = Join-Path $slnFolder "src/AbpDesk" -$abpDeskWebFolder = Join-Path $abpDeskFolder "AbpDesk.Web.Mvc" - -## CLEAR ###################################################################### - -Remove-Item $outputFolder -Force -Recurse -New-Item -Path $outputFolder -ItemType Directory - -## RESTORE NUGET PACKAGES ##################################################### - -Set-Location $slnFolder -dotnet restore - -## PUBLISH ASPDESK WEB ######################################################## - -Set-Location $abpDeskWebFolder -dotnet publish --output (Join-Path $outputFolder "AbpDesk/Web") - -New-Item -Path (Join-Path $outputFolder "AbpDesk/Web/PlugIns") -ItemType Directory -Copy-Item (Join-Path $abpDeskFolder "Web_PlugIns/*") (Join-Path $outputFolder "AbpDesk/Web/PlugIns/") - -## PUBLISH IDENTITY HTTP API HOST ############################################# - -Set-Location (Join-Path $slnFolder "src/Volo.Abp.Identity.HttpApi.Host") -dotnet publish --output (Join-Path $outputFolder "AbpIdentity/HttpApiHost") - -## CREATE DOCKER IMAGES ####################################################### - -Set-Location (Join-Path $outputFolder "AbpDesk/Web") - -docker rmi abpdesk/web -f -docker build -t abpdesk/web . - -Set-Location (Join-Path $outputFolder "AbpIdentity/HttpApiHost") - -docker rmi abpidentity/httpapihost -f -docker build -t abpidentity/httpapihost . - -## DOCKER COMPOSE FILES ####################################################### - -Copy-Item (Join-Path $slnFolder "docker/*.*") $outputFolder - -## FINALIZE ################################################################### - -Set-Location $outputFolder \ No newline at end of file diff --git a/common.props b/common.props index 15df803252..380276a7e1 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 0.9.0 + 0.14.0 $(NoWarn);CS1591 https://abp.io/assets/abp_nupkg.png https://abp.io @@ -11,7 +11,7 @@ - + \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 314feb5709..0000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,28 +0,0 @@ -version: '2' - -services: - - mongodb: - image: tutum/mongodb - environment: - - AUTH=no - ports: - - "27017:27017" - - "28017:28017" - - abpidentity_httpapihost: - image: abpidentity/httpapihost - environment: - - ASPNETCORE_ENVIRONMENT=Staging - - abpdesk_web: - image: abpdesk/web - environment: - - ASPNETCORE_ENVIRONMENT=Staging - - load_balancer: - image: haproxy:1.7.1 - volumes: - - "./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg" - ports: - - "9005:8080" \ No newline at end of file diff --git a/docker/down.ps1 b/docker/down.ps1 deleted file mode 100644 index 508a7c4d74..0000000000 --- a/docker/down.ps1 +++ /dev/null @@ -1 +0,0 @@ -docker-compose down -v --rmi local \ No newline at end of file diff --git a/docker/haproxy.cfg b/docker/haproxy.cfg deleted file mode 100644 index 276ad980c8..0000000000 --- a/docker/haproxy.cfg +++ /dev/null @@ -1,18 +0,0 @@ -global - maxconn 4096 - -defaults - mode http - timeout connect 5s - timeout client 50s - timeout server 50s - -listen http-in - bind *:8080 - - server web-1 outputs_abpdesk_web_1:80 - server web-2 outputs_abpdesk_web_2:80 - - stats enable - stats uri /haproxy - stats refresh 1s \ No newline at end of file diff --git a/docker/up.ps1 b/docker/up.ps1 deleted file mode 100644 index 49ee1ee616..0000000000 --- a/docker/up.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -docker rm $(docker ps -aq) -docker-compose up -d mongodb -docker-compose up -d abpidentity_httpapihost -docker-compose up -d abpdesk_web -sleep 2 -docker-compose scale abpdesk_web=2 -sleep 2 -docker-compose up -d load_balancer \ No newline at end of file diff --git a/docs/en/AspNetCore/Auto-API-Controllers.md b/docs/en/AspNetCore/Auto-API-Controllers.md new file mode 100644 index 0000000000..48567b6919 --- /dev/null +++ b/docs/en/AspNetCore/Auto-API-Controllers.md @@ -0,0 +1,138 @@ +# Auto API Controllers + +Once you create an [application service](Application-Services.md), you generally want to create an API controller to expose this service as an HTTP (REST) API endpoint. A typical API controller does nothing but redirects method calls to the application service and configures the REST API using attributes like [HttpGet], [HttpPost], [Route]... etc. + +ABP can **automagically** configures your application services as MVC API Controllers by convention. Most of time you don't care about its detailed configuration, but it's possible fully customize it. + +## Configuration + +Basic configuration is simple. Just configure `AbpAspNetCoreMvcOptions` and use `ConventionalControllers.Create` method as shown below: + +````csharp +[DependsOn(BookStoreApplicationModule)] +public class BookStoreWebModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); + }); + } +} +```` + +This example code configures all the application services in the assembly containing the class `BookStoreApplicationModule`. The figure below shows the resulting API on the [Swagger UI](https://swagger.io/tools/swagger-ui/). + +![bookstore-apis](../images/bookstore-apis.png) + +### Examples + +Some example method names and the corresponding routes calculated by convention: + +| Service Method Name | HTTP Method | Route | +| ----------------------------------------------------- | ----------- | -------------------------- | +| GetAsync(Guid id) | GET | /api/app/book/{id} | +| GetListAsync() | GET | /api/app/book | +| CreateAsync(CreateBookDto input) | POST | /api/app/book | +| UpdateAsync(Guid id, UpdateBookDto input) | PUT | /api/app/book/{id} | +| DeleteAsync(Guid id) | DELETE | /api/app/book/{id} | +| GetEditorsAsync(Guid id) | GET | /api/app/book/{id}/editors | +| CreateEditorAsync(Guid id, BookEditorCreateDto input) | POST | /api/app/book/{id}/editor | + +### HTTP Method + +ABP uses a naming convention while determining the HTTP method for a service method (action): + +- **Get**: Used if the method name starts with 'GetList', 'GetAll' or 'Get'. +- **Put**: Used if the method name starts with 'Put' or 'Update'. +- **Delete**: Used if the method name starts with 'Delete' or 'Remove'. +- **Post**: Used if the method name starts with 'Create', 'Add', 'Insert' or 'Post'. +- **Patch**: Used if the method name starts with 'Patch'. +- Otherwise, **Post** is used **by default**. + +If you need to customize HTTP method for a particular method, then you can use one of the standard ASP.NET Core attributes ([HttpPost], [HttpGet], [HttpPut]... etc.). This requires to add [Microsoft.AspNetCore.Mvc.Core](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Core) nuget package to your project that contains the service. + +### Route + +Route is calculated based on some conventions: + +* It always starts with '**/api**'. +* Continues with a **route path**. Default value is '**/app**' and can be configured as like below: + +````csharp +Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.RootPath = "volosoft/book-store"; + }); +}); +```` + +Then the route for getting a book will be '**/api/volosoft/book-store/book/{id}**'. This sample uses two-level root path, but you generally use a single level depth. + +* Continues with the **normalized controller/service name**. Normalization removes 'AppService', 'ApplicationService' and 'Service' postfixes and converts it to **camelCase**. If your application service class name is 'BookAppService' then it becomes only '/book'. + * If you want to customize naming, then set the `UrlControllerNameNormalizer` option. It's a func delegate which allows you to determine the name per controller/service. +* If the method has an '**id**' parameter then it adds '**/{id}**' ro the route. +* Then it adds the action name if necessary. Action name is obtained from the method name on the service and normalized by; + * Removing '**Async**' postfix. If the method name is 'GetPhonesAsync' then it becomes 'GetPhones'. + * Removing **HTTP method prefix**. 'GetList', 'GetAll', 'Get', 'Put', 'Update', 'Delete', 'Remove', 'Create', 'Add', 'Insert', 'Post' and 'Patch' prefixes are removed based on the selected HTTP method. So, 'GetPhones' becomes 'Phones' since 'Get' prefix is a duplicate for a GET request. + * Converting the result to **camelCase**. + * If the resulting action name is **empty** then it's not added to the route. If it's not empty, it's added to the route (like '/phones'). For 'GetAllAsync' method name it will be empty, for 'GetPhonesAsync' method name is will be 'phones'. + * Normalization can be customized by setting the `UrlActionNameNormalizer` option. It's an action delegate that is called for every method. +* If there is another parameter with 'Id' postfix, then it's also added to the route as the final route segment (like '/phoneId'). + +## Service Selection + +Creating conventional HTTP API controllers are not unique to application services actually. + +### IRemoteService Interface + +If a class implements the `IRemoteService` interface then it's automatically selected to be a conventional API controller. Since application services inherently implement it, they are considered as natural API controllers. + +### RemoteService Attribute + +`RemoteService` attribute can be used to mark a class as a remote service or disable for a particular class that inherently implements the `IRemoteService` interface. Example: + +````csharp +[RemoteService(IsEnabled = false)] //or simply [RemoteService(false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +### TypePredicate Option + +You can further filter classes to become an API controller by providing the `TypePedicate` option: + +````csharp +services.Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.TypePredicate = type => { return true; }; + }); +}); +```` + +Instead of returning `true` for every type, you can check it and return `false` if you don't want to expose this type as an API controller. + +## API Explorer + +API Exploring a service that makes possible to investigate API structure by the clients. Swagger uses it to create a documentation and test UI for an endpoint. + +API Explorer is automatically enabled for conventional HTTP API controllers by default. Use `RemoteService` attribute to control it per class or method level. Example: + +````csharp +[RemoteService(IsMetadataEnabled = false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +Disabled `IsMetadataEnabled` which hides this service from API explorer and it will not be discoverable. However, it still can be usable for the clients know the exact API path/route. \ No newline at end of file diff --git a/docs/en/AspNetCore/Bundling-Minification.md b/docs/en/AspNetCore/Bundling-Minification.md index b8d70d8624..7170690ef3 100644 --- a/docs/en/AspNetCore/Bundling-Minification.md +++ b/docs/en/AspNetCore/Bundling-Minification.md @@ -1,5 +1,5 @@ -## ASP.NET Core MVC Bundling & Minification +# ASP.NET Core MVC Bundling & Minification There are many ways of bundling & minification of client side resources (JavaScript and CSS files). Most common ways are: @@ -8,7 +8,7 @@ There are many ways of bundling & minification of client side resources (JavaScr ABP offers a simple, dynamic, powerful, modular and built-in way. -### Volo.Abp.AspNetCore.Mvc.UI.Bundling Package +## Volo.Abp.AspNetCore.Mvc.UI.Bundling Package > This package is already installed by default with the startup templates. So, most of the time, you don't need to install it manually. @@ -34,7 +34,7 @@ namespace MyCompany.MyProject } ```` -### Razor Bundling Tag Helpers +## Razor Bundling Tag Helpers The simplest way of creating a bundle is to use `abp-script-bundle` or `abp-style-bundle` tag helpers. Example: @@ -54,7 +54,7 @@ This bundle defines a style bundle with a **unique name**: `MyGlobalBundle`. It' * The bundle files may be **physical** files or [**virtual/embedded** files](../Virtual-File-System.md). * ABP automatically adds **version query string** to the bundle file URL to prevent browsers from caching when the bundle is being updated. (like ?_v=67872834243042 - generated from last change date of the related files). The versioning works even if the bundle files are individually added to the page (on the development environment). -#### Importing The Bundling Tag Helpers +### Importing The Bundling Tag Helpers > This is already imported by default with the startup templates. So, most of the time, you don't need to add it manually. @@ -64,7 +64,7 @@ In order to use bundle tag helpers, you need to add it into your `_ViewImports.c @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling ```` -#### Unnamed Bundles +### Unnamed Bundles The `name` is **optional** for the razor bundle tag helpers. If you don't define a name, it's automatically **calculated** based on the used bundle file names (they are **concatenated** and **hashed**). Example: @@ -90,7 +90,7 @@ Advantages of **named** bundles: * Other **modules can contribute** to the bundle by its name (see the sections below). -#### Single File +### Single File If you need to just add a single file to the page, you can use the `abp-script` or `abp-style` tag without a wrapping in the `abp-script-bundle` or `abp-style-bundle` tag. Example: @@ -100,11 +100,11 @@ If you need to just add a single file to the page, you can use the `abp-script` The bundle name will be *scripts.my-scripts* for the example above ("/" is replaced by "."). All bundling features are work as expected for single file bundles too. -### Bundling Options +## Bundling Options If you need to use same bundle in **multiple pages** or want to use some more **powerful features**, you can configure bundles **by code** in your [module](../Module-Development-Basics.md) class. -#### Creating A New Bundle +### Creating A New Bundle Example usage: @@ -141,10 +141,9 @@ After defining such a bundle, it can be included into a page using the same tag This time, no file defined in the tag helper definition because the bundle files are defined by the code. -#### Configuring An Existing Bundle +### Configuring An Existing Bundle -ABP supports [modularity](../Module-Development-Basics.md) for bundling as well. A module can modify an existing bundle that is created by a dependant module. -Example: +ABP supports [modularity](../Module-Development-Basics.md) for bundling as well. A module can modify an existing bundle that is created by a dependant module. Example: ````C# [DependsOn(typeof(MyWebModule))] @@ -168,7 +167,7 @@ public class MyWebExtensionModule : AbpModule > It's not possible to configure unnamed bundle tag helpers by code, because their name are not known at the development time. It's suggested to always use a name for a bundle tag helper. -### Bundle Contributors +## Bundle Contributors Adding files to an existing bundle seems useful. What if you need to **replace** a file in the bundle or you want to **conditionally** add files? Defining a bundle contributor provides extra power for such cases. @@ -187,7 +186,7 @@ public class MyExtensionGlobalStyleContributor : BundleContributor } ```` -Then you can use this contributor as below: +Then you can use this contributor as like below: ````C# services.Configure(options => @@ -200,8 +199,9 @@ services.Configure(options => }); ```` -Contributors can also be used in the bundle tag helpers. -Example: +> You can also add contributors while creating a new bundle. + +Contributors can also be used in the bundle tag helpers. Example: ````xml @@ -213,7 +213,7 @@ Example: `abp-style` and `abp-script` tags can get `type` attributes (instead of `src` attributes) as shown in this sample. When you add a bundle contributor, its dependencies are also automatically added to the bundle. -#### Contributor Dependencies +### Contributor Dependencies A bundle contributor can have one or more dependencies to other contributors. Example: @@ -230,11 +230,40 @@ When a bundle contributor is added, its dependencies are **automatically and rec Creating contributors and defining dependencies is a way of organizing bundle creation across different modules. -#### Accessing to the IServiceProvider +### Contributor Extensions + +In some advanced scenarios, you may want to do some additional configuration whenever a bundle contributor is used. Contributor extensions works seamlessly when the extended contributor is used. + +The example below adds some styles for prism.js library: + +````csharp +public class MyPrismjsStyleExtension : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/prismjs/plugins/toolbar/prism-toolbar.css"); + } +} +```` + +Then you can configure `BundleContributorOptions` to extend existing `PrismjsStyleBundleContributor`. + +````csharp +Configure(options => +{ + options + .Extensions() + .Add(); +}); +```` + +Whenever `PrismjsStyleBundleContributor` is added into a bundle, `MyPrismjsStyleExtension` will also be automatically added. + +### Accessing to the IServiceProvider While it is rarely needed, `BundleConfigurationContext` has a `ServiceProvider` property that you can resolve service dependencies inside the `ConfigureBundle` method. -#### Standard Package Contributors +### Standard Package Contributors Adding a specific NPM package resource (js, css files) into a bundle is pretty straight forward for that package. For example you always add the `bootstrap.css` file for the bootstrap NPM package. @@ -255,7 +284,7 @@ Using the built-in contributors for standard packages; * Prevents multiple modules adding the **duplicate the files**. * Manages **dependencies recursively** (adds dependencies of dependencies, if necessary). -##### Volo.Abp.AspNetCore.Mvc.UI.Packages Package +#### Volo.Abp.AspNetCore.Mvc.UI.Packages Package > This package is already installed by default in the startup templates. So, most of the time, you don't need to install it manually. @@ -282,7 +311,7 @@ namespace MyCompany.MyProject } ```` -#### Bundle Inheritance +### Bundle Inheritance In some specific cases, it may be needed to create a **new** bundle **inherited** from other bundle(s). Inheriting from a bundle (recursively) inherits all files/contributors of that bundle. Then the derived bundle can add or modify files/contributors **without modifying** the original bundle. Example: @@ -302,11 +331,11 @@ services.Configure(options => }); ```` -### Themes +## Themes Themes uses the standard package contributors to add library resources to page layouts. Themes may also define some standard/global bundles, so any module can contribute to these standard/global bundles. See the [theming documentation](Theming.md) for more. -### Best Practices & Suggestions +## Best Practices & Suggestions It's suggested to define multiple bundles for an application, each one is used for different purposes. @@ -317,7 +346,7 @@ It's suggested to define multiple bundles for an application, each one is used f Establish a balance between performance, network bandwidth usage and count of many bundles. -### See Also +## See Also * [Client Side Package Management](Client-Side-Package-Management.md) * [Theming](Theming.md) diff --git a/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md b/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md new file mode 100644 index 0000000000..0b0667dd0d --- /dev/null +++ b/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md @@ -0,0 +1,165 @@ +# Dynamic C# API Clients + +ABP can dynamically create C# API client proxies to call remote HTTP services (REST APIs). In this way, you don't need to deal with `HttpClient` and other low level HTTP features to call remote services and get results. + +## Service Interface + +Your service/controller should implement an interface that is shared between the server and the client. So, first define a service interface in a shared library project. Example: + +````csharp +public interface IBookAppService : IApplicationService +{ + Task> GetListAsync(); +} +```` + +Your interface should implement the `IRemoteService` interface to be automatically discovered. Since the `IApplicationService` inherits the `IRemoteService` interface, the `IBookAppService` above satisfies this condition. + +Implement this class in your service application. You can use [auto API controller system](Auto-API-Controllers.md) to expose the service as a REST API endpoint. + +## Client Proxy Generation + +First, add [Volo.Abp.Http.Client](https://www.nuget.org/packages/Volo.Abp.Http.Client) nuget package to your client project: + +```` +Install-Package Volo.Abp.Http.Client +```` + +Then add `AbpHttpClientModule` dependency to your module: + +````csharp +[DependsOn(typeof(AbpHttpClientModule))] //add the dependency +public class MyClientAppModule : AbpModule +{ +} +```` + +Now, it's ready to create the client proxies. Example: + +````csharp +[DependsOn( + typeof(AbpHttpClientModule), //used to create client proxies + typeof(BookStoreApplicationModule) //contains the application service interfaces + )] +public class MyClientAppModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + //Create dynamic client proxies + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly + ); + } +} +```` + +`AddHttpClientProxies` method gets an assembly, finds all service interfaces in the given assembly, creates and registers proxy classes. + +### Endpoint Configuration + +`RemoteServices` section in the `appsettings.json` file is used to get remote service address by default. Simplest configuration is shown below: + +```` +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + } + } +} +```` + +See the "RemoteServiceOptions" section below for more detailed configuration. + +## Usage + +It's straightforward to use. Just inject the service interface in the client application code: + +````csharp +public class MyService : ITransientDependency +{ + private readonly IBookAppService _bookService; + + public MyService(IBookAppService bookService) + { + _bookService = bookService; + } + + public async Task DoIt() + { + var books = await _bookService.GetListAsync(); + foreach (var book in books) + { + Console.WriteLine($"[BOOK {book.Id}] Name={book.Name}"); + } + } +} +```` + +This sample injects the `IBookAppService` service interface defined above. The dynamic client proxy implementation makes an HTTP call whenever a service method is called by the client. + +### IHttpClientProxy Interface + +While you can inject `IBookAppService` like above to use the client proxy, you could inject `IHttpClientProxy` for a more explicit usage. In this case you will use the `Service` property of the `IHttpClientProxy` interface. + +## Configuration + +### RemoteServiceOptions + +`RemoteServiceOptions` is automatically set from the `appsettings.json` by default. Alternatively, you can use `Configure` method to set or override it. Example: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + context.Services.Configure(options => + { + options.RemoteServices.Default = + new RemoteServiceConfiguration("http://localhost:53929/"); + }); + + //... +} +```` + +### Multiple Remote Service Endpoints + +The examples above have configured the "Default" remote service endpoint. You may have different endpoints for different services (as like in a microservice approach where each microservice has different endpoints). In this case, you can add other endpoints to your configuration file: + +````json +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + }, + "BookStore": { + "BaseUrl": "http://localhost:48392/" + } + } +} +```` + +`AddHttpClientProxies` method can get an additional parameter for the remote service name. Example: + +````csharp +context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly, + remoteServiceName: "BookStore" +); +```` + +`remoteServiceName` parameter matches the service endpoint configured via `RemoteServiceOptions`. If the `BookStore` endpoint is not defined then it fallbacks to the `Default` endpoint. + +### As Default Services + +When you create a service proxy for `IBookAppService`, you can directly inject the `IBookAppService` to use the proxy client (as shown in the usage section). You can pass `asDefaultServices: false` to the `AddHttpClientProxies` method to disable this feature. + +````csharp +context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly, + asDefaultServices: false +); +```` + +Using `asDefaultServices: false` may only be needed if your application has already an implementation of the service and you do not want to override/replace the other implementation by your client proxy. + +> If you disable `asDefaultServices`, you can only use `IHttpClientProxy` interface to use the client proxies (see the related section above). \ No newline at end of file diff --git a/docs/en/Audit-Logging.md b/docs/en/Audit-Logging.md new file mode 100644 index 0000000000..f11a3f19e3 --- /dev/null +++ b/docs/en/Audit-Logging.md @@ -0,0 +1,3 @@ +# Audit Logging + +TODO \ No newline at end of file diff --git a/docs/en/Best-Practices/MongoDB-Integration.md b/docs/en/Best-Practices/MongoDB-Integration.md index 32eefadd6a..76b6e8561f 100644 --- a/docs/en/Best-Practices/MongoDB-Integration.md +++ b/docs/en/Best-Practices/MongoDB-Integration.md @@ -103,34 +103,6 @@ public class IdentityMongoModelBuilderConfigurationOptions } ``` -* **Do** explicitly configure `BsonClassMap` for all entities. Create a static method for this purpose. Example: - -````C# -public static class AbpIdentityBsonClassMap -{ - private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); - - public static void Configure() - { - OneTimeRunner.Run(() => - { - BsonClassMap.RegisterClassMap(map => - { - map.AutoMap(); - map.ConfigureExtraProperties(); - }); - - BsonClassMap.RegisterClassMap(map => - { - map.AutoMap(); - }); - }); - } -} -```` - -`BsonClassMap` works with static methods. So, it is only needed to configure entities once in an application. `OneTimeRunner` guarantees that it runs in a thread safe manner and only once in the application life. Such a mapping above ensures that unit test properly run. This code will be called by the **module class** below. - ### Repository Implementation - **Do** **inherit** the repository from the `MongoDbRepository` class and implement the corresponding repository interface. Example: @@ -187,8 +159,6 @@ public class AbpIdentityMongoDbModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - AbpIdentityBsonClassMap.Configure(); - context.Services.AddMongoDbContext(options => { options.AddRepository(); diff --git a/docs/en/Blog-Posts/2019-02-22/Post.md b/docs/en/Blog-Posts/2019-02-22/Post.md new file mode 100644 index 0000000000..35f8219014 --- /dev/null +++ b/docs/en/Blog-Posts/2019-02-22/Post.md @@ -0,0 +1,54 @@ +# Microservice Demo, Projects Status and Road Map + +After [the first announcement](https://abp.io/blog/abp/Abp-vNext-Announcement) on the ABP vNext, we have a lot of improvements on the codebase (1100+ commits on the [GitHub repository](https://github.com/abpframework/abp)). We've created features, samples, documentation and much more. In this post, I want to inform you about some news and the status of the project. + +## Microservice Demo Solution + +One of the major goals of the ABP framework is to provide a [convenient infrastructure to create microservice solutions](https://abp.io/documents/abp/latest/Microservice-Architecture). + +We've been working to develop a microservice solution demo. Initial version was completed and [documented](https://abp.io/documents/abp/latest/Samples/Microservice-Demo). This sample solution aims to demonstrate a simple yet complete microservice solution; + +- Has multiple, independent, self-deployable **microservices**. +- Multiple **web applications**, each uses a different API gateway. +- Has multiple **gateways** / BFFs (Backend for Frontends) developed using the [Ocelot](https://github.com/ThreeMammals/Ocelot) library. +- Has an **authentication service** developed using the [IdentityServer](https://identityserver.io/) framework. It's also a SSO (Single Sign On) application with necessary UIs. +- Has **multiple databases**. Some microservices has their own database while some services/applications shares a database (to demonstrate different use cases). +- Has different types of databases: **SQL Server** (with **Entity Framework Core** ORM) and **MongoDB**. +- Has a **console application** to show the simplest way of using a service by authenticating. +- Uses [Redis](https://redis.io/) for **distributed caching**. +- Uses [RabbitMQ](https://www.rabbitmq.com/) for service-to-service **messaging**. +- Uses [Docker](https://www.docker.com/) & [Kubernates](https://kubernetes.io/) to **deploy** & run all services and applications. +- Uses [Elasticsearch](https://www.elastic.co/products/elasticsearch) & [Kibana](https://www.elastic.co/products/kibana) to store and visualize the logs (written using [Serilog](https://serilog.net/)). + +See [its documentation](https://abp.io/documents/abp/latest/Samples/Microservice-Demo) for a detailed explanation of the solution. + +## Improvements/Features + +We've worked on so many features including **distributed event bus** (with RabbitMQ integration), **IdentityServer4 integration** and enhancements for almost all features. We are continuously refactoring and adding tests to make the framework more stable and production ready. It is [rapidly growing](https://github.com/abpframework/abp/graphs/contributors). + +## Road Map + +There are still too much work to be done before the first stable release (v1.0). You can see [prioritized backlog items](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog) on the GitHub repo. + +According to our estimation, we have planned to release v1.0 in Q2 of 2019 (probably in May or June). So, not too much time to wait. We are also very excited for the first stable release. + +We will also work on [the documentation](https://abp.io/documents/abp/latest) since it is far from complete now. + +First release may not include a SPA template. However, we want to prepare a simple one if it can be possible. Haven't decided yet about the SPA framework. Alternatives: **Angular, React and Blazor**. Please write your thought as a comment to this post. + +## Chinese Web Site + +There is a big ABP community in China. They have created a Chinese version of the abp.io web site: https://cn.abp.io/ They are keeping it up to date. Thanks to the Chinese developers and especially to [Liming Ma](https://github.com/maliming). + +## NDC {London} 2019 + +It was a pleasure to be in [NDC {London}](https://ndc-london.com/) 2019 as a partner. We've talked to many developers about the current ASP.NET Boilerplate and the ABP vNext and we got good feedbacks. + +We also had a chance to talk with [Scott Hanselman](https://twitter.com/shanselman) and [Jon Galloway](https://twitter.com/jongalloway). They visited our booth and we talked about the ideas for ABP vNext. They liked features, approaches and the goal of new ABP framework. See some photos and comments on twitter: + +![scott-and-jon](scott-and-jon.png) + +## Follow It + +* You can star and follow the **GitHub** repository: https://github.com/abpframework/abp +* You can follow the official **Twitter** account for news: https://twitter.com/abpframework \ No newline at end of file diff --git a/docs/en/Blog-Posts/2019-02-22/scott-and-jon.png b/docs/en/Blog-Posts/2019-02-22/scott-and-jon.png new file mode 100644 index 0000000000..79ad21aee7 Binary files /dev/null and b/docs/en/Blog-Posts/2019-02-22/scott-and-jon.png differ diff --git a/docs/en/Entity-Framework-Core.md b/docs/en/Entity-Framework-Core.md index 4f9ff367ee..e608736bcd 100644 --- a/docs/en/Entity-Framework-Core.md +++ b/docs/en/Entity-Framework-Core.md @@ -1,8 +1,8 @@ -## Entity Framework Core Integration +# Entity Framework Core Integration This document explains how to integrate EF Core as an ORM provider to ABP based applications and how to configure it. -### Installation +## Installation `Volo.Abp.EntityFrameworkCore` is the main nuget package for the EF Core integration. Install it to your project (for a layered application, to your data/infrastructure layer): @@ -28,7 +28,7 @@ namespace MyCompany.MyProject > Note: Instead, you can directly download a [startup template](https://abp.io/Templates) with EF Core pre-installed. -### Creating DbContext +## Creating DbContext You can create your DbContext as you normally do. It should be derived from `AbpDbContext` as shown below: @@ -50,7 +50,21 @@ namespace MyCompany.MyProject } ```` -### Registering DbContext To Dependency Injection +### Configure the Connection String Selection + +If you have multiple databases in your application, you can configure the connection string name for your DbContext using the `[ConnectionStringName]` attribute. Example: + +```csharp +[ConnectionStringName("MySecondConnString")] +public class MyDbContext : AbpDbContext +{ + +} +``` + +If you don't configure, the `Default` connection string is used. If you configure a specific connection string name, but not define this connection string name in the application configuration then it fallbacks to the `Default` connection string. + +## Registering DbContext To Dependency Injection Use `AddAbpDbContext` method in your module to register your DbContext class for [dependency injection](Dependency-Injection.md) system. @@ -74,7 +88,7 @@ namespace MyCompany.MyProject } ```` -#### Add Default Repositories +### Add Default Repositories ABP can automatically create default [generic repositories](Repositories.md) for the entities in your DbContext. Just use `AddDefaultRepositories()` option on the registration: @@ -137,7 +151,7 @@ public class BookManager : DomainService This sample uses `InsertAsync` method to insert a new entity to the database. -#### Add Custom Repositories +### Add Custom Repositories Default generic repositories are powerful enough in most cases (since they implement `IQueryable`). However, you may need to create a custom repository to add your own repository methods. @@ -173,7 +187,7 @@ public class BookRepository : EfCoreRepository, Now, it's possible to [inject](Dependency-Injection.md) the `IBookRepository` and use the `DeleteBooksByType` method when needed. -##### Override Default Generic Repository +#### Override Default Generic Repository Even if you create a custom repository, you can still inject the default generic repository (`IRepository` for this example). Default repository implementation will not use the class you have created. @@ -199,7 +213,7 @@ public override async Task DeleteAsync( } ```` -#### Access to the EF Core API +### Access to the EF Core API In most cases, you want to hide EF Core APIs behind a repository (this is the main purpose of the repository). However, if you want to access the DbContext instance over the repository, you can use `GetDbContext()` or `GetDbSet()` extension methods. Example: @@ -225,9 +239,9 @@ public class BookService > Important: You must reference to the `Volo.Abp.EntityFrameworkCore` package from the project you want to access to the DbContext. This breaks encapsulation, but this is what you want in that case. -#### Advanced Topics +### Advanced Topics -##### Set Default Repository Classes +#### Set Default Repository Classes Default generic repositories are implemented by `EfCoreRepository` class by default. You can create your own implementation and use it for default repository implementation. @@ -272,7 +286,7 @@ context.Services.AddAbpDbContext(options => }); ``` -##### Set Base DbContext Class or Interface for Default Repositories +#### Set Base DbContext Class or Interface for Default Repositories If your DbContext inherits from another DbContext or implements an interface, you can use that base class or interface as DbContext for default repositories. Example: @@ -304,7 +318,7 @@ public class BookRepository : EfCoreRepository, One advantage of using interface for a DbContext is then it becomes replaceable by another implementation. -##### Replace Other DbContextes +#### Replace Other DbContextes Once you properly define and use an interface for DbContext, then any other implementation can replace it using the `ReplaceDbContext` option: diff --git a/docs/en/Event-Bus.md b/docs/en/Event-Bus.md new file mode 100644 index 0000000000..cf2b57c018 --- /dev/null +++ b/docs/en/Event-Bus.md @@ -0,0 +1,3 @@ +# Event Bus + +TODO \ No newline at end of file diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index fe1ff3450b..8d3c898787 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -152,6 +152,27 @@ services.AddApplication(options => }); ```` +4. Update `Program.cs` to not use the `WebHost.CreateDefaultBuilder()` method since it uses the default DI container: + +````csharp +public class Program +{ + public static void Main(string[] args) + { + BuildWebHostInternal(args).Run(); + } + + public static IWebHost BuildWebHostInternal(string[] args) => + new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); +} +```` + ## Source Code Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication). + diff --git a/docs/en/Index.md b/docs/en/Index.md index df0cab524a..b1bccab0ea 100644 --- a/docs/en/Index.md +++ b/docs/en/Index.md @@ -6,25 +6,25 @@ Explore the left navigation menu to deep dive in the documentation. ## Project Status -ABP is the **next generation** of the open source [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework. It's currently in early preview stage and not ready to use in production. The documentation is in progress and currently is very incomplete. +ABP is the **next generation** of the open source [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework. It's currently in early preview stage and not ready to use in production. The documentation is still in progress and it is incomplete yet. -For short-term and production applications, it's suggested to use the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework which is feature rich, mature, maintained and up-to-date. +For short-term and production level applications, it's suggested to use [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework which has rich feature set, mature, actively maintained and up-to-date. ## Getting Started -Easiest way to start a new project with ABP is to use the Startup templates: +Easiest way to start a new project with ABP is to use the startup templates: * [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) -If you want to start from scratch (with an empty project) then manually install the ABP framework, use following tutorials: +If you want to start from scratch (with an empty project) then manually install the ABP Framework and use the following tutorials: * [Console Application](Getting-Started-Console-Application.md) * [ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) ## Source Code -ABP is being developed on GitHub. See [the source code](https://github.com/abpframework/abp). +ABP is hosted on GitHub. See [the source code](https://github.com/abpframework/abp). ## Want to Contribute? -ABP is a community-driven open source project. See [the contribution guide](Contribution/Index.md) if you want to be a part of this project. \ No newline at end of file +ABP is a community-driven open source project. See [the contribution guide](Contribution/Index.md) if you want to be a part of this project. diff --git a/docs/en/Localization.md b/docs/en/Localization.md index b6d27cc9ce..d34dc8232a 100644 --- a/docs/en/Localization.md +++ b/docs/en/Localization.md @@ -1,8 +1,8 @@ -## Localization +# Localization ABP's localization system is seamlessly integrated to the `Microsoft.Extensions.Localization` package and compatible with the [Microsoft's localization documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization). It adds some useful features and enhancements to make it easier to use in real life application scenarios. -### Volo.Abp.Localization Package +## Volo.Abp.Localization Package > This package is already installed by default with the startup template. So, most of the time, you don't need to install it manually. @@ -28,9 +28,9 @@ namespace MyCompany.MyProject } ``` -#### Creating A Localization Resource +## Creating A Localization Resource -A localization resource is used to group related localization strings together and separate them from other localization strings of the application. A module generally defines its own localization resource. Localization resource is just a plain class. Example: +A localization resource is used to group related localization strings together and separate them from other localization strings of the application. A [module](Module-Development-Basics.md) generally defines its own localization resource. Localization resource is just a plain class. Example: ````C# public class TestResource @@ -52,7 +52,8 @@ public class MyModule : AbpModule }); Configure(options => - { + { + //Define a new localization resource (TestResource) options.Resources .Add("en") .AddVirtualJson("/Localization/Resources/Test"); @@ -65,7 +66,7 @@ In this example; * Added a new localization resource with "en" (English) as the default culture. * Used JSON files to store the localization strings. -* JSON files are embedded into the assembly using the [virtual file system](Virtual-File-System.md). +* JSON files are embedded into the assembly using `VirtualFileSystemOptions` (see [virtual file system](Virtual-File-System.md)). JSON files are located under "/Localization/Resources/Test" project folder as shown below: @@ -85,7 +86,7 @@ A JSON localization file content is shown below: * Every localization file should define the `culture` code for the file (like "en" or "en-US"). * `texts` section just contains key-value collection of the localization strings (keys may have spaces too). -##### Short Localization Resource Name +### Short Localization Resource Name Localization resources are also available in the client (JavaScript) side. So, setting a short name for the localization resource makes it easy to use localization texts. Example: @@ -98,7 +99,7 @@ public class TestResource See the Getting Localized Test / Client Side section below. -##### Inherit From Other Resources +### Inherit From Other Resources A resource can inherit from other resources which makes possible to re-use existing localization strings without referring the existing resource. Example: @@ -124,7 +125,7 @@ services.Configure(options => * A resource may inherit from multiple resources. * If the new resource defines the same localized string, it overrides the string. -##### Extending Existing Resource +### Extending Existing Resource Inheriting from a resource creates a new resource without modifying the existing one. In some cases, you may want to not create a new resource but directly extend an existing resource. Example: @@ -139,13 +140,13 @@ services.Configure(options => * If an extension file defines the same localized string, it overrides the string. -#### Getting Localized Texts +## Getting Localized Texts -##### Server Side +### Server Side Getting the localized text on the server side is pretty standard. -###### Simplest Usage In A Class +#### Simplest Usage In A Class ````C# public class MyService @@ -164,7 +165,7 @@ public class MyService } ```` -###### Simplest Usage In A Razor View/Page +#### Simplest Usage In A Razor View/Page ````c# @inject IHtmlLocalizer Localizer @@ -174,7 +175,7 @@ public class MyService Refer to the [Microsoft's localization documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) for details about using localization on the server side. -##### Client Side +### Client Side ABP provides JavaScript services to use the same localized texts in the client side. diff --git a/docs/en/Microservice-Architecture.md b/docs/en/Microservice-Architecture.md new file mode 100644 index 0000000000..e30c070a01 --- /dev/null +++ b/docs/en/Microservice-Architecture.md @@ -0,0 +1,30 @@ +# Microservice Architecture + +*"Microservices are a software development technique—a variant of the **service-oriented architecture** (SOA) architectural style that structures an application as a collection of **loosely coupled services**. In a microservices architecture, services are **fine-grained** and the protocols are **lightweight**. The benefit of decomposing an application into different smaller services is that it improves **modularity**. This makes the application easier to understand, develop, test, and become more resilient to architecture erosion. It **parallelizes development** by enabling small autonomous teams to **develop, deploy and scale** their respective services independently. It also allows the architecture of an individual service to emerge through **continuous refactoring**. Microservices-based architectures enable **continuous delivery and deployment**."* + +— [Wikipedia](https://en.wikipedia.org/wiki/Microservices) + +## Introduction + +One of the major goals of the ABP framework is to provide a convenient infrastructure to create microservice solutions. To make this possible, + +* Provides a [module system](Module-Development-Basics.md) that allows you to split your application into modules where each module may have its own database, entities, services, APIs, UI components/pages... etc. +* Offers an [architectural model](Best-Practices/Module-Architecture.md) to develop your modules to be compatible to microservice development and deployment. +* Provides [best practices guide](Best-Practices/Index.md) to develop your module standards-compliance. +* Provides base infrastructure to implement [Domain Driven Design](Domain-Driven-Design.md) in your microservices. +* Provide services to [automatically create REST-style APIs](AspNetCore/Auto-API-Controllers.md) from your application services. +* Provide services to [automatically create C# API clients](AspNetCore/Dynamic-CSharp-API-Clients.md) that makes easy to consume your services from another service/application. +* Provides a [distributed event bus](Event-Bus.md) to communicate your services. +* Provides many other services to make your daily development easier. + +## Microservice for New Applications + +One common advise to start a new solution is **always to start with a monolith**, keep it modular and split into microservices once the monolith becomes a problem. This makes your progress fast in the beginning especially if your team is small and you don't want to deal with challanges of the microservice architecture. + +However, developing such a well-modular application can be a problem since it is **hard to keep modules isolated** from each other as you would do it for microservices (see [Stefan Tilkov's article](https://martinfowler.com/articles/dont-start-monolith.html) about that). Microservice architecture naturally forces you to develop well isolated services, but in a modular monolithic application it's easy to tight couple modules to each other and design **weak module boundaries** and API contracts. + +ABP can help you in that point by oferring a **microservice-compatible, strict module architecture** where your module is splitted into multiple layers/projects and developed in its own VS solution completely isolated and independent from other modules. Such a developed module is a natural microservice yet it can be easily plugged-in a monolithic application. See the [module development best practice guide](Best-Practices/Index.md) that offers a **microservice-first module design**. All [standard ABP modules](https://github.com/abpframework/abp/tree/master/modules) are developed based on this guide. So, you can use these modules by embedding into your monolithic solution or deploy them separately and use via remote APIs. They can share a single database or can have their own database based on your simple configuration. + +## Microservice Demo Solution + +The [sample microservice solution](Samples/Microservice-Demo.md) demonstrates a complete microservice solution based on the ABP framework. \ No newline at end of file diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index adfcd15453..1aa81621f5 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -1,9 +1,475 @@ # Docs Module -Docs module is used to create technical documentation pages. ABP's [own documentation](https://abp.io/documents/) already using this module. +## What is Docs Module? + +Docs module is an application module for ABP framework. It simplifies software documentation. This module is free and open-source. + +### Integration + +Currently docs module provides you to store your docs both on GitHub and file system. + +### Hosting + +Docs module is an application module and does not offer any hosting solution. You can host your docs on-premise or on cloud. + +### Versioning + +When you use GitHub to store your docs, Docs Module supports versioning. If you have multiple versions for your docs, there will be a combo-box on the UI to switch between versions. If you choose file system to store your docs, it does not support multiple versions. + +[The documents](https://abp.io/documents/) for ABP framework is also using this module. > Docs module follows the [module architecture best practices](../Best-Practices/Module-Architecture.md) guide. + + ## Installation -TODO... \ No newline at end of file +### 1- Download + +If you do not have an existing ABP project, this step shows you how to create a new project from [abp.io](https://abp.io) to add the Docs Module. If you already have an ABP project, you can skip this step. + +Navigate to https://abp.io/Templates. Enter your project name as `Acme.MyProject`, select `ASP.NET Core Mvc Application` and select `Entity Framework Core` for the database provider. + +Note that this document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. + +![Create new project](../images/docs-module_download-new-abp-project.png) + +### 2- Running The Empty Application + +After you download the project, extract the ZIP file and open `Acme.MyProject.sln`. You will see that the solution consists of `Application`, `Domain `, `EntityFrameworkCore` and `Web` projects. Right click on `Acme.MyProject.Web` project and **Set as StartUp Project**. + +![Create a new project](../images/docs-module_solution-explorer.png) + +The database connection string is located in `appsettings.json` of your `Acme.MyProject.Web` project. If you have a different database configuration, change the connection string. + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost;Database=MyProject;Trusted_Connection=True;MultipleActiveResultSets=true" + } +} +``` + + + +Open `Package Manager Console` in the Visual Studio and choose `src\Acme.MyProject.EntityFrameworkCore` as the default project. Run `Update-Database` command to create your new database. The database `MyProject` will be created in your database server. + +Now an empty ABP project has been created! You can now run your project and see the empty website. + +To login your website enter `admin` as the username and `1q2w3E*` as the password. + +### 2- Referencing Docs Module Packages + +Docs module packages are hosted on NuGet. There are 4 packages that needs be to installed to your application. Each package has to be installed to the relevant project. + +* [Volo.Docs.Domain](https://www.nuget.org/packages/Volo.Docs.Domain/) needs to be referenced to `Acme.MyProject.Domain` project. + + * Edit `Acme.MyProject.Domain.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Docs.EntityFrameworkCore/) needs to be referenced to `Acme.MyProject.EntityFrameworkCore` project. + + - Edit `Acme.MyProject.EntityFrameworkCore.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.Application](https://www.nuget.org/packages/Volo.Docs.Application/) needs to be referenced to `Acme.MyProject.Application` project. + + * Edit `Acme.MyProject.Application.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.Web ](https://www.nuget.org/packages/Volo.Docs.Web/)needs to be referenced to `Acme.MyProject.Web` project. + + - Edit `Acme.MyProject.Web.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` + + + +### 3- Adding Module Dependencies + +An ABP module must declare `[DependsOn]` attribute if it has a dependency upon another module. Each module has to be added in`[DependsOn]` attribute to the relevant project. + +* Open `MyProjectDomainModule.cs`and add `typeof(DocsDomainModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsDomainModule), + typeof(AbpIdentityDomainModule), + typeof(AbpAuditingModule), + typeof(BackgroundJobsDomainModule), + typeof(AbpAuditLoggingDomainModule) + )] + public class MyProjectDomainModule : AbpModule + { + //... + } + ``` + +* Open `MyProjectEntityFrameworkCoreModule.cs`and add `typeof(DocsEntityFrameworkCoreModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsEntityFrameworkCoreModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(BackgroundJobsEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule) + )] + public class MyProjectEntityFrameworkCoreModule : AbpModule + { + //... + } + ``` + + +* Open `MyProjectApplicationModule.cs`and add `typeof(DocsApplicationModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsApplicationModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityApplicationModule))] + public class MyProjectApplicationModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefinitionProviders.Add(); + }); + + Configure(options => + { + options.AddProfile(); + }); + } + } + ``` + + +* Open `MyProjectWebModule.cs`and add `typeof(DocsWebModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsWebModule), + typeof(MyProjectApplicationModule), + typeof(MyProjectEntityFrameworkCoreModule), + typeof(AbpAutofacModule), + typeof(AbpIdentityWebModule), + typeof(AbpAccountWebModule), + typeof(AbpAspNetCoreMvcUiBasicThemeModule) + )] + public class MyProjectWebModule : AbpModule + { + //... + } + ``` + + + +### 4- Database Integration + +#### 4.1- Entity Framework Integration + +If you choose Entity Framework as your database provider, you need to configure the Docs Module in your DbContext. To do this; + +- Open `MyProjectDbContext.cs` and add `modelBuilder.ConfigureDocs()` to the `OnModelCreating()` + + ```csharp + [ConnectionStringName("Default")] + public class MyProjectDbContext : AbpDbContext + { + public MyProjectDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //... + modelBuilder.ConfigureDocs(); + } + } + ``` + +* Open `Package Manager Console` in `Visual Studio` and choose `Acme.MyProject.EntityFrameworkCore` as default project. Then write the below command to add the migration for Docs Module. + + ```csharp + add-migration Added_Docs_Module + ``` + + When the command successfully executes , you will see a new migration file named as `20181221111621_Added_Docs_Module` in the folder `Acme.MyProject.EntityFrameworkCore\Migrations`. + + Now, update the database for Docs module database changes. To do this run the below code on `Package Manager Console` in `Visual Studio`. Be sure `Acme.MyProject.EntityFrameworkCore` is still default project. + + ```csharp + update-database + ``` + + Finally, you can check your database to see the newly created tables. For example you can see `DocsProjects` table must be added to your database. + + +### 5- Linking Docs Module + +The default route for Docs module is; + +``` +/Documents +``` + +To add Docs module link to your application menu; + +* Open `MyProjectMenuContributor.cs` and add the below line to the method `ConfigureMainMenuAsync()`. + + ```csharp + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + ``` + + Final look of **MyProjectMenuContributor.cs** + + ```csharp + private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + { + var l = context.ServiceProvider.GetRequiredService>(); + + context.Menu.Items.Insert(0, new ApplicationMenuItem("MyProject.Home", l["Menu:Home"], "/")); + + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + } + ``` + +The `Menu:Docs` keyword is a localization key. To localize the menu text, open `Localization\MyProject\en.json` in the project `Acme.MyProject.Domain`. And add the below line + +```json +"Menu:Docs": "Documents" +``` + +Final look of **en.json** + +```json +{ + "culture": "en", + "texts": { + "Menu:Home": "Home", + "Welcome": "Welcome", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.", + "Menu:Docs": "Documents" + } +} +``` + +The new menu item for Docs Module is added to the menu. Run your web application and browse to `http://localhost:YOUR_PORT_NUMBER/documents` URL. + +You will see a warning says; + +``` +There are no projects yet! +``` + +As we have not added any projects yet, this warning is normal. + +### 6- Adding New Docs Project + +Open `DocsProjects` in your database, and insert a new record with the following field information; + +* **Name**: The display name of the document name which will be shown on the web page. +* **ShortName**: A short and URL friendly name that will be used in your docs URL. +* **Format**: The format of the document (for Markdown: `md`, for HTML: `html`) +* **DefaultDocumentName**: The document for the initial page. +* **NavigationDocumentName**: The document to be used for the navigation menu (index). +* **MinimumVersion**: The minimum version to show the docs. Below version will not be listed. +* **DocumentStoreType**: The source of the documents (for GitHub:`GitHub`, for file system`FileSystem`) +* **ExtraProperties**: A serialized `JSON` that stores special configuration for the selected `DocumentStoreType`. +* **MainWebsiteUrl**: The URL when user clicks to the logo of the Docs module page. You can simply set as `/` to link to your website root address. +* **LatestVersionBranchName**: This is a config for GitHub. It's the branch name which to retrieve the docs. You can set it as `master`. + +#### Sample Project Record for "GitHub" + +You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. + +- Name: `ABP framework (GitHub)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `GitHub` + +- ExtraProperties: + + ```json + {"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"} + ``` + + Note that `GitHubAccessToken` is masked with `***`. It's a private token that you must get it from GitHub. See https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `master` + +For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939658', N'ABP framework (GitHub)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'GitHub', N'{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"}', N'/', N'master') +``` + +Be aware that `GitHubAccessToken` is masked. It's a private token and you must get your own token and replace the `***` string. + +#### Sample Project Record for "FileSystem" + +You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. + +- Name: `ABP framework (FileSystem)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `FileSystem` + +- ExtraProperties: + + ```json + {"Path":"C:\\Github\\abp\\docs\\en"} + ``` + + Note that `Path` must be replaced with your local docs directory. You can fetch the ABP Framework's documents from https://github.com/abpframework/abp/tree/master/docs/en and copy to the directory `C:\\Github\\abp\\docs\\en` to get it work. + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `` + +For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939659', N'ABP framework (FileSystem)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'FileSystem', N'{"Path":"C:\\Github\\abp\\docs\\en"}', N'/', NULL) +``` + + + +Add one of the sample projects above and run the application. In the menu you will see `Documents` link, click the menu link to open the documents page. + +So far, we have created a new application from abp.io website and made it up and ready for Docs module. + +### 7- Creating a New Document + +In the sample Project records, you see that `Format` is specified as `md` which refers to [Mark Down](https://en.wikipedia.org/wiki/Markdown). You can see the mark down cheat sheet following the below link; + +https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet + +ABP Docs Module can render mark down to HTML. + +Now let's have a look a sample document in markdown format. + +~~~markdown +# This is a header + +Welcome to Docs Module. + +## This is a sub header + + [This is a link](https://abp.io) + +![This is an image](https://abp.io/assets/my-image.png) + +## This is a code block + +```csharp +public class Person +{ + public string Name { get; set; } + + public string Address { get; set; } +} +``` +~~~ + + + +As an example you can see ABP Framework documentation: + +[https://github.com/abpframework/abp/blob/master/docs/en/](https://github.com/abpframework/abp/blob/master/docs/en/) + +### 8- Creating the Navigation Document + +Navigation document is the main menu of the documents page. It is located on the left side of the page. It is a `JSON` file. Take a look at the below sample navigation document to understand the structure. + +```json +{ + "items":[ + { + "text":"Sample Menu Item - 1", + "items":[ + { + "text":"Sample Menu Item - 1.1", + "items":[ + { + "text":"Sample Menu Item - 1.1.1", + "path":"SampleMenuItem_1_1_1.md" + } + ] + }, + { + "text":"Sample Menu Item - 1.2", + "items":[ + { + "text":"Sample Menu Item - 1.2.1", + "path":"SampleMenuItem_1_2_1.md" + }, + { + "text":"Sample Menu Item - 1.2.2", + "path":"SampleMenuItem_1_2_2.md" + } + ] + } + ] + }, + { + "text":"Sample Menu Item - 2", + "items":[ + { + "text":"Sample Menu Item - 2.1", + "items":[ + { + "text":"Sample Menu Item - 2.1.1", + "path":"SampleMenuItem_2_1_1.md" + } + ] + } + ] + } + ] +} +``` + +The upper sample `JSON` file renders the below navigation menu as `HTML`. + +![Navigation menu](../images/docs-module_download-sample-navigation-menu.png) + + + +Finally a new Docs Module is added to your project which is feeded with GitHub. \ No newline at end of file diff --git a/docs/en/MongoDB.md b/docs/en/MongoDB.md index c03c6f4f2c..e7d8084f41 100644 --- a/docs/en/MongoDB.md +++ b/docs/en/MongoDB.md @@ -1,8 +1,8 @@ -## MongoDB Integration +# MongoDB Integration This document explains how to integrate MongoDB as a database provider to ABP based applications and how to configure it. -### Installation +## Installation `Volo.Abp.MongoDB` is the main nuget package for the MongoDB integration. Install it to your project (for a layered application, to your data/infrastructure layer): @@ -26,7 +26,7 @@ namespace MyCompany.MyProject } ``` -### Creating a Mongo Db Context +## Creating a Mongo Db Context ABP introduces **Mongo Db Context** concept (which is similar to Entity Framework Core's DbContext) to make it easier to use collections and configure them. An example is shown below: @@ -39,19 +39,62 @@ public class MyDbContext : AbpMongoDbContext protected override void CreateModel(IMongoModelBuilder modelBuilder) { - modelBuilder.Entity(b => - { - b.CollectionName = "Questions"; - }); + base.CreateModel(modelBuilder); + + //Customize the configuration for your collections. } } ``` * It's derived from `AbpMongoDbContext` class. * Adds a public `IMongoCollection` property for each mongo collection. ABP uses these properties to create default repositories by default. -* Overriding `CreateModel` method allows to configure collections (like their collection name in the database). +* Overriding `CreateModel` method allows to configure collection configuration. + +### Configure Mapping for a Collection + +ABP automatically register entities to MongoDB client library for all `IMongoCollection` properties in your DbContext. For the example above, `Question` and `Category` entities are automatically registered. + +For each registered entity, it calls `AutoMap()` and configures known properties of your entity. For instance, if your entity implements `IHasExtraProperties` interface (which is already implemented for every aggregate root by default), it automatically configures `ExtraProperties`. + +So, most of times you don't need to explicitly configure registration for your entities. However, if you need it you can do it by overriding the `CreateModel` method in your DbContext. Example: + +````csharp +protected override void CreateModel(IMongoModelBuilder modelBuilder) +{ + base.CreateModel(modelBuilder); + + modelBuilder.Entity(b => + { + b.CollectionName = "MyQuestions"; //Sets the collection name + b.BsonMap.UnmapProperty(x => x.MyProperty); //Ignores 'MyProperty' + }); +} +```` + +This example changes the mapped collection name to 'MyQuestions' in the database and ignores a property in the `Question` class. + +If you only need to configure the collection name, you can also use `[MongoCollection]` attribute for the collection in your DbContext. Example: + +````csharp +[MongoCollection("MyQuestions")] //Sets the collection name +public IMongoCollection Questions => Collection(); +```` + +### Configure the Connection String Selection + +If you have multiple databases in your application, you can configure the connection string name for your DbContext using the `[ConnectionStringName]` attribute. Example: + +````csharp +[ConnectionStringName("MySecondConnString")] +public class MyDbContext : AbpMongoDbContext +{ + +} +```` + +If you don't configure, the `Default` connection string is used. If you configure a specific connection string name, but not define this connection string name in the application configuration then it fallbacks to the `Default` connection string. -### Registering DbContext To Dependency Injection +## Registering DbContext To Dependency Injection Use `AddAbpDbContext` method in your module to register your DbContext class for [dependency injection](Dependency-Injection.md) system. @@ -75,7 +118,7 @@ namespace MyCompany.MyProject } ``` -#### Add Default Repositories +### Add Default Repositories ABP can automatically create default [generic repositories](Repositories.md) for the entities in your DbContext. Just use `AddDefaultRepositories()` option on the registration: @@ -138,7 +181,7 @@ public class BookManager : DomainService This sample uses `InsertAsync` method to insert a new entity to the database. -#### Add Custom Repositories +### Add Custom Repositories Default generic repositories are powerful enough in most cases (since they implement `IQueryable`). However, you may need to create a custom repository to add your own repository methods. @@ -182,7 +225,7 @@ public class BookRepository : Now, it's possible to [inject](Dependency-Injection.md) the `IBookRepository` and use the `DeleteBooksByType` method when needed. -##### Override Default Generic Repository +#### Override Default Generic Repository Even if you create a custom repository, you can still inject the default generic repository (`IRepository` for this example). Default repository implementation will not use the class you have created. @@ -208,7 +251,7 @@ public override async Task DeleteAsync( } ``` -#### Access to the MongoDB API +### Access to the MongoDB API In most cases, you want to hide MongoDB APIs behind a repository (this is the main purpose of the repository). However, if you want to access the MongoDB API over the repository, you can use `GetDatabase()` or `GetCollection()` extension methods. Example: @@ -232,9 +275,9 @@ public class BookService > Important: You must reference to the `Volo.Abp.MongoDB` package from the project you want to access to the MongoDB API. This breaks encapsulation, but this is what you want in that case. -#### Advanced Topics +### Advanced Topics -##### Set Default Repository Classes +#### Set Default Repository Classes Default generic repositories are implemented by `MongoDbRepository` class by default. You can create your own implementation and use it for default repository implementation. @@ -279,7 +322,7 @@ context.Services.AddMongoDbContext(options => }); ``` -##### Set Base MongoDbContext Class or Interface for Default Repositories +#### Set Base MongoDbContext Class or Interface for Default Repositories If your MongoDbContext inherits from another MongoDbContext or implements an interface, you can use that base class or interface as the MongoDbContext for default repositories. Example: @@ -313,7 +356,7 @@ public class BookRepository One advantage of using interface for a MongoDbContext is then it becomes replaceable by another implementation. -##### Replace Other DbContextes +#### Replace Other DbContextes Once you properly define and use an interface for a MongoDbContext , then any other implementation can replace it using the `ReplaceDbContext` option: diff --git a/docs/en/Samples/Microservice-Demo.md b/docs/en/Samples/Microservice-Demo.md new file mode 100644 index 0000000000..55a60dca89 --- /dev/null +++ b/docs/en/Samples/Microservice-Demo.md @@ -0,0 +1,1454 @@ +# Microservice Demo Solution + +*"Microservices are a software development technique—a variant of the **service-oriented architecture** (SOA) architectural style that structures an application as a collection of **loosely coupled services**. In a microservices architecture, services are **fine-grained** and the protocols are **lightweight**. The benefit of decomposing an application into different smaller services is that it improves **modularity**. This makes the application easier to understand, develop, test, and become more resilient to architecture erosion. It **parallelizes development** by enabling small autonomous teams to **develop, deploy and scale** their respective services independently. It also allows the architecture of an individual service to emerge through **continuous refactoring**. Microservices-based architectures enable **continuous delivery and deployment**."* + +— [Wikipedia](https://en.wikipedia.org/wiki/Microservices) + +## Introduction + +One of the major goals of the ABP framework is to provide a [convenient infrastructure to create microservice solutions](../Microservice-Architecture.md). + +This sample aims to demonstrate a simple yet complete microservice solution; + +* Has multiple, independent, self-deployable **microservices**. +* Multiple **web applications**, each uses a different API gateway. +* Has multiple **gateways** / BFFs (Backend for Frontends) developed using the [Ocelot](https://github.com/ThreeMammals/Ocelot) library. +* Has an **authentication service** developed using the [IdentityServer](https://identityserver.io/) framework. It's also a SSO (Single Sign On) application with necessary UIs. +* Has **multiple databases**. Some microservices has their own database while some services/applications shares a database (to demonstrate different use cases). +* Has different types of databases: **SQL Server** (with **Entity Framework Core** ORM) and **MongoDB**. +* Has a **console application** to show the simplest way of using a service by authenticating. +* Uses [Redis](https://redis.io/) for **distributed caching**. +* Uses [RabbitMQ](https://www.rabbitmq.com/) for service-to-service **messaging**. +* Uses [Docker](https://www.docker.com/) & [Kubernates](https://kubernetes.io/) to **deploy** & run all services and applications. +* Uses [Elasticsearch](https://www.elastic.co/products/elasticsearch) & [Kibana](https://www.elastic.co/products/kibana) to store and visualize the logs (written using [Serilog](https://serilog.net/)). + +The diagram below shows the system: + +![microservice-sample-diagram-2](../images/microservice-sample-diagram-2.png) + +### Source Code + +You can get the source code from [the GitHub repository](https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo). + +### Status + +Initial version of this sample has been completed. Additional improvement are still in development. + +## Running the Solution + +You can either run from the **source code** or from the pre-configured **docker-compose** file. + +### Using the Docker Containers + +#### Pre Requirements + +Running as docker containers is easier since all dependencies are pre-configured. You only need to install the [latest docker](https://docs.docker.com/compose/install/). + +#### Running Containers + +- Clone or download the [ABP repository](https://github.com/abpframework/abp). + +- Open a command line in the `samples/MicroserviceDemo` folder of the repository. + +- Pull images from Docker Hub: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml pull + ``` + +- If you want to build images locally you may skip the above step and instead use build command: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml build + ``` + + Building images may take a **long time** depending on your machine. + +- Restore SQL Server databases: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml run restore-database + ``` + +- Start the containers: + + ``` + docker-compose up -d + ``` + +- Add this line to the end of your `hosts` file: + + ``` + 127.0.0.1 auth-server + ``` + + hosts file is located inside the `C:\Windows\System32\Drivers\etc\hosts` folder on Windows and `/etc/hosts` for Linux/MacOS. + +#### Run the Applications + +There are a few applications running in the containers you may want to explore: + +* Backend Admin Application (BackendAdminApp.Host): `http://localhost:51512` + *(Used to manage users & products in the system)* +* Public Web Site (PublicWebsite.Host): `http://localhost:51513` + *(Used to list products and run/manage the blog module)* +* Authentication Server (AuthServer.Host): `http://auth-server:51511/` + *(Used as a single sign on and authentication server built with IdentityServer4)* +* Kibana UI: `http://localhost:51510` + *(Use to show/trace logs written by all services/applications/gateways)* + +### Running From the Source Code + +#### Pre Requirements + +To be able to run the solution from source code, following tools should be installed and running on your computer: + +* [SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) 2015+ (can be [express edition](https://www.microsoft.com/en-us/sql-server/sql-server-editions-express)) +* [Redis](https://redis.io/download) 5.0+ +* [RabbitMQ](https://www.rabbitmq.com/install-windows.html) 3.7.11+ +* [MongoDB](https://www.mongodb.com/download-center) 4.0+ +* [ElasticSearch](https://www.elastic.co/downloads/elasticsearch) 6.6+ +* [Kibana](https://www.elastic.co/downloads/kibana) 6.6+ (optional, recommended to show logs) + +#### Open & Build the Visual Studio Solution + +* Open the `samples\MicroserviceDemo\MicroserviceDemo.sln` in Visual Studio 2017 (15.9.0+). +* Run `dotnet restore` from the command line inside the `samples\MicroserviceDemo` folder. +* Build the solution in Visual Studio. + +#### Restore Databases + +Open `MsDemo_Identity.zip` and `MsDemo_ProductManagement.zip` inside the `samples\MicroserviceDemo\databases` folder and restore to the SQL Server. + +> Notice that: These databases have EF Core migrations in the solution, however they don't have seed data, especially required for IdentityServer4 configuration. So, restoring the databases is much more easier. + +#### Run Projects + +Run the projects with the following order (right click to each project, set as startup project an press Ctrl+F5 to run without debug): + +* AuthServer.Host +* IdentityService.Host +* BloggingService.Host +* ProductService.Host +* InternalGateway.Host +* BackendAdminAppGateway.Host +* PublicWebSiteGateway.Host +* BackendAdminApp.Host +* PublicWebSite.Host + +## A Brief Overview of the Solution + +The Visual Studio solution consists of multiple projects each have different roles in the system: + +![microservice-sample-solution](../images/microservice-sample-solution.png) + +### Applications + +These are the actual applications those have user interfaces to interact to the users and use the system. + +- **AuthServer.Host**: Host the IdentityServer4 to provide an authentication service to other services and applications. It is a single-sign server and contains the login page. +- **BackendAdminApp.Host**: This is a backend admin application that host UI for Identity and Product management modules. +- **PubicWebSite.Host**: As public web site that contains a simple product list page and blog module UI. +- **ConsoleClientDemo**: A simple console application to demonstrate the usage of services from a C# application. + +### Gateways / BFFs (Backend for Frontend) + +Gateways are used to provide a single entry point to the applications. It can also used for rate limiting, load balancing... etc. Used the [Ocelot](https://github.com/ThreeMammals/Ocelot) library. + +* **BackendAdminAppGateway.Host**: Used by the BackendAdminApp.Host application as backend. +* **PublicWebSiteGateway.Host**: Used by the PublicWebSite.Host application as backend. +* **InternalGateway.Host**: Used for inter-service communication (the communication between microservices). + +### Microservices + +Microservices have no UI, but exposes some REST APIs. + +- **IdentityService.Host**: Host the ABP Identity module which is used to manage users & roles. It has no additional service, but only hosts the Identity module's API. +- **BloggingService.Host**: Host the ABP Blogging module which is used to manage blog & posts (a typical blog application). It has no additional service, but only hosts the Blogging module's API. +- **ProductService.Host**: Hosts the Product module (that is inside the solution) which is used to manage products. It also contains the EF Core migrations to create/update the Product Management database schema. + +### Modules + +* **Product**: A layered module that is developed with the [module development best practices](../Best-Practices/Index.md). It can be embedded into a monolithic application or can be hosted as a microservice by separately deploying API and UI (as done in this demo solution). + +### Databases + +This solution is using multiple databases: + +* **MsDemo_Identity**: An SQL database. Used **SQL Server** by default, but can be any DBMS supported by the EF Core. Shared by AuthServer and IdentityService. Also audit logs, permissions and settings are stored in this database (while they could easily have their own databases, shared the same database to keep it simple). +* **MsDemo_ProductManagement**: An SQL database. Again, used **SQL Server** by default, but can be any DBMS supported by the EF Core. Used by the ProductService as a dedicated database. +* **MsDemo_Blogging**: A **MongoDB** database. Used by the BloggingService. +* **Elasticsearch**: Used to write logs over Serilog. + +## Applications + +### Authentication Server (AuthServer.Host) + +This project is used by all other services and applications for authentication & single sign on. Mainly, uses **IdentityServer4** to provide these services. It uses some of the [pre-build ABP modules](../Modules/Index) like *Identity*, *Audit Logging* and *Permission Management*. + +#### Database & EF Core Configuration + +This application uses a SQL database (named it as **MsDemo_Identity**) and maintains its schema via **Entity Framework Core migrations.** + +It has a DbContext named **AuthServerDbContext** and defined as shown below: + +````csharp +public class AuthServerDbContext : AbpDbContext +{ + public AuthServerDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureIdentity(); + modelBuilder.ConfigureIdentityServer(); + modelBuilder.ConfigureAuditLogging(); + modelBuilder.ConfigurePermissionManagement(); + modelBuilder.ConfigureSettingManagement(); + } +} +```` + +In the **OnModelCreating**, you see **ConfigureX()** method calls. A module with a database schema generally declares such an extension method to configure EF Core mappings for its own entities. This is a flexible approach where you can arrange your databases and modules inside them; You can use a different database for each module, or combine some of them in a shared database. In the AuthServer project, we decided to combine multiple module schemas in a single EF Core DbContext, in a single physical database. These modules are Identity, IdentityServer, AuditLogging, PermissionManagement and SettingManagement modules. + +Notice that this DbContext is only for database migrations. All modules have their own `DbContext` classes those are used in the runtime by the modules. + +#### User Interface + +AuthServer has a simple home page that shows the current user info if the current user has logged in: + +![microservice-sample-authserver-home](../images/microservice-sample-authserver-home.png) + +It also provides Login & Register pages: + +![microservice-sample-authserver-login](../images/microservice-sample-authserver-login.png) + +These pages are not included in the project itself. Instead, AuthServer project uses the prebuilt ABP [account module](https://github.com/abpframework/abp/tree/master/modules/account) with IdentityServer extension. That means it can also act as an OpenId Connect server with necessary UI and logic. + +#### Dependencies + +* **RabbitMQ** for messaging to other services. +* **Redis** for distributed/shared caching. +* **Elasticsearch** for storing logs. + +### Backend Admin Application (BackendAdminApp.Host) + +This is a web application that is used to manage users, roles, permissions and products in the system. + +#### Authentication + +BackendAdminApp redirects to the AuthServer for authentication. Once the user enters a correct username & password, the page is redirected to the backend application again. Authentication configuration is setup in the `BackendAdminAppHostModule` class: + +````charp +context.Services.AddAuthentication(options => +{ + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; +}) +.AddCookie("Cookies", options => +{ + options.Cookie.Expiration = TimeSpan.FromDays(365); + options.ExpireTimeSpan = TimeSpan.FromDays(365); +}) +.AddOpenIdConnect("oidc", options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ClientId = configuration["AuthServer:ClientId"]; + options.ClientSecret = configuration["AuthServer:ClientSecret"]; + options.RequireHttpsMetadata = false; + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.Scope.Add("role"); + options.Scope.Add("email"); + options.Scope.Add("phone"); + options.Scope.Add("BackendAdminAppGateway"); + options.Scope.Add("IdentityService"); + options.Scope.Add("ProductService"); + options.ClaimActions.MapAbpClaimTypes(); +}); +```` + +* It adds "Cookies" authentication as the primary authentication type. +* "oidc" authentication is configured to use the AuthServer application as the authentication server. +* It requires the additional identity scopes *role*, *email* and *phone*. +* It requires the API resource scopes *BackendAdminAppGateway*, *IdentityService* and *ProductService* because it will use these services as APIs. + +IdentityServer client settings are stored inside the `appsettings.json` file: + +````json +"AuthServer": { + "Authority": "http://localhost:64999", + "ClientId": "backend-admin-app-client", + "ClientSecret": "1q2w3e*" +} +```` + +#### User Interface + +The BackendAdminApp.Host project itself has not a single UI element/page. It is only used to serve UI pages of the Identity and Product Management modules. `BackendAdminAppHostModule` adds dependencies to `AbpIdentityWebModule` (*[Volo.Abp.Identity.Web](https://www.nuget.org/packages/Volo.Abp.Identity.Web)* package) and `ProductManagementWebModule` (*ProductManagement.Web* project) for that purpose. + +A screenshot from the user management page: + +![microservice-sample-backend-ui](../images/microservice-sample-backend-ui.png) + +A screenshot from the permission management modal for a role: + +![microservice-sample-backend-ui-permissions](../images/microservice-sample-backend-ui-permissions.png) + +#### Using Microservices + +Backend admin application uses the Identity and Product microservices for all operations, over the Backend Admin Gateway (BackendAdminAppGateway.Host). + +##### Remote End Point + +`appsettings.json` file contains the `RemoteServices` section to declare the remote service endpoint(s). Each microservice will normally have different endpoints. However, this solution uses the API Gateway pattern to provide a single endpoint for the applications: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65115/" + } +} +```` + +`http://localhost:65115/` is the URL of the *BackendAdminAppGateway.Host* project. It knows where are Identity and Product services are located. + +##### HTTP Clients + +ABP application modules generally provides C# client libraries to consume services (APIs) easily (they generally uses the [Dynamic C# API Clients](../AspNetCore/Dynamic-CSharp-API-Clients.md) feature of the ABP framework). That means if you need to consume Identity service API, you can reference to its client package and easily use the APIs by provided interfaces. + +For that purpose, `BackendAdminAppHostModule` class declares dependencies for `AbpIdentityHttpApiClientModule` and `ProductManagementHttpApiClientModule`. + +Once you refer these client packages, you can directly inject an application service interface (e.g. `IIdentityUserAppService`) and use its methods like a local method call. It actually invokes remote service calls over HTTP to the related service endpoint. + +##### Passing the Access Token + +Since microservices requires authentication & authorization, each remote service call should contain an Authentication header. This header is obtained from the `access_token` inside the current `HttpContext` for the current user. This is automatically done when you use the `Volo.Abp.Http.Client.IdentityModel` package. `BackendAdminAppHostModule` declares dependencies to this package and to the related `AbpHttpClientIdentityModelModule` class. It is integrated to the HTTP Clients explained above. + +#### Dependencies + +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Public Web Site (PublicWebSite.Host) + +This is a public web site project that has a web blog and product list page. + +#### Authentication + +PublicWebSite can show blog posts and product list without login. If you login, you can also manage blogs. It redirects to the AuthServer for authentication. Once the user enters a correct username & password, the page is redirected to the public web site application again. Authentication configuration is setup in the `PublicWebSiteHostModule` class: + +```charp +context.Services.AddAuthentication(options => +{ + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; +}) +.AddCookie("Cookies", options => +{ + options.Cookie.Expiration = TimeSpan.FromDays(365); + options.ExpireTimeSpan = TimeSpan.FromDays(365); +}) +.AddOpenIdConnect("oidc", options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ClientId = configuration["AuthServer:ClientId"]; + options.ClientSecret = configuration["AuthServer:ClientSecret"]; + options.RequireHttpsMetadata = false; + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.Scope.Add("role"); + options.Scope.Add("email"); + options.Scope.Add("phone"); + options.Scope.Add("PublicWebSiteGateway"); + options.Scope.Add("ProductService"); + options.Scope.Add("BloggingService"); + options.ClaimActions.MapAbpClaimTypes(); +}); +``` + +- It adds "Cookies" authentication as the primary authentication type. +- "oidc" authentication is configured to use the AuthServer application as the authentication server. +- It requires the additional identity scopes *role*, *email* and *phone*. +- It requires the API resource scopes *PublicWebSiteGateway*, *BloggingService* and *ProductService* because it will use these services as APIs. + +IdentityServer client settings are stored inside the `appsettings.json` file: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ClientId": "public-website-client", + "ClientSecret": "1q2w3e*" +} +``` + +#### User Interface + +The PublicWebSite.Host project has a page to list products (`Pages/Products.cshtml`). It also uses the UI from the blogging module. `PublicWebSiteHostModule` adds dependencies to `BloggingWebModule` (*[Volo.Blogging.Web](https://www.nuget.org/packages/Volo.Blogging.Web)* package) for that purpose. + +A screenshot from the Products page: + +![microservice-sample-public-product-list](../images/microservice-sample-public-product-list.png) + +#### Using Microservices + +Publc web site application uses the Blogging and Product microservices for all operations, over the Public Web Site Gateway (PublicWebSiteGateway.Host). + +##### Remote End Point + +`appsettings.json` file contains the `RemoteServices` section to declare the remote service endpoint(s). Each microservice will normally have different endpoints. However, this solution uses the API Gateway pattern to provide a single endpoint for the applications: + +```json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:64897/" + } +} +``` + +`http://localhost:64897/` is the URL of the *PublicWebSiteGateway.Host* project. It knows where are Blogging and Product services are located. + +##### HTTP Clients + +`PublicWebSiteHostModule` class declares dependencies for `BloggingHttpApiClientModule` and `ProductManagementHttpApiClientModule` to be able to use remote HTTP APIs for these services. + +##### Passing the Access Token + +Just like explained in the Backend Admin Application section, Public Web Site project also uses the `AbpHttpClientIdentityModelModule` to pass `access_token` to the calling services for authentication. + +#### Dependencies + +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Console Client Demo + +Finally, the solution includes a very simple console application, named ConsoleClientDemo, that uses Identity and Product services by authenticating through the AuthServer. It uses the Internal Gateway (InternalGateway.Host) to perform HTTP API calls. + +#### Remote Service Configuration + +`RemoteService` configuration in the `appsettings.json` file is simple: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65129/" + } +} +```` + +`http://localhost:65129/` is the URL of the Internal Gateway. All API calls to the services are performed over this URL. + +#### Authentication (IdentityServer Client) Configuration + +`appsettings.json` also has a configuration for the IdentityServer authentication: + +````json +"IdentityClients": { + "Default": { + "GrantType": "client_credentials", + "ClientId": "console-client-demo", + "ClientSecret": "1q2w3e*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService ProductService" + } +} +```` + +This sample uses the `client_credentials` grant type which requires a `ClientId` and `ClientSecret` for the authentication process. There are also [other grant types](http://docs.identityserver.io/en/latest/topics/grant_types.html). For example, you can use the following configuration to swith to the `password` (Resource Owner Password) grant type: + +````json +"IdentityClients": { + "Default": { + "GrantType": "password", + "ClientId": "console-client-demo", + "ClientSecret": "1q2w3e*", + "UserName": "admin", + "UserPassword": "1q2w3E*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService ProductService" + } +} +```` + +Resource Owner Password requires a `UserName` & `UserPassword` in addition to client credentials. This grant type is useful to call remote services on behalf of a user. + +`Scope` declares the APIs (and the gateway) to grant access. This application uses the Internal Gateway. + +#### HTTP Client Dependencies + +`ConsoleClientDemoModule` has dependencies to `AbpIdentityHttpApiClientModule` and `ProductManagementHttpApiClientModule` in order to use Identity and Product APIs. It also has `AbpHttpClientIdentityModelModule` dependency to authenticate via IdentityServer. + +#### Using the Services + +Using the services is straightforward. See the `ClientDemoService` class which simply injects `IIdentityUserAppService` and `IProductAppService` and uses them. This class also shows a manual HTTP call using an `HttpClient` object. See source code of the `ClientDemoService` for details. + +## API Gateways / BFFs (Backend for Frontend) + +Gateways are used to provide a **single entry point** to the applications. In this way, an application only deal with a single service address (API endpoint) instead of a different addresses for each services. Gateways are also used for rate limiting, security, authentication, load balancing and many more requirements. + +"**Backend for Frontend**" (BFF) is a common architectural pattern which offers to build a **dedicated and specialized** gateway for each different application / client type. This solution uses this pattern and has multiple gateways. + +This solution uses the [Ocelot](https://github.com/ThreeMammals/Ocelot) library to build API Gateways. It's a widely accepted API Gateway library for ASP.NET Core. + +### Backend Admin Application Gateway (BackendAdminAppGateway.Host) + +This is backend (server side API) for the "Backend Admin Application" (don't confuse about the naming; Backend Admin Application is a frontend web application actually, but used by system admins rather than regular users). + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +````csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +```` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `BackendAdminAppGateway` in this case. So, this solution defines gateways as API resources. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +````json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "BackendAdminAppGateway" +} +```` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +````json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/identity/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 63568 + } + ], + "UpstreamPathTemplate": "/api/identity/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:65115" +} +```` + +`ReRoutes` is an array of URL mappings. `BaseUrl` in the `GlobalConfiguration` section is the URL of this gateway (Ocelot needs to know its own URL). See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the configuration. + +Ocelot is a finalizer ASP.NET Core middleware and should be written as the last item in the pipeline: + +````csharp +app.UseOcelot().Wait(); +```` + +It handles and redirects requests based on the configuration above. + +#### ABP Configuration Endpoints + +ABP provides some built-in APIs to get some configuration and information from the server. Examples: + +* `/api/abp/application-configuration` returns localization texts, permission and setting values (try http://localhost:65115/api/abp/application-configuration for this gateway). +* `/Abp/ServiceProxyScript` returns dynamic javascript proxies to call services from a javascript client (try http://localhost:65115/Abp/ServiceProxyScript for this gateway). + +These endpoints should be served by the gateway service, not by microservices. A microservice can only know permissions related to that microservice. But, once properly configured, gateway can aggregate permission values for multiple services as a single list which is more suitable for clients. + +For this purpose, the ASP.NET Core pipeline was configured to handle some specific routes via MVC, instead of Ocelot. To make this possible, MapWhen extension method is used like that: + +````csharp +app.MapWhen(ctx => ctx.Request.Path.ToString().StartsWith("/api/abp/") || + ctx.Request.Path.ToString().StartsWith("/Abp/"), + app2 => + { + app2.UseMvcWithDefaultRouteAndArea(); + }); + +app.UseOcelot().Wait(); +```` + +This configuration uses standard MVC middleware when request path starts with `/api/abp/` or `/Abp/`. + +#### Swagger + +This gateway is configured to use the [swagger UI](https://swagger.io/tools/swagger-ui/), a popular tool to discover & test HTTP APIs. Normally, Ocelot does not support to show APIs on the swagger, because it can not know details of each microservice API. But it is possible when you follow ABP layered module architecture [best practices](../Best-Practices/Index.md). + +`BackendAdminAppGatewayHostModule` adds dependency to `AbpIdentityHttpApiModule` (*[Volo.Abp.Identity.HttpApi](https://www.nuget.org/packages/Volo.Abp.Identity.HttpApi)* package) and `ProductManagementHttpApiModule` (*ProductManagement.HttpApi* project) to include their HTTP API Controllers. In this way, swagger can discover them. While it references to the API layer, it does not reference to the implementation of application services, because they will be running in the related microservice endpoints and redirected by the Ocelot based on the request URL. + +Anyway, when you open the URL `http://localhost:65115/swagger/index.html`, you will see APIs of all configured microservices. + +#### Permission Management + +Backend Admin Application provides a permission management UI (seen before) and uses this gateway to get/set permissions. Permission management API is hosted inside the gateway, instead of a separate service. This is a design decision, but it could be hosted as another microservice if you would like. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Public Web Site Gateway (PublicWebSiteGateway.Host) + +This is backend (server side API gateway) for the "Public Web Site" application. + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `PublicWebSiteGateway` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "PublicWebSiteGateway" +} +``` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +```json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/blogging/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 62157 + } + ], + "UpstreamPathTemplate": "/api/blogging/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:64897" +} +``` + +See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the Ocelot configuration. + +#### Other + +See the "ABP Configuration Endpoints" and "Swagger" topics inside the "Backend Admin Application Gateway" section which are very similar for this gateway. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Internal Gateway (InternalGateway.Host) + +This gateway is not a BFF. It is designed for inter-microservice communication and is not exposed publicly. + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `InternalGateway` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "InternalGateway" +} +``` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +```json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/identity/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 63568 + } + ], + "UpstreamPathTemplate": "/api/identity/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/blogging/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 62157 + } + ], + "UpstreamPathTemplate": "/api/blogging/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:65129" +} +``` + +`ReRoutes` configuration covers all microservices in the system. See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the Ocelot configuration. + +#### Other + +See the "ABP Configuration Endpoints" and "Swagger" topics inside the "Backend Admin Application Gateway" section which are very similar for this gateway. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +## Microservices + +Microservices are standalone HTTP APIs those implement the business of the system in a distributed manner. + +* They are used by applications and other microservices through the gateways and HTTP APIs. +* They can raise or register to events in the system. +* They can communicate to each other via asynchronous messaging. + +### Identity Service (IdentityService.Host) + +This service provides user and role management APIs. + +#### Database + +Shares the same database (MsDemo_Identity) with the AuthServer application. + +#### Identity Module + +This service actually just hosts the ABP Identity package/module. Does not include any API itself. In order to host it, adds the following dependencies: + +* `AbpIdentityHttpApiModule` (*[Volo.Abp.Identity.HttpApi](https://www.nuget.org/packages/Volo.Abp.Identity.HttpApi)* package) to provide Identity APIs. +* `AbpIdentityApplicationModule` (*[Volo.Abp.Identity.Application](https://www.nuget.org/packages/Volo.Abp.Identity.Application)* package) to host the implementation of the application and domain layers of the module. +* `AbpIdentityEntityFrameworkCoreModule` (*[Volo.Abp.Identity.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Abp.Identity.EntityFrameworkCore)* package) to use EF Core as database API. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `IdentityService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "IdentityService" +} +``` + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:63568/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Blogging Service (BloggingService.Host) + +This service hosts the blogging API. + +#### Database + +It has a dedicated MongoDB database (MsDemo_Blogging) to store blog and posts. It also uses the MsDemo_Identity SQL database for audit logs, permissions and settings. So, there are two connection strings in the `appsettings.json` file: + +````json +"ConnectionStrings": { + "Default": "Server=localhost;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true", + "Blogging": "mongodb://localhost|MsDemo_Blogging" +} +```` + +#### Blogging Module + +This service actually just hosts the ABP Blogging package/module. Does not include any API itself. In order to host it, adds the following dependencies: + +- `BloggingHttpApiModule` (*[Volo.Blogging.HttpApi](https://www.nuget.org/packages/Volo.Blogging.HttpApi)* package) to provide Blogging APIs. +- `BloggingApplicationModule` (*[Volo.Blogging.Application](https://www.nuget.org/packages/Volo.Blogging.Application)* package) to host the implementation of the application and domain layers of the module. +- `BloggingMongoDbModule` (*[Volo.Blogging.MongoDB](https://www.nuget.org/packages/Volo.Abp.Identity.EntityFrameworkCore)* package) to use MongoDB as the database. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `BloggingService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "BloggingService" +} +``` + +#### IdentityServer Client + +This microservice also uses the Identity microservice API through the Internal Gateway, because it needs to query user details (username, email, phone, name and surname) in some cases. So, it is also a client for the IdentityServer and defines a section in the `appsettings.json` file for that: + +````json +"IdentityClients": { + "Default": { + "GrantType": "client_credentials", + "ClientId": "blogging-service-client", + "ClientSecret": "1q2w3e*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService" + } +} +```` + +Since it uses the Internal Gateway, it should also configure the remote endpoint of the gateway: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65129/", + "UseCurrentAccessToken": "false" + } +} +```` + +When you set `UseCurrentAccessToken` to `false`, ABP ignores the current `access_token` in the current `HttpContext` and authenticates to the AuthServer with the credentials defined above. + +Why not using the token of the current user in the current request? Because, the user may not have required permissions on the Identity module, so it can not just pass the current authentication token directly to the Identity service. In addition, some of the blog service APIs are anonymous (not requires authenticated user), so in some cases there is no "current user" in the HTTP request. For these reasons, Blogging service should be defined as a client for the Identity service with its own credentials and permissions. + +If you check the `AbpPermissionGrants` table in the `MsDemo_Identity` database, you can see the related permission for the `blogging-service-client`. + +![microservice-sample-blogservice-permission-in-database](../images/microservice-sample-blogservice-permission-in-database.png) + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:62157/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Product Service (ProductService.Host) + +This service hosts the Product Management API. + +#### Database & EF Core Migrations + +It has a separated SQL database, named **MsDemo_ProductManagement**, for the product management module. It uses EF Core as the database provider and has a DbContext named `ProductServiceMigrationDbContext`: + +````csharp +public class ProductServiceMigrationDbContext : AbpDbContext +{ + public ProductServiceMigrationDbContext( + DbContextOptions options + ) : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureProductManagement(); + } +} +```` + +Actual model configuration is done inside the `modelBuilder.ConfigureProductManagement()` extension method. This project maintains the database schema using EF Core migrations. + +Notice that this DbContext is only for database migrations. Product Management module has its own `DbContext` class that is used in the runtime (See `ProductManagementDbContext` class in the ProductManagement.EntityFrameworkCore project). + +There are two connection strings in the `appsettings.json` file: + +````json +"ConnectionStrings": { + "Default": "Server=localhost;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true", + "ProductManagement": "Server=localhost;Database=MsDemo_ProductManagement;Trusted_Connection=True;MultipleActiveResultSets=true" +} +```` + +`Default` connection strings points to the MsDemo_Identity database that is used for audit logging, permission and setting stores. `ProductManagement` connection string is used by the product module. + +#### Product Module + +This service actually just hosts the Product Management module. Does not include any API itself. In order to host it, adds the following dependencies: + +- `ProductManagementHttpApiModule` to provide product management APIs. +- `ProductManagementApplicationModule` to host the implementation of the application and domain layers of the module. +- `ProductManagementEntityFrameworkCoreModule` to use EF Core as database API. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. See the Product Management module section below for more information about this module. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `ProductService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "ProductService" +} +``` + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:60244/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +## Modules + +ABP provides a strong infrastructure to make modular application development easier by providing services and architecture (see the [module development best practices guide](../Best-Practices/Index.md)). + +This solution demonstrate how to use [prebuilt application modules](../Modules/Index.md) in a distributed architecture. The solution also includes a simple "Product Management" module to show the implementation of a well layered module example. + +### Product Management + +Product Management is a module that consists of several layers and packages/projects: + +![microservice-sample-product-module-in-solution](../images/microservice-sample-product-module-in-solution.png) + +* `ProductManagement.Domain.Shared` contains constants and types shared among all layers. +* `ProductManagement.Domain` contains the domain logic and defines entities, domain services, domain events, business/domain exceptions. +* `ProductManagement.Application.Contracts` contains application service interfaces and DTOs. +* `ProductManagement.Application` contains the implementation of application services. +* `ProductManagement.EntityFrameworkCore` contains DbConext and other EF Core related classes and configuration. +* `ProductManagement.HttpApi` contains API Controllers. +* `ProductManagement.HttpApi.Client` contains C# proxies to directly use the HTTP API remotely. Uses [Dynamic C# API Clients](../AspNetCore/Dynamic-CSharp-API-Clients.md) feature of the ABP framework. +* `ProductManagement.Web` contains the UI elements (pages, scripts, styles... etc). + +By the help of this layering, it is possible to use the same module as a package reference in a monolithic application or use as a service that runs in another server. It is possible to separate UI (Web) and API layers, so they run in different servers. + +In this solution, Web layer runs in the Backend Admin Application while API layer is hosted by the Product microservice. + +This tutorial will highlight some important aspects of the module. But, it's suggested to see the source code for a better understanding. + +#### Domain Layer + +`Product` is the main [Aggregate Root](../Entities.md) of this module: + +````csharp +public class Product : AuditedAggregateRoot +{ + /// + /// A unique value for this product. + /// ProductManager ensures the uniqueness of it. + /// It can not be changed after creation of the product. + /// + [NotNull] + public string Code { get; private set; } + + [NotNull] + public string Name { get; private set; } + + public float Price { get; private set; } + + public int StockCount { get; private set; } + + //... +} +```` + +All of its properties have private setters which prevents any direct change of the properties from out of the class. Product class ensures its own integrity and validity by its own constructors and methods. + +It has two constructors: + +````csharp +private Product() +{ + //Default constructor is needed for ORMs. +} + +internal Product( + Guid id, + [NotNull] string code, + [NotNull] string name, + float price = 0.0f, + int stockCount = 0) +{ + Check.NotNullOrWhiteSpace(code, nameof(code)); + + if (code.Length >= ProductConsts.MaxCodeLength) + { + throw new ArgumentException( + $"Product code can not be longer than {ProductConsts.MaxCodeLength}" + ); + } + + Id = id; + Code = code; + SetName(Check.NotNullOrWhiteSpace(name, nameof(name))); + SetPrice(price); + SetStockCountInternal(stockCount, triggerEvent: false); +} + +```` + +Default (**parameterless**) constructor is private and is not used in the application code. It is needed because most ORMs requires a parameterless constructor on deserializing entities while getting from the database. + +Second constructor is **internal** that means it can only be used inside the domain layer. This enforces to use the `ProductManager` while creating a new `Product`. Because, `ProductManager` should implement a business rule on a new product creation. This constructor only requires the minimal required arguments to create a new product with some optional arguments. It checks some simple business rules to ensure that the entity is created as a valid product. + +Rest of the class has methods to manipulate properties of the entity. Example: + +````csharp +public Product SetPrice(float price) +{ + if (price < 0.0f) + { + throw new ArgumentException($"{nameof(price)} can not be less than 0.0!"); + } + + Price = price; + return this; +} + +```` + +`SetPrice` method is used to change the price of the product in a safe manner (by checking a validation rule). + +`SetStockCount` is another method that is used to change stock count of a product: + +````csharp +public Product SetStockCount(int stockCount) +{ + return SetStockCountInternal(stockCount); +} + +private Product SetStockCountInternal(int stockCount, bool triggerEvent = true) +{ + if (StockCount < 0) + { + throw new ArgumentException($"{nameof(stockCount)} can not be less than 0!"); + } + + if (StockCount == stockCount) + { + return this; + } + + if (triggerEvent) + { + AddDistributedEvent( + new ProductStockCountChangedEto( + Id, StockCount, stockCount + ) + ); + } + + StockCount = stockCount; + return this; +} + +```` + +This method also triggers a **distributed event** with the `ProductStockCountChangedEto` parameter (Eto is a conventional postfix stands for **E**vent **T**ransfer **O**bject, but not required) to notify listeners that stock count of a product has changed. Any subscriber can receive this event and perform an action based on that knowledge. + +Events are distributed by RabbitMQ for this solution. But ABP is message broker independent by providing necessary abstractions (see the [Event Bus](../Event-Bus.md) document). + +As said before, this module forces to always use the `ProductManager` to create a new `Product`. `ProductManager` is a simple domain service defined as shown: + +````csharp +public class ProductManager : DomainService +{ + private readonly IRepository _productRepository; + + public ProductManager(IRepository productRepository) + { + _productRepository = productRepository; + } + + public async Task CreateAsync( + [NotNull] string code, + [NotNull] string name, + float price = 0.0f, + int stockCount = 0) + { + var existingProduct = + await _productRepository.FirstOrDefaultAsync(p => p.Code == code); + + if (existingProduct != null) + { + throw new ProductCodeAlreadyExistsException(code); + } + + return await _productRepository.InsertAsync( + new Product( + GuidGenerator.Create(), + code, + name, + price, + stockCount + ) + ); + } +} +```` + +* It checks if given code is used before. Throws `ProductCodeAlreadyExistsException` so. +* If uses the `GuidGenerator` (`IGuidGenerator`) service to create a new `Guid`. +* It inserts the entity to the repository. + +So, with this design, uniqueness of the product code is guaranteed. + +`ProductCodeAlreadyExistsException` is a domain/business exception defined as like below: + +````csharp +public class ProductCodeAlreadyExistsException : BusinessException +{ + public ProductCodeAlreadyExistsException(string productCode) + : base("PM:000001", $"A product with code {productCode} has already exists!") + { + + } +} +```` + +`PM:000001` is a code for the exception type that is sent to the clients, so they can understand the error type. Not implemented for this case, but it is also possible to localize business exceptions. See the [exception handling documentation](../Exception-Handling.md). + +#### Application Layer + +Application layer of this module has two services: + +* `ProductAppService` is mainly used by the Backend Admin Application to manage (create, update, delete...) products. It requires permission to perform any operation. +* `PublicProductAppService` is used by the Public Web Site to show list of products to the visitors. It does not require any permission since most of the visitors are not logged in to the application. + +Notice that; instead of putting two application service into the same project, it might be a better principle to have separated application layers per application. But we unified them for simplicity in this solution. + +As an example, `ProductAppService` has the following method to update a product: + +````csharp +[Authorize(ProductManagementPermissions.Products.Update)] +public async Task UpdateAsync(Guid id, UpdateProductDto input) +{ + var product = await _productRepository.GetAsync(id); + + product.SetName(input.Name); + product.SetPrice(input.Price); + product.SetStockCount(input.StockCount); + + return ObjectMapper.Map(product); +} +```` + +* It defines the required permission (*ProductManagementPermissions.Products.Update* is a constant with value `ProductManagement.Update`) to perform this operation. +* Gets the id of the product and a DTO contains the values to update. +* Gets the related product entity from the repository. +* Uses the related methods (like `SetName`) of the `Product` class to change properties, because they are with private setters and the only way to change a value is to use an entity method. +* Returns an updated `ProductDto` to the client (client may need it for some reason) by using the [ObjectMapper](../Object-To-Object-Mapping.md). + +The implementation may vary based on the requirements. This implementation follows the [best practices offered here](../Best-Practices/Application-Services.md). + +#### Other Layers + +See other layers from the source code. + +## Infrastructure + +### Messaging and RabbitMQ + +Asynchronous Messaging is a key concept in distributed systems. It makes possible to communicate as a loosely coupled manner with fault tolerance. It does not require both sides to be online at the moment of messaging. So, it is a widely used communication pattern in microservice architecture. + +#### Distributed Event Bus + +Distributed Events (Event Bus) is a way of messaging where a service raise/trigger events while other services registers/listens to these events to be notified when an important event occurs. ABP makes distributed events easier to use by providing conventions, services and integrations. + +You have seen that the `Product` class publishing an event using the following code line: + +````csharp +AddDistributedEvent(new ProductStockCountChangedEto(Id, StockCount, stockCount)); +```` + +`ProductStockCountChangedEto` was defined as shown below: + +````csharp +[Serializable] +public class ProductStockCountChangedEto : EtoBase +{ + public Guid Id { get; } + + public int OldCount { get; set; } + + public int CurrentCount { get; set; } + + private ProductStockCountChangedEto() + { + //Default constructor is needed for deserialization. + } + + public ProductStockCountChangedEto(Guid id, int oldCount, int currentCount) + { + Id = id; + OldCount = oldCount; + CurrentCount = currentCount; + } +} +```` + +This object stores necessary information about the event. Another service can easily register to this event by implementing the `IDistributedEventHandler` interface with the generic `ProductStockCountChangedEto` parameter: + +````csharp +public class MyHandler : IDistributedEventHandler +{ + public async Task HandleEventAsync(ProductStockCountChangedEto eventData) + { + var productId = eventData.Id; + //... + } +} +```` + +All the integration and communication are done by the ABP framework when you use the [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) package. If you need to publish events out of an entity, just inject the `IDistributedEventBus` and use the `PublishAsync` method. + +See the [Event Bus](../Event-Bus.md) documentation for more information about the distributed event system. + +#### RabbitMQ Configuration + +In this solution, [RabbitMQ](https://www.rabbitmq.com/) is used for messaging & distributed events. + +[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) package is required to integrate to the RabbitMQ for distributed event system. Then you need to add dependency to the `AbpEventBusRabbitMqModule` for your module. For example, `ProductServiceHostModule` declares this dependency. + +`AbpEventBusRabbitMqModule` gets configuration from the `appsettings.json` by default. For example, the Product Service has such a configuration: + +````json +"RabbitMQ": { + "Connections": { + "Default": { + "HostName": "localhost" + } + }, + "EventBus": { + "ClientName": "MsDemo_ProductService", + "ExchangeName": "MsDemo" + } +} +```` + +### Caching and Redis + +A distributed system obviously needs to a distributed and shared cache, instead of isolated in-memory caches for each service. + +[Redis](https://redis.io/) is used as a distributed cache in this solution. The solution uses Microsoft's standard [Microsoft.Extensions.Caching.Redis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Redis) package for integration. All applications and services uses Redis cache when you use and configure this package. See [Microsoft's documentation](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) for more. + +The solution also uses the [Microsoft.AspNetCore.DataProtection.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.AspNetCore.DataProtection.StackExchangeRedis) package to share data protection keys between applications and services over Redis cache. + +### Logging, Serilog, Elasticsearch and Kibana + +This solution uses [Serilog](https://serilog.net/) as a logging library. It is a widely used library which has many data source integrations including [Elasticsearch](https://www.elastic.co/products/elasticsearch). + +Logging configurations are done in `Program.cs` files using a code block similar to the given below: + +````csharp +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.WithProperty("Application", "ProductService") + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .WriteTo.Elasticsearch( + new ElasticsearchSinkOptions(new Uri(configuration["ElasticSearch:Url"])) + { + AutoRegisterTemplate = true, + AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6, + IndexFormat = "msdemo-log-{0:yyyy.MM}" + }) + .CreateLogger(); +```` + +This configures multiple log target: File and Elasticsearch. `Application` property is set to `ProductService` for this example. This is a way of distinguishing the logs of multiple services in a single database. You can then query logs by the `Application` name. + +Elasticsearch URL is read from the `appsettings.json` configuration file: + +````json +"ElasticSearch": { + "Url": "http://localhost:9200" +} +```` + +If you use Kibana, which is a Visualization tool that is well integrated to Elasticsearch, you can see some fancy UI about your logs: + +![microservice-sample-kibana-2](../images/microservice-sample-kibana-2.png) + +*Figure - A dashboard that shows log and error counts by service/application.* + +![microservice-sample-kibana-1](../images/microservice-sample-kibana-1.png) + +*Figure - A list of log entries* + +Kibana URL is `http://localhost:5601/` by default. + +### Audit Logging + +ABP provides automatic audit logging which saves every request in detail (who is the current user, what is the browser/client, what actions performed, which entities changed, even which properties of entities has been updated). See the [audit logging document](../Audit-Logging.md) for details. + +All of the services and applications are configured to write audit logs. Audit logs are saved to the MsDemo_Identity SQL database. So, you can query all audit logs of all applications from a single point. + +An Audit Log record has a `CorrelationId` property that can be used to track a request. When a service calls another service in a single web request, they both save audit logs with the same `CorrelationId`. See the `AbpAuditLogs` table in the database. \ No newline at end of file diff --git a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md index 9a48022e27..6db6766c0b 100644 --- a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md @@ -82,11 +82,11 @@ namespace Acme.BookStore EF Core requires you to relate entities with your DbContext. The easiest way to do this is to add a `DbSet` property to the `BookStoreDbContext` class in the `Acme.BookStore.EntityFrameworkCore` project, as shown below: ````C# -public class BookStoreDbContext : AbpDbContext -{ - public DbSet Book { get; set; } - ... -} + public class BookStoreDbContext : AbpDbContext + { + public DbSet Book { get; set; } + ... + } ```` #### Add New Migration & Update the Database @@ -236,7 +236,7 @@ namespace Acme.BookStore You normally create **Controllers** to expose application services as **HTTP API** endpoints. Thus allowing browser or 3rd-party clients to call them via AJAX. -ABP can **automagically** configures your application services as MVC API Controllers by convention. +ABP can [**automagically**](../../AspNetCore/Auto-API-Controllers.md) configures your application services as MVC API Controllers by convention. #### Swagger UI diff --git a/docs/en/Virtual-File-System.md b/docs/en/Virtual-File-System.md index 9a27f3c426..c89a2a34ef 100644 --- a/docs/en/Virtual-File-System.md +++ b/docs/en/Virtual-File-System.md @@ -108,7 +108,7 @@ Embedding a file into a module assembly and being able to use it from another pr Let's assume that you're developing a module that contains an embedded JavaScript file. Whenever you change this file you must re-compile the project, re-start the application and refresh the browser page to take the change. Obviously, this is very time consuming and tedious. -What is needed is the ability for the application to directly use the physical file at development time and a have a browser refresh reflect any change made in the JavaScript file. The `ReplaceEmbeddedByPyhsical` method makes all this possible. +What is needed is the ability for the application to directly use the physical file at development time and a have a browser refresh reflect any change made in the JavaScript file. The `ReplaceEmbeddedByPhysical` method makes all this possible. The example below shows an application that depends on a module (`MyModule`) that itself contains embedded files. The application can reach the source code of the module at development time. @@ -124,8 +124,8 @@ public class MyWebAppModule : AbpModule { Configure(options => { - //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project - options.FileSets.ReplaceEmbeddedByPyhsical( + //ReplaceEmbeddedByPhysical gets the root folder of the MyModule project + options.FileSets.ReplaceEmbeddedByPhysical( Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyModuleProject", Path.DirectorySeparatorChar)) ); }); diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index ff05d3934a..905821c73a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -186,10 +186,20 @@ ] }, { - "text": "ASP.NET Core MVC", + "text": "ASP.NET Core", "items": [ { - "text": "API Versioning" + "text": "API", + "items": [ + { + "text": "Auto API Controllers", + "path": "AspNetCore/Auto-API-Controllers.md" + }, + { + "text": "Dynamic C# API Clients", + "path": "AspNetCore/Dynamic-CSharp-API-Clients.md" + } + ] }, { "text": "User Interface", @@ -246,10 +256,23 @@ } ] }, + { + "text": "Samples", + "items": [ + { + "text": "Microservice Demo", + "path": "Samples/Microservice-Demo.md" + } + ] + }, { "text": "Application Modules", "path": "Modules/Index.md" }, + { + "text": "Microservice Architecture", + "path": "Microservice-Architecture.md" + }, { "text": "Testing" }, diff --git a/docs/en/images/bookstore-apis.png b/docs/en/images/bookstore-apis.png new file mode 100644 index 0000000000..aedd79c7f1 Binary files /dev/null and b/docs/en/images/bookstore-apis.png differ diff --git a/docs/en/images/docs-module_download-new-abp-project.png b/docs/en/images/docs-module_download-new-abp-project.png new file mode 100644 index 0000000000..0da3b7a67a Binary files /dev/null and b/docs/en/images/docs-module_download-new-abp-project.png differ diff --git a/docs/en/images/docs-module_download-sample-navigation-menu.png b/docs/en/images/docs-module_download-sample-navigation-menu.png new file mode 100644 index 0000000000..9a1232f198 Binary files /dev/null and b/docs/en/images/docs-module_download-sample-navigation-menu.png differ diff --git a/docs/en/images/docs-module_solution-explorer.png b/docs/en/images/docs-module_solution-explorer.png new file mode 100644 index 0000000000..cafc38f0b0 Binary files /dev/null and b/docs/en/images/docs-module_solution-explorer.png differ diff --git a/docs/en/images/microservice-sample-authserver-home.png b/docs/en/images/microservice-sample-authserver-home.png new file mode 100644 index 0000000000..7ae62ad6d5 Binary files /dev/null and b/docs/en/images/microservice-sample-authserver-home.png differ diff --git a/docs/en/images/microservice-sample-authserver-login.png b/docs/en/images/microservice-sample-authserver-login.png new file mode 100644 index 0000000000..f6e8dfaa9f Binary files /dev/null and b/docs/en/images/microservice-sample-authserver-login.png differ diff --git a/docs/en/images/microservice-sample-backend-ui-permissions.png b/docs/en/images/microservice-sample-backend-ui-permissions.png new file mode 100644 index 0000000000..02769be3e5 Binary files /dev/null and b/docs/en/images/microservice-sample-backend-ui-permissions.png differ diff --git a/docs/en/images/microservice-sample-backend-ui.png b/docs/en/images/microservice-sample-backend-ui.png new file mode 100644 index 0000000000..0935a6047a Binary files /dev/null and b/docs/en/images/microservice-sample-backend-ui.png differ diff --git a/docs/en/images/microservice-sample-blogservice-permission-in-database.png b/docs/en/images/microservice-sample-blogservice-permission-in-database.png new file mode 100644 index 0000000000..f99cd39893 Binary files /dev/null and b/docs/en/images/microservice-sample-blogservice-permission-in-database.png differ diff --git a/docs/en/images/microservice-sample-diagram-2.png b/docs/en/images/microservice-sample-diagram-2.png new file mode 100644 index 0000000000..17aea07098 Binary files /dev/null and b/docs/en/images/microservice-sample-diagram-2.png differ diff --git a/docs/en/images/microservice-sample-diagram.png b/docs/en/images/microservice-sample-diagram.png new file mode 100644 index 0000000000..b1d9f6c66e Binary files /dev/null and b/docs/en/images/microservice-sample-diagram.png differ diff --git a/docs/en/images/microservice-sample-kibana-1.png b/docs/en/images/microservice-sample-kibana-1.png new file mode 100644 index 0000000000..f3a51bd349 Binary files /dev/null and b/docs/en/images/microservice-sample-kibana-1.png differ diff --git a/docs/en/images/microservice-sample-kibana-2.png b/docs/en/images/microservice-sample-kibana-2.png new file mode 100644 index 0000000000..31b281486c Binary files /dev/null and b/docs/en/images/microservice-sample-kibana-2.png differ diff --git a/docs/en/images/microservice-sample-product-module-in-solution.png b/docs/en/images/microservice-sample-product-module-in-solution.png new file mode 100644 index 0000000000..27e841cdd5 Binary files /dev/null and b/docs/en/images/microservice-sample-product-module-in-solution.png differ diff --git a/docs/en/images/microservice-sample-public-product-list.png b/docs/en/images/microservice-sample-public-product-list.png new file mode 100644 index 0000000000..cf8649bbe5 Binary files /dev/null and b/docs/en/images/microservice-sample-public-product-list.png differ diff --git a/docs/en/images/microservice-sample-solution.png b/docs/en/images/microservice-sample-solution.png new file mode 100644 index 0000000000..4c8344ed68 Binary files /dev/null and b/docs/en/images/microservice-sample-solution.png differ diff --git a/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md b/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md new file mode 100644 index 0000000000..afe8ea700b --- /dev/null +++ b/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md @@ -0,0 +1,138 @@ +# 自动API控制器 + +创建[应用程序服务](Application-Services.md)后, 通常需要创建API控制器以将此服务公开为HTTP(REST)API端点. 典型的API控制器除了将方法调用重定向到应用程序服务并使用[HttpGet],[HttpPost],[Route]等属性配置REST API之外什么都不做. + +ABP可以按照惯例 **自动** 将你的应用程序服务配置为MVC API控制器. 大多数时候你不关心它的详细配置,但它可以完全被自定义. + +## 配置 + +基本配置很简单. 只需配置`AbpAspNetCoreMvcOptions`并使用`ConventionalControllers.Create`方法,如下所示: + +````csharp +[DependsOn(BookStoreApplicationModule)] +public class BookStoreWebModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); + }); + } +} +```` + +此示例代码配置包含类`BookStoreApplicationModule`的程序集中的所有应用程序服务.下图显示了[Swagger UI](https://swagger.io/tools/swagger-ui/)上的API内容. + +![bookstore-apis](../images/bookstore-apis.png) + +### 例子 + +一些示例方法名称和按约定生成的相应路由: + +| 服务方法名称 | HTTP Method | 路由 | +| ----------------------------------------------------- | ----------- | -------------------------- | +| GetAsync(Guid id) | GET | /api/app/book/{id} | +| GetListAsync() | GET | /api/app/book | +| CreateAsync(CreateBookDto input) | POST | /api/app/book | +| UpdateAsync(Guid id, UpdateBookDto input) | PUT | /api/app/book/{id} | +| DeleteAsync(Guid id) | DELETE | /api/app/book/{id} | +| GetEditorsAsync(Guid id) | GET | /api/app/book/{id}/editors | +| CreateEditorAsync(Guid id, BookEditorCreateDto input) | POST | /api/app/book/{id}/editor | + +### HTTP Method + +ABP在确定服务方法的HTTP Method时使用命名约定: + +- **Get**: 如果方法名称以`GetList`,`GetAll`或`Get`开头. +- **Put**: 如果方法名称以`Put`或`Update`开头. +- **Delete**: 如果方法名称以`Delete`或`Remove`开头. +- **Post**: 如果方法名称以`Create`,`Add`,`Insert`或`Post`开头. +- **Patch**: 如果方法名称以`Patch`开头. +- 其他情况, **Post** 为 **默认方式**. + +如果需要为特定方法自定义HTTP Method, 则可以使用标准ASP.NET Core的属性([HttpPost], [HttpGet], [HttpPut]... 等等.). 这需要添加[Microsoft.AspNetCore.Mvc.Core](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Core)的Nuget包. + +### 路由 + +路由根据一些惯例生成: + +* 它始终以 **/api**开头. +* 接着是**路由路径**. 默认值为"**/app**", 可以进行如下配置: + +````csharp +Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.RootPath = "volosoft/book-store"; + }); +}); +```` + +然后获得一本书的路由将是'**/api/volosoft/book-store/book/{id}**'. 此示例使用两级根路径,但通常使用单个级别的深度. + +* 接着 **标准化控制器/服务名称**. 会删除`AppService`,`ApplicationService`和`Service`的后缀并将其转换为 **camelCase**. 如果你的应用程序服务类名称为`BookAppService`.那么它将变为`/book`. + * 如果要自定义命名, 则设置`UrlControllerNameNormalizer`选项. 它是一个委托允许你自定义每个控制器/服务的名称. +* 如果该方法具有 '**id**'参数, 则会在路由中添加'**/{id}**'. +* 如有必要,它会添加操作名称. 操作名称从服务上的方法名称获取并标准化; + * 删除'**Async**'后缀. 如果方法名称为'GetPhonesAsync',则变为`GetPhones`. + * 删除**HTTP method前缀**. 基于的HTTP method删除`GetList`,`GetAll`,`Get`,`Put`,`Update`,`Delete`,`Remove`,`Create`,`Add`,`Insert`,`Post`和`Patch`前缀, 因此`GetPhones`变为`Phones`, 因为`Get`前缀和GET请求重复. + * 将结果转换为**camelCase**. + * 如果生成的操作名称为**空**,则它不会添加到路径中.否则它会被添加到路由中(例如'/phones').对于`GetAllAsync`方法名称,它将为空,因为`GetPhonesAsync`方法名称将为`phone`. + * 可以通过设置`UrlActionNameNormalizer`选项来自定义.It's an action delegate that is called for every method. +* 如果有另一个带有'Id'后缀的参数,那么它也会作为最终路线段添加到路线中(例如'/phoneId'). + +## 服务选择 + +创建的HTTP API控制器并不是应用服务所独有的功能. + +### IRemoteService 接口 + +如果一个类实现了`IRemoteService`接口, 那么它会被自动选择为API控制器. 由于应用程序服务本身实现了`IRemoteService`接口, 因此它自然就成为API控制器. + +### RemoteService Attribute + +`RemoteService`可用于将实现`IRemoteService`接口的类标记为远程服务或禁用它. 例如: + +````csharp +[RemoteService(IsEnabled = false)] //or simply [RemoteService(false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +### TypePredicate 选项 + +你可以通过提供`TypePedicate`选项进一步过滤类以成为API控制器: + +````csharp +services.Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.TypePredicate = type => { return true; }; + }); +}); +```` + +如果你不想将此类型公开为API控制器, 则可以在类型检查时返回`false`. + +## API Explorer + +API Explorer是可以由客户端获取API结构的服务. Swagger使用它为endpoint创建文档和test UI. + +默认情况下, HTTP API控制器会自动启用API Explorer, 可以使用`RemoteService`按类或方法的级别控制它. 例如: + +````csharp +[RemoteService(IsMetadataEnabled = false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +禁用`IsMetadataEnabled`从而从API Explorer中隐藏此服务, 并且无法被发现. 但是它仍然可以被知道确切API路径/路由的客户端使用. \ No newline at end of file diff --git a/docs/zh-Hans/AspNetCore/Dynamic-CSharp-API-Clients.md b/docs/zh-Hans/AspNetCore/Dynamic-CSharp-API-Clients.md new file mode 100644 index 0000000000..f964ac9013 --- /dev/null +++ b/docs/zh-Hans/AspNetCore/Dynamic-CSharp-API-Clients.md @@ -0,0 +1,165 @@ +# 动态 C# API 客户端 + +ABP可以自动创建C# API 客户端代理来调用远程HTTP服务(REST APIS).通过这种方式,你不需要通过 `HttpClient` 或者其他低级的HTTP功能调用远程服务并获取数据. + +## 服务接口 + +你的service或controller需要实现一个在服务端和客户端共享的接口.因此,首先需要在一个共享的类库项目中定义一个服务接口.例如: + +````csharp +public interface IBookAppService : IApplicationService +{ + Task> GetListAsync(); +} +```` + +为了能自动被发现,你的接口需要实现`IRemoteService`接口.由于`IApplicationService`继承自`IRemoteService`接口.所以`IBookAppService`完全满足这个条件. + +在你的服务中实现这个类,你可以使用[auto API controller system](Auto-API-Controllers.md)将你的服务暴漏为一个REST API 端点. + +## 客户端代理生成 + +首先,将[Volo.Abp.Http.Client](https://www.nuget.org/packages/Volo.Abp.Http.Client) nuget包添加到你的客户端项目中: + +```` +Install-Package Volo.Abp.Http.Client +```` + +然后给你的模块添加`AbpHttpClientModule`依赖: + +````csharp +[DependsOn(typeof(AbpHttpClientModule))] //添加依赖 +public class MyClientAppModule : AbpModule +{ +} +```` + +现在,已经可以创建客户端代理了.例如: + +````csharp +[DependsOn( + typeof(AbpHttpClientModule), //用来创建客户端代理 + typeof(BookStoreApplicationModule) //包含应用服务接口 + )] +public class MyClientAppModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + //创建动态客户端代理 + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly + ); + } +} +```` + +`AddHttpClientproxies`方法获得一个程序集,找到这个程序集中所有的服务接口,创建并注册代理类. + +### Endpoint配置 + +`appsettings.json`文件中的`RemoteServices`节点被用来设置默认的服务地址.下面是最简单的配置: + +```` +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + } + } +} +```` + +查看下面的"RemoteServiceOptions"章节获取更多详细配置. + +## 使用 + +可以很直接地使用.只需要在你的客户端程序中注入服务接口: + +````csharp +public class MyService : ITransientDependency +{ + private readonly IBookAppService _bookService; + + public MyService(IBookAppService bookService) + { + _bookService = bookService; + } + + public async Task DoIt() + { + var books = await _bookService.GetListAsync(); + foreach (var book in books) + { + Console.WriteLine($"[BOOK {book.Id}] Name={book.Name}"); + } + } +} +```` + +本例注入了上面定义的`IBookAppService`服务接口.当客户端调用服务方法的时候动态客户端代理就会创建一个HTTP调用. + +### IHttpClientProxy接口 + +你可以像上面那样注入`IBookAppService`来使用客户端代理,也可以注入`IHttpClientProxy`获取更多明确的用法.这种情况下你可以使用`IHttpClientProxy`接口的`Service`属性. + +## 配置 + +### RemoteServiceOptions + +默认情况下`RemoteServiceOptions`从`appsettings.json`获取.或者,你可以使用`Configure`方法来设置或重写它.如: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + context.Services.Configure(options => + { + options.RemoteServices.Default = + new RemoteServiceConfiguration("http://localhost:53929/"); + }); + + //... +} +```` + +### 多个远程服务端点 + +上面的例子已经配置了"Default"远程服务端点.你可能需要为不同的服务创建不同的端点.(就像在微服务方法中一样,每个微服务具有不同的端点).在这种情况下,你可以在你的配置文件中添加其他的端点: + +````json +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + }, + "BookStore": { + "BaseUrl": "http://localhost:48392/" + } + } +} +```` + +`AddHttpClientProxies`方法有一个可选的参数来定义远程服务的名字: + +````csharp +context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly, + remoteServiceName: "BookStore" +); +```` + +`remoteServiceName`参数会匹配通过`RemoteServiceOptions`配置的服务端点.如果`BookStore`端点没有定义就会使用默认的`Default`端点. + +### 作为默认服务 + +当你为`IBookAppService`创建了一个服务代理,你可以直接注入`IBookAppService`来使用代理客户端(像上面章节中将的那样).你可以传递`asDefaultService:false`到`AddHttpClientProxies`方法来禁用此功能. + +````csharp +context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly, + asDefaultServices: false +); +```` + +如果你的程序中已经有一个服务的实现并且你不想用你的客户端代理重写或替换其他的实现,就需要使用`asDefaultServices:false` + +> 如果你禁用了`asDefaultService`,你只能使用`IHttpClientProxy`接口去使用客户端代理.(参见上面的相关章节). \ No newline at end of file diff --git a/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md b/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md new file mode 100644 index 0000000000..69a8603baf --- /dev/null +++ b/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md @@ -0,0 +1,54 @@ +# 微服务演示,项目状态和路线图 + +在ABP vNext上的[第一个公告](https://cn.abp.io/blog/abp/Abp-vNext-Announcement)之后,我们对代码库进行了很多改进([GitHub存储库](https://github.com/abpframework/abp)上的1100多次提交).我们已经创建了功能,示例,文档等等.在这篇文章中,我想告诉你一些新闻和项目的状态. + +## 微服务演示解决方案 + +ABP框架的主要目标之一是提供[创建微服务解决方案的便利基础设施](https://cn.abp.io/documents/abp/latest/Microservice-Architecture). + +我们一直在努力开发微服务解决方案演示.初始版本已完成并[文档化](https://cn.abp.io/documents/abp/latest/Samples/Microservice-Demo).该示例解决方案旨在演示一个简单而完整的微服务解决方案; + +- 具有多个独立的,可自我部署的**微服务**. +- 多个**Web应用程序**,每个都使用不同的API网关. +- 使用[Ocelot](https://github.com/ThreeMammals/Ocelot)库开发了多个**网关** / BFF(后端为前端(Backend for Frontends)). +- 使用[IdentityServer](https://identityserver.io/)框架开发**身份验证服务**.它也是一个带有必要UI的SSO(单点登录)应用程序. +- 有**多个数据库**.一些微服务有自己的数据库,而一些服务/应用程序共享一个数据库(以演示不同的用例). +- 具有不同类型的数据库:**SQL Server**(使用**Entity Framework Core** ORM)和**MongoDB**. +- 有一个**控制台应用程序**来显示通过身份验证使用服务的最简单方法. +- 使用[Redis](https://redis.io/)进行**分布式缓存**. +- 使用[RabbitMQ](https://www.rabbitmq.com/)进行服务到服务(service-to-service)的**消息传递**. +- 使用[Docker](https://www.docker.com/)和[Kubernates](https://kubernetes.io/)**部署**并运行所有服务和应用程序. +- 使用[Elasticsearch](https://www.elastic.co/products/elasticsearch)和[Kibana](https://www.elastic.co/products/kibana)存储和可视化日志(使用[Serilog](https://serilog.net/)编写). + +有关解决方案的详细说明,请参阅[其文档](https://cn.abp.io/documents/abp/latest/Samples/Microservice-Demo). + +## 改进/功能 + +我们已经开发了许多功能,包括**分布式事件总线**(与RabbitMQ集成),**IdentityServer4集成**以及几乎所有功能的增强.我们不断重构和添加测试,以使框架更稳定和生产就绪.它正在[快速增长](https://github.com/abpframework/abp/graphs/contributors). + +## 路线图 + +在第一个稳定版本(v1.0)之前还有很多工作要做.您可以在GitHub仓库上看到[优先的积压项目](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog). + +根据我们的估计,我们计划在2019年第二季度(可能在五月或六月)发布v1.0.所以,不用等待太长时间了.我们也对第一个稳定版本感到非常兴奋. + +我们还将完善[文档](https://cn.abp.io/documents/abp/latest),因为它现在还远未完成. + +第一个版本可能不包含SPA模板.但是,如果可能的话,我们想要准备一个简单些的.SPA框架还没有确定下来.备选有:**Angular,React和Blazor**.请将您的想法写为对此帖的评论. + +## 中文网 + +中国有一个大型的ABP社区.他们创建了一个中文版的abp.io网站:https://cn.abp.io/. 他们一直在保持更新.感谢中国的开发人员,特别是[Liming Ma](https://github.com/maliming). + +## NDC {London} 2019 + +很高兴作为合作伙伴参加[NDC {London}](https://ndc-london.com/)2019 .我们已经与许多开发人员讨论过当前的ASP.NET Boilerplate和ABP vNext,我们得到了很好的反馈. + +我们还有机会与[Scott Hanselman](https://twitter.com/shanselman)和[Jon Galloway](https://twitter.com/jongalloway)交谈.他们参观了我们的展位,我们谈到了ABP vNext的想法.他们喜欢新的ABP框架的功能,方法和目标.在twitter上查看一些照片和评论: + +![scott-and-jon](scott-and-jon.png) + +## 跟上步伐 + +* 您可以标星并关注**GitHub**存储库:https://github.com/abpframework/abp +* 您可以关注官方**Twitter**帐户获取新闻:https://twitter.com/abpframework diff --git a/docs/zh-Hans/Blog-Posts/2019-02-22/scott-and-jon.png b/docs/zh-Hans/Blog-Posts/2019-02-22/scott-and-jon.png new file mode 100644 index 0000000000..79ad21aee7 Binary files /dev/null and b/docs/zh-Hans/Blog-Posts/2019-02-22/scott-and-jon.png differ diff --git a/docs/zh-Hans/Domain-Services.md b/docs/zh-Hans/Domain-Services.md new file mode 100644 index 0000000000..181efe0c43 --- /dev/null +++ b/docs/zh-Hans/Domain-Services.md @@ -0,0 +1,3 @@ +# ABP Documentation + +待添加 diff --git a/docs/zh-Hans/Dynamic-Proxying-Interceptors.md b/docs/zh-Hans/Dynamic-Proxying-Interceptors.md new file mode 100644 index 0000000000..6657f1ca33 --- /dev/null +++ b/docs/zh-Hans/Dynamic-Proxying-Interceptors.md @@ -0,0 +1,3 @@ +## Dynamic Proxying / Interceptors + +待添加 diff --git a/docs/zh-Hans/Event-Bus.md b/docs/zh-Hans/Event-Bus.md new file mode 100644 index 0000000000..0adb56101d --- /dev/null +++ b/docs/zh-Hans/Event-Bus.md @@ -0,0 +1,3 @@ +# Event Bus + + TODO \ No newline at end of file diff --git a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md index d0733bb140..cf9ac3f66f 100644 --- a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md +++ b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md @@ -156,6 +156,26 @@ services.AddApplication(options => }); ```` +4. 更新 `Program.cs`代码, 不再使用`WebHost.CreateDefaultBuilder()`方法(因为它使用默认的DI容器): + + ````csharp +public class Program +{ + public static void Main(string[] args) + { + BuildWebHostInternal(args).Run(); + } + public static IWebHost BuildWebHostInternal(string[] args) => + new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); +} +```` + + ### 源码 从[此处](../samples/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码. diff --git a/docs/zh-Hans/Guid-Generation.md b/docs/zh-Hans/Guid-Generation.md new file mode 100644 index 0000000000..be0c1f425b --- /dev/null +++ b/docs/zh-Hans/Guid-Generation.md @@ -0,0 +1,3 @@ +## Guid 生成 + +待添加 diff --git a/docs/zh-Hans/Microservice-Architecture.md b/docs/zh-Hans/Microservice-Architecture.md new file mode 100644 index 0000000000..166591e779 --- /dev/null +++ b/docs/zh-Hans/Microservice-Architecture.md @@ -0,0 +1,30 @@ +# 微服务架构 + +*"作为**面向服务架构**(SOA)的一个变体,微服务是一种将应用程序分解成**松散耦合服务**的新型架构风格. 通过**细粒度**的服务和**轻量级**的协议,微服务提供了更多的**模块化**,使应用程序更容易理解,开发,测试,并且更容易抵抗架构侵蚀. 它使小型团队能够**开发,部署和扩展**各自的服务,实现开发的**并行化**.它还允许通过**连续重构**形成单个服务的架构. 基于微服务架构可以实现**持续交付和部署**."* + +— [维基百科](https://zh.wikipedia.org/wiki/Microservices) + +## 介绍 + +ABP框架的主要目标之一就是提供**便捷的基础设施来创建微服务解决方案**. 我们做了以下工作: + +* 提供[模块系统](Module-Development-Basics.md),允许将应用程序拆分为模块,其中每个模块可以拥有自己的数据库,实体,服务,API,UI组件/页面....等. +* 提供[架构模型](Best-Practices/Module-Architecture.md)来开发模块,与微服务开发和部署兼容. +* 提供[最佳实践指南](Best-Practices/Index.md)制定模块开发标准. +* 提供基础设施来实现微服务中的[领域驱动设计](Domain-Driven-Design.md). +* 提供从应用程序服务[自动生成REST风格的API](AspNetCore/Auto-API-Controllers.md)的服务. +* 提供[自动创建C#API客户端](AspNetCore/Dynamic-CSharp-API-Clients.md)服务,以便从其他服务/应用程序使用你服务. +* 提供[分布式事件总线](Event-Bus.md)用于服务通信. +* 提供更多其他服务,使日常开发更加简便. + +## 在新应用程序中使用微服务 + +开始一个新解决方案建议**始终从单体开始**, 保持模块化,在单体成为问题时将其拆分为微服务.这使初期进度会很快,特别是如果你的团队人数不多,并且不想处理微服务架构带来的各种挑战. + +然而开发一个良好的模块化应用程序不是那么简单,因为很难像微服务那样**保持模块之间的隔离** (参阅 [Stefan Tilkov的文章](https://martinfowler.com/articles/dont-start-monolith.html)). 微服务架构会自然的让你开发隔离的服务,但是在模块化的单体应用程序中,模块很容易彼此紧密耦合并设计出**弱模块边界**和API约定. + +ABP可以帮助你,它提供了与**与微服务兼容的严格模块架构** 在这个架构中你的模块被分割成多个层/项目,在自己的VS解决方案中进行开发,该解决方案完成独立于其它模块. 这种方式开发的模块是一种天然的微服务,但是它可以很容易的插入到单体应用程序中. 请参阅**微服务优先的模块设计**的[模块开发最佳实践指南](Best-Practices/Index.md). 所有[标准的ABP模块](https://github.com/abpframework/abp/tree/master/modules)都是基于本指南开发的. 因此你可以将这些模块嵌入到单体解决方案中使用它们,也可以单独部署通过远程API调用. 它们可以共享一个数据库,也可以通过简单配置使用自己的数据库. + +## 微服务解决方案示例 + +[微服务解决方案示例](Samples/Microservice-Demo.md)演示了基于ABP框架的完整的微服务的解决方案. \ No newline at end of file diff --git a/docs/zh-Hans/Module-Development-Basics.md b/docs/zh-Hans/Module-Development-Basics.md index 044016e17a..9feaa8c7f9 100644 --- a/docs/zh-Hans/Module-Development-Basics.md +++ b/docs/zh-Hans/Module-Development-Basics.md @@ -125,3 +125,10 @@ public class BlogModule 你可以根据需要使用多个``DependsOn``属性或将多个模块类型传递给单个``DependsOn``属性. 依赖模块可能依赖于另一个模块,但你只需要定义直接依赖项.ABP在启动时会调查应用程序的依赖关系,并以正确的顺序初始化/关闭模块. + +## 框架模块 vs 应用程序模块 + +**模块分为两种类型.** 这两种类型并没有任何结构上的区别,只是按功能和用途分类: + +- **框架模块**: 这些是**框架的核心模块** 如缓存, 邮件, 主题, 安全, 序列化, 验证, EF Core集成, MongoDB集成... 等. 它们没有应用/业务功能,它们提供了日常开发经常用到的基础设施,集成和抽象. +- **应用程序模块**: 这些模块实现了 **特定的应用/业务功能** 像博客, 文档管理, 身份管理, 租房管理... 等等. 它们通过有自己的实体,服务,API和UI组件. 请参阅 [预构建的应用程序模块](Modules/Index.md). diff --git a/docs/zh-Hans/Modules/Docs.md b/docs/zh-Hans/Modules/Docs.md new file mode 100644 index 0000000000..cfe287082b --- /dev/null +++ b/docs/zh-Hans/Modules/Docs.md @@ -0,0 +1,467 @@ +# 文档模块 + +## 什么是文档模块? + +文档模块是ABP框架的一个应用程序模块. 它简化了软件文档的制作. 这个模块是开源免费的. + +### 集成 + +目前文档模块提供提供了两种支持的存储,Github与文件系统. + +### 托管 + +文档模块是一个应用程序模块,不提供任何托管的解决方案,你可以在本地或云上托管文档. + +### 版本 + +当你使用GitHub存储文档时,文档模块支持多版本. 如果你的文档具有多个版本, UI上有一个组合框,用于切换版本. 如果你选择使用文件系统存储文档, 那么它不支持多版本. + +ABP框架的[文档](https://abp.io/documents/)也是使用的此模块. + +> 文档模块遵循 [模块化架构最佳实践](../Best-Practices/Module-Architecture.md) 指南. + + + +## 安装 + +### 1- 下载 + +如果你没有现有的ABP项目, 这个步骤向你展示如何在[abp.io](https://cn.abp.io)创建一个新项目并添加文档模块. 如果你本地已经有了一个ABP项目, 那么你可以跳过这一步. + +打开 https://cn.abp.io/Templates. 输入项目名称为 `Acme.MyProject`, 选择 `ASP.NET Core Mvc Application` 和选择 `Entity Framework Core` 做为数据库提供者. + +请注意,本文档包含了 `Entity Framework Core` 提供者 不过你也可以选择 `MongoDB` 做为数据库提供者. + +![创建新项目](../images/docs-module_download-new-abp-project.png) + +### 2- 运行这个空项目 + +下载项目后, 解压压缩文档并且打开 `Acme.MyProject.sln`. 你可以看到这个解决方案包含了 `Application`, `Domain `, `EntityFrameworkCore` 和 `Web` 项目. 右键选择 `Acme.MyProject.Web` 项目**设置为启动项目**. + +![创建新项目](../images/docs-module_solution-explorer.png) + +数据库连接字符串位于`Acme.MyProject.Web`项目的`appsettings.json`中. 如果你有不同的数据库配置, 可以修改这个连接字符串. + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost;Database=MyProject;Trusted_Connection=True;MultipleActiveResultSets=true" + } +} +``` + +打开Visual Studio包管理控制台选择`src\Acme.MyProject.EntityFrameworkCore` 做为默认项目. 运行 `Update-Database` 命令创建数据库. 数据库`MyProject`将在数据库服务器中创建. + +现在一个空的ABP项目已经创建完成! 现在你可以运行项目并且查看网站. + +输入用户名 `admin` 密码 `1q2w3E*` 登录到网站. + +### 2- 引用文档模块包 + +文档模块包托管在Nuget上面. 需要有四个包安装到你的应用程序中. 每个包必须安装到相关的项目. + +* [Volo.Docs.Domain](https://www.nuget.org/packages/Volo.Docs.Domain/) 需要安装到 `Acme.MyProject.Domain` 项目. + + * 修改 `Acme.MyProject.Domain.csproj` 文件并且添加以下行. 需要注意它要设置(v0.9.0)为Latest版本. + + ```csharp + + ``` +* [Volo.Docs.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Docs.EntityFrameworkCore/) 需要安装到 `Acme.MyProject.EntityFrameworkCore` 项目. + + - 修改 `Acme.MyProject.EntityFrameworkCore.csproj`文件并且添加以下行. 需要注意它要设置(v0.9.0)为Latest版本. + + ```csharp + + ``` +* [Volo.Docs.Application](https://www.nuget.org/packages/Volo.Docs.Application/) 需要安装到 `Acme.MyProject.Application` 项目. + + * 修改 `Acme.MyProject.Application.csproj`文件并且添加以下行. 需要注意它要设置(v0.9.0)为Latest版本. + + ```csharp + + ``` +* [Volo.Docs.Web ](https://www.nuget.org/packages/Volo.Docs.Web/) 需要安装到 `Acme.MyProject.Web` 项目. + + - 修改 `Acme.MyProject.Web.csproj`文件并且添加以下行. 需要注意它要设置(v0.9.0)为Latest版本. + + ```csharp + + ``` + + + +### 3- 添加模块添加 + +一个ABP模块必须声明 `[DependsOn]` attribute 如果它依赖于另一个模块. 每个模块都必须在相关的项目的`[DependsOn]`Attribute 中添加. + +* 打开 `MyProjectDomainModule.cs`并且添加 `typeof(DocsDomainModule)` 如下所示; + + ```csharp + [DependsOn( + typeof(DocsDomainModule), + typeof(AbpIdentityDomainModule), + typeof(AbpAuditingModule), + typeof(BackgroundJobsDomainModule), + typeof(AbpAuditLoggingDomainModule) + )] + public class MyProjectDomainModule : AbpModule + { + //... + } + ``` + +* 打开 `MyProjectEntityFrameworkCoreModule.cs`并且添加 `typeof(DocsEntityFrameworkCoreModule)` 如下所示; + + ```csharp + [DependsOn( + typeof(DocsEntityFrameworkCoreModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(BackgroundJobsEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule) + )] + public class MyProjectEntityFrameworkCoreModule : AbpModule + { + //... + } + ``` + + +* 打开 `MyProjectApplicationModule.cs`并且添加 `typeof(DocsApplicationModule)` 如下所示; + + ```csharp + [DependsOn( + typeof(DocsApplicationModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityApplicationModule))] + public class MyProjectApplicationModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefinitionProviders.Add(); + }); + + Configure(options => + { + options.AddProfile(); + }); + } + } + ``` + + +* 打开 `MyProjectWebModule.cs`并且添加 `typeof(DocsWebModule)` 如下所示; + + ```csharp + [DependsOn( + typeof(DocsWebModule), + typeof(MyProjectApplicationModule), + typeof(MyProjectEntityFrameworkCoreModule), + typeof(AbpAutofacModule), + typeof(AbpIdentityWebModule), + typeof(AbpAccountWebModule), + typeof(AbpAspNetCoreMvcUiBasicThemeModule) + )] + public class MyProjectWebModule : AbpModule + { + //... + } + ``` + + + +### 4- 数据库集成 + +#### 4.1- Entity Framework 集成 + +如果你选择了Entity Framework 做为数据库供应者,你需要在DbContext中配置文档模块. 做以下操作; + +- 打开 `MyProjectDbContext.cs` 并且添加 `modelBuilder.ConfigureDocs()` 到 `OnModelCreating()` 方法中 + + ```csharp + [ConnectionStringName("Default")] + public class MyProjectDbContext : AbpDbContext + { + public MyProjectDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //... + modelBuilder.ConfigureDocs(); + } + } + ``` + +* 打开 `Visual Studio` 的 `包管理控制台` 选择 `Acme.MyProject.EntityFrameworkCore` 做为默认项目. 然后编写以下命令为文档模块添加迁移. + + ```csharp + add-migration Added_Docs_Module + ``` + + 当命令执行成功后 , 你会看到`Acme.MyProject.EntityFrameworkCore\Migrations` 目录下有名为 `20181221111621_Added_Docs_Module` 的迁移文件. + + 现在更新数据库. 在 `Visual Studio` 的 `包管理控制台` 中执行以下代码. 要确认已 `Acme.MyProject.EntityFrameworkCore` 项目设置为默认项目. + + ```csharp + update-database + ``` + + 最后你可以查看数据库中创建的新表,例如你可以看到 `DocsProjects` 表已经添加到数据库中. + + +### 5- 链接文档模块 + +文档模块的默认路由是; + +``` +/Documents +``` + +添加文档模块的链接到你的应用程序菜单中; + +* 打开 `MyProjectMenuContributor.cs` 并且在 `ConfigureMainMenuAsync()` 方法方法中添加以下代码. + + ```csharp + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + ``` + + 最后 **MyProjectMenuContributor.cs** 有以下内容 + + ```csharp + private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + { + var l = context.ServiceProvider.GetRequiredService>(); + + context.Menu.Items.Insert(0, new ApplicationMenuItem("MyProject.Home", l["Menu:Home"], "/")); + + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + } + ``` + +`Menu:Docs` 关键词是本地化的Key. 要本地化菜单文本, 打开`Acme.MyProject.Domain` 中的 `Localization\MyProject\zh-Hans.json`. 添加以下行. + +```json +"Menu:Docs": "文档" +``` + +最后 **zh-Hans.json** 有以下内容 + +```json +{ + "culture": "zh-Hans", + "texts": { + "Menu:Home": "首页", + "Welcome": "欢迎", + "LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 cn.abp.io.", + "Menu:Docs": "文档" + } +} +``` + +现在菜单中已经添加了文档模块项. 运行Web应用程序并且在浏览器中打开 `http://localhost:YOUR_PORT_NUMBER/documents` URL. + +你会看到一个警告; + +``` +There are no projects yet! +``` + +这个警告是正常的,因为我们还没有添加任何项目. + +### 6- 添加文档项目 + +在数据库中打开 `DocsProjects`, 并且插入包含以下字段的新记录; + +* **Name**: 在Web页面上文档的显示名称. +* **ShortName**: 在文档URL中使用的友好的简短URL名称. +* **Format**: 文档的格式 ( Markdown: `md`, HTML: `html`) +* **DefaultDocumentName**: 文档的初始页面. +* **NavigationDocumentName**: 导航菜单(索引)的文档. +* **MinimumVersion**: 显示文档的最低版本. 低于此的版本不会列出. +* **DocumentStoreType**: 文档的来源 ( GitHub:`GitHub`,文件系统`FileSystem`). +* **ExtraProperties**: 序列化的`JSON`, 它存储所选 `DocumentStoreType` 的特殊配置. +* **MainWebsiteUrl**: 用户单击文档模块页面Logo时跳转的URL.你只需设置为`/`即可链接到网站根地址. +* **LatestVersionBranchName**: 这是GitHub的配置.它是检索文档的分支名称.你可以将其设置为`master`. + +#### "GitHub" 项目的示例记录 + +你可以使用 [ABP Framework](https://github.com/abpframework/abp/) GitHub文档来配置Github文档存储. + +- Name: `ABP framework (GitHub)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `GitHub` + +- ExtraProperties: + + ```json + {"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/zh-Hans/","GitHubAccessToken":"***"} + ``` + + 注意 `GitHubAccessToken` 用 `***` 掩盖. 这是一个私人令牌,你必须从GitHub获取它. 请参阅 https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `master` + +对于 `SQL` 数据库,你可以使用下面的 `T-SQL` 命令将指定的示例插入到 `DocsProjects` 表中: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939658', N'ABP framework (GitHub)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'GitHub', N'{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/zh-Hans/","GitHubAccessToken":"***"}', N'/', N'master') +``` + +请注意,`GitHubAccessToken` 被屏蔽了.它是一个私人令牌,你必须获得自己的令牌并替换 `***` 字符串. + +#### "FileSystem" 项目的示例记录 + +你可以使用 [ABP Framework](https://github.com/abpframework/abp/) GitHub文档来配置你的文件系统存储. + +- Name: `ABP framework (FileSystem)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `FileSystem` + +- ExtraProperties: + + ```json + {"Path":"C:\\Github\\abp\\docs\\zh-Hans"} + ``` + + 请注意 `Path` 必须使用本地docs目录替换. 你可以从https://github.com/abpframework/abp/tree/master/docs/zh-hans获取ABP Framework的文档并且复制到该目录 `C:\\Github\\abp\\docs\\zh-Hans` 使其正常工作. + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `` + +对于 `SQL` 数据库,你可以使用下面的 `T-SQL` 命令将指定的示例插入到 `DocsProjects` 表中: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939659', N'ABP framework (FileSystem)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'FileSystem', N'{"Path":"C:\\Github\\abp\\docs\\zh-Hans"}', N'/', NULL) +``` + +添加上面的一个示例项目后运行该应用程序. 在菜单中你会看到`文档` 链接,点击菜单链接打开文档页面. + +到目前为止, 我们已经从abp.io网站创建了一个新的应用程序,并为Docs模块做好准备. + +### 7- 添加一个新文档 + +在示例项目记录中, 你可以看到 `Format` 被指定为 `md` 指的是 [Mark Down](https://en.wikipedia.org/wiki/Markdown). 你可以打开下面的链接查看语法; + +https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet + +ABP文档模块可以把MarkDown渲染为HTML. + +现在让我们看一下Markdown格式的示例文档. + +~~~markdown +# This is a header + +Welcome to Docs Module. + +## This is a sub header + + [This is a link](https://abp.io) + +![This is an image](https://abp.io/assets/my-image.png) + +## This is a code block + +```csharp +public class Person +{ + public string Name { get; set; } + + public string Address { get; set; } +} +``` +~~~ + +你可以使用 ABP Framework 的文档做为示例: + +[https://github.com/abpframework/abp/blob/master/docs/zh-Hans/](https://github.com/abpframework/abp/blob/master/docs/zh-Hans/) + +### 8- 创建文档导航 + +导航文档是文档页面的主菜单. 它位于页面的左侧,是一个`JSON` 文件. 请查看以下示例导航文档以了解结构. + +```json +{ + "items":[ + { + "text":"Sample Menu Item - 1", + "items":[ + { + "text":"Sample Menu Item - 1.1", + "items":[ + { + "text":"Sample Menu Item - 1.1.1", + "path":"SampleMenuItem_1_1_1.md" + } + ] + }, + { + "text":"Sample Menu Item - 1.2", + "items":[ + { + "text":"Sample Menu Item - 1.2.1", + "path":"SampleMenuItem_1_2_1.md" + }, + { + "text":"Sample Menu Item - 1.2.2", + "path":"SampleMenuItem_1_2_2.md" + } + ] + } + ] + }, + { + "text":"Sample Menu Item - 2", + "items":[ + { + "text":"Sample Menu Item - 2.1", + "items":[ + { + "text":"Sample Menu Item - 2.1.1", + "path":"SampleMenuItem_2_1_1.md" + } + ] + } + ] + } + ] +} +``` + +上面的示例 `JSON` 文件将下面的导航菜单呈现为 `HTML` . + +![Navigation menu](../images/docs-module_download-sample-navigation-menu.png) + +最后,为您的项目添加了一个新的Docs模块, 该模块由GitHub提供. \ No newline at end of file diff --git a/docs/zh-Hans/Modules/Index.md b/docs/zh-Hans/Modules/Index.md new file mode 100644 index 0000000000..8e5edf35b6 --- /dev/null +++ b/docs/zh-Hans/Modules/Index.md @@ -0,0 +1,26 @@ +# 应用程序模块 + +ABP是一个 **模块化的应用程序框架** 由十多个 **nuget packages** 组成. 它提供了一个完整的基础设施来构建你自己的应用程序模块,这些模块包含实体,服务,数据库集成,API,UI组件等. + +**有两种类型的模块.** 它们没有任何结构上的差异,只是按照功能和目地分类: + +* [**框架模块**](https://github.com/abpframework/abp/tree/master/framework/src): 这些是 **框架的核心模块**,像缓存,邮件,主题,安全性,序列化,验证,Ef Core集成,MongoDB集成...等等. 它们没有应用程序/业务功能,但通过提供通用基础架构,集成和抽象会使你的日常开发更加容易. +* [**应用程序模块**](https://github.com/abpframework/abp/tree/master/modules): 这些模块是实现特定的应用程序/业务功能,像 博客, 文档管理, 身份管理, 租户管理... 等等. 它是通常有自己的实体,服务,API和UI组件. + +## 开源的应用程序模块 + +有一些由ABP社区开发和维护的 **开源免费** 的应用程序模块: + +* **Account**: 用于用户登录/注册应用程序. +* **Audit Logging**: 用于将审计日志持久化到数据库. +* **Background Jobs**: 用于在使用默认后台作业管理器时保存后台作业. +* **Blogging**: 用于创建精美的博客. ABP的[博客](https://abp.io/blog/abp/) 就使用了此模块. +* [**Docs**](Docs.md): 用于创建技术文档页面. ABP的[文档](https://abp.io/documents/) 就使用了此模块. +* **Identity**: 用于管理角色,用户和他们的权限. +* **Identity Server**: 集成了IdentityServer4. +* **Permission Management**: 用于保存权限. +* **Setting Management**: 用于保存设置. +* **Tenant Management**: 用于管理[多租户](../Multi-Tenancy.md)应用程序的租户. +* **Users**: 用于抽象用户, 因此其他模块可以依赖此模块而不是Identity模块. + +模块化文档正在编写中. 请参阅[这个仓库](https://github.com/abpframework/abp/tree/master/modules)获取所有模块的源代码. \ No newline at end of file diff --git a/docs/zh-Hans/Samples/Microservice-Demo.md b/docs/zh-Hans/Samples/Microservice-Demo.md new file mode 100644 index 0000000000..67ba362c24 --- /dev/null +++ b/docs/zh-Hans/Samples/Microservice-Demo.md @@ -0,0 +1,1456 @@ +# 微服务解决方案示例 + +*"作为**面向服务架构**(SOA)的一个变体,微服务是一种将应用程序分解成**松散耦合服务**的新型架构风格. 通过**细粒度**的服务和**轻量级**的协议,微服务提供了更多的**模块化**,使应用程序更容易理解,开发,测试,并且更容易抵抗架构侵蚀. 它使小型团队能够**开发,部署和扩展**各自的服务,实现开发的**并行化**.它还允许通过**连续重构**形成单个服务的架构. 基于微服务架构可以实现**持续交付和部署**."* + +— [维基百科](https://zh.wikipedia.org/wiki/Microservices) + +## 介绍 + +ABP框架的主要目标之一就是提供[便捷的基础设施来创建微服务解决方案](../Microservice-Architecture.md). + +此示例演示了一个简单而完整的微服务解决方案; + +* 拥有多个可独立可单独部署的**微服务**. +* 多个**Web应用程序**, 每一个都使用不同的API网关. +* 使用[Ocelot](https://github.com/ThreeMammals/Ocelot)库开发了多个**网关** / BFFs ([用于前端的后端](https://docs.microsoft.com/zh-cn/azure/architecture/patterns/backends-for-frontends)). +* 包含使用[IdentityServer](https://identityserver.io/)框架开发的 **身份认证服务**. 它也是一个带有UI的SSO(单点登陆)应用程序. +* 有**多个数据库**. 一些微服务有自己的数据库,也有一些服务/应用程序共享同一个数据库(以演示不同的用例). +* 有不同类型的数据库: **SQL Server** (与 **Entity Framework Core** ORM) 和 **MongoDB**. +* 有一个**控制台应用程序**使用身份验证展示使用服务最简单的方法. +* 使用[Redis](https://redis.io/)做**分布式缓存**. +* 使用[RabbitMQ](https://www.rabbitmq.com/)做服务间的**消息**传递. +* 使用 [Docker](https://www.docker.com/) & [Kubernates](https://kubernetes.io/) 来**部署**&**运行**所有的服务和应用程序. +* 使用 [Elasticsearch](https://www.elastic.co/products/elasticsearch) & [Kibana](https://www.elastic.co/products/kibana) 来存储和可视化日志 (使用[Serilog](https://serilog.net/)写日志). + + +下图显示了该系统: + +![microservice-sample-diagram](../images/microservice-sample-diagram.png) + +### 源码 + +你可以从[GitHub仓库](https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo)获取源码. + +### 状态 + +此示例仍处于开发阶段,尚未完成. + +## Running the Solution + +You can either run from the **source code** or from the pre-configured **docker-compose** file. + +### Using the Docker Containers + +#### Pre Requirements + +Running as docker containers is easier since all dependencies are pre-configured. You only need to install the [latest docker](https://docs.docker.com/compose/install/). + +#### Running Containers + +- Clone or download the [ABP repository](https://github.com/abpframework/abp). + +- Open a command line in the `samples/MicroserviceDemo` folder of the repository. + + +- Pull images from Docker Hub: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml pull + ``` + +- If you want to build images locally you may skip the above step and instead use build command: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml build + ``` + + Building images may take a **long time** depending on your machine. + +- Restore SQL Server databases: + + ``` + docker-compose -f docker-compose.yml -f docker-compose.migrations.yml run restore-database + ``` + +- Start the containers: + + ``` + docker-compose up -d + ``` + +- Add this line to the end of your `hosts` file: + + ``` + 127.0.0.1 auth-server + ``` + + hosts file is located inside the `C:\Windows\System32\Drivers\etc\hosts` folder on Windows and `/etc/hosts` for Linux/MacOS. + +#### Run the Applications + +There are a few applications running in the containers you may want to explore: + +* Backend Admin Application (BackendAdminApp.Host): `http://localhost:51512` + *(Used to manage users & products in the system)* +* Public Web Site (PublicWebsite.Host): `http://localhost:51513` + *(Used to list products and run/manage the blog module)* +* Authentication Server (AuthServer.Host): `http://auth-server:51511/` + *(Used as a single sign on and authentication server built with IdentityServer4)* +* Kibana UI: `http://localhost:51510` + *(Use to show/trace logs written by all services/applications/gateways)* + +### Running From the Source Code + +#### Pre Requirements + +To be able to run the solution from source code, following tools should be installed and running on your computer: + +* [SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) 2015+ (can be [express edition](https://www.microsoft.com/en-us/sql-server/sql-server-editions-express)) +* [Redis](https://redis.io/download) 5.0+ +* [RabbitMQ](https://www.rabbitmq.com/install-windows.html) 3.7.11+ +* [MongoDB](https://www.mongodb.com/download-center) 4.0+ +* [ElasticSearch](https://www.elastic.co/downloads/elasticsearch) 6.6+ +* [Kibana](https://www.elastic.co/downloads/kibana) 6.6+ (optional, recommended to show logs) + +#### Open & Build the Visual Studio Solution + +* Open the `samples\MicroserviceDemo\MicroserviceDemo.sln` in Visual Studio 2017 (15.9.0+). +* Run `dotnet restore` from the command line inside the `samples\MicroserviceDemo` folder. +* Build the solution in Visual Studio. + +#### Restore Databases + +Open `MsDemo_Identity.zip` and `MsDemo_ProductManagement.zip` inside the `samples\MicroserviceDemo\databases` folder and restore to the SQL Server. + +> Notice that: These databases have EF Core migrations in the solution, however they don't have seed data, especially required for IdentityServer4 configuration. So, restoring the databases is much more easier. + +#### Run Projects + +Run the projects with the following order (right click to each project, set as startup project an press Ctrl+F5 to run without debug): + +* AuthServer.Host +* IdentityService.Host +* BloggingService.Host +* ProductService.Host +* InternalGateway.Host +* BackendAdminAppGateway.Host +* PublicWebSiteGateway.Host +* BackendAdminApp.Host +* PublicWebSite.Host + +## A Brief Overview of the Solution + +The Visual Studio solution consists of multiple projects each have different roles in the system: + +![microservice-sample-solution](../images/microservice-sample-solution.png) + +### Applications + +These are the actual applications those have user interfaces to interact to the users and use the system. + +- **AuthServer.Host**: Host the IdentityServer4 to provide an authentication service to other services and applications. It is a single-sign server and contains the login page. +- **BackendAdminApp.Host**: This is a backend admin application that host UI for Identity and Product management modules. +- **PubicWebSite.Host**: As public web site that contains a simple product list page and blog module UI. +- **ConsoleClientDemo**: A simple console application to demonstrate the usage of services from a C# application. + +### Gateways / BFFs (Backend for Frontend) + +Gateways are used to provide a single entry point to the applications. It can also used for rate limiting, load balancing... etc. Used the [Ocelot](https://github.com/ThreeMammals/Ocelot) library. + +* **BackendAdminAppGateway.Host**: Used by the BackendAdminApp.Host application as backend. +* **PublicWebSiteGateway.Host**: Used by the PublicWebSite.Host application as backend. +* **InternalGateway.Host**: Used for inter-service communication (the communication between microservices). + +### Microservices + +Microservices have no UI, but exposes some REST APIs. + +- **IdentityService.Host**: Host the ABP Identity module which is used to manage users & roles. It has no additional service, but only hosts the Identity module's API. +- **BloggingService.Host**: Host the ABP Blogging module which is used to manage blog & posts (a typical blog application). It has no additional service, but only hosts the Blogging module's API. +- **ProductService.Host**: Hosts the Product module (that is inside the solution) which is used to manage products. It also contains the EF Core migrations to create/update the Product Management database schema. + +### Modules + +* **Product**: A layered module that is developed with the [module development best practices](../Best-Practices/Index.md). It can be embedded into a monolithic application or can be hosted as a microservice by separately deploying API and UI (as done in this demo solution). + +### Databases + +This solution is using multiple databases: + +* **MsDemo_Identity**: An SQL database. Used **SQL Server** by default, but can be any DBMS supported by the EF Core. Shared by AuthServer and IdentityService. Also audit logs, permissions and settings are stored in this database (while they could easily have their own databases, shared the same database to keep it simple). +* **MsDemo_ProductManagement**: An SQL database. Again, used **SQL Server** by default, but can be any DBMS supported by the EF Core. Used by the ProductService as a dedicated database. +* **MsDemo_Blogging**: A **MongoDB** database. Used by the BloggingService. +* **Elasticsearch**: Used to write logs over Serilog. + +## Applications + +### Authentication Server (AuthServer.Host) + +This project is used by all other services and applications for authentication & single sign on. Mainly, uses **IdentityServer4** to provide these services. It uses some of the [pre-build ABP modules](../Modules/Index) like *Identity*, *Audit Logging* and *Permission Management*. + +#### Database & EF Core Configuration + +This application uses a SQL database (named it as **MsDemo_Identity**) and maintains its schema via **Entity Framework Core migrations.** + +It has a DbContext named **AuthServerDbContext** and defined as shown below: + +````csharp +public class AuthServerDbContext : AbpDbContext +{ + public AuthServerDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureIdentity(); + modelBuilder.ConfigureIdentityServer(); + modelBuilder.ConfigureAuditLogging(); + modelBuilder.ConfigurePermissionManagement(); + modelBuilder.ConfigureSettingManagement(); + } +} +```` + +In the **OnModelCreating**, you see **ConfigureX()** method calls. A module with a database schema generally declares such an extension method to configure EF Core mappings for its own entities. This is a flexible approach where you can arrange your databases and modules inside them; You can use a different database for each module, or combine some of them in a shared database. In the AuthServer project, we decided to combine multiple module schemas in a single EF Core DbContext, in a single physical database. These modules are Identity, IdentityServer, AuditLogging, PermissionManagement and SettingManagement modules. + +Notice that this DbContext is only for database migrations. All modules have their own `DbContext` classes those are used in the runtime by the modules. + +#### User Interface + +AuthServer has a simple home page that shows the current user info if the current user has logged in: + +![microservice-sample-authserver-home](../images/microservice-sample-authserver-home.png) + +It also provides Login & Register pages: + +![microservice-sample-authserver-login](../images/microservice-sample-authserver-login.png) + +These pages are not included in the project itself. Instead, AuthServer project uses the prebuilt ABP [account module](https://github.com/abpframework/abp/tree/master/modules/account) with IdentityServer extension. That means it can also act as an OpenId Connect server with necessary UI and logic. + +#### Dependencies + +* **RabbitMQ** for messaging to other services. +* **Redis** for distributed/shared caching. +* **Elasticsearch** for storing logs. + +### Backend Admin Application (BackendAdminApp.Host) + +This is a web application that is used to manage users, roles, permissions and products in the system. + +#### Authentication + +BackendAdminApp redirects to the AuthServer for authentication. Once the user enters a correct username & password, the page is redirected to the backend application again. Authentication configuration is setup in the `BackendAdminAppHostModule` class: + +````charp +context.Services.AddAuthentication(options => +{ + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; +}) +.AddCookie("Cookies", options => +{ + options.Cookie.Expiration = TimeSpan.FromDays(365); + options.ExpireTimeSpan = TimeSpan.FromDays(365); +}) +.AddOpenIdConnect("oidc", options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ClientId = configuration["AuthServer:ClientId"]; + options.ClientSecret = configuration["AuthServer:ClientSecret"]; + options.RequireHttpsMetadata = false; + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.Scope.Add("role"); + options.Scope.Add("email"); + options.Scope.Add("phone"); + options.Scope.Add("BackendAdminAppGateway"); + options.Scope.Add("IdentityService"); + options.Scope.Add("ProductService"); + options.ClaimActions.MapAbpClaimTypes(); +}); +```` + +* It adds "Cookies" authentication as the primary authentication type. +* "oidc" authentication is configured to use the AuthServer application as the authentication server. +* It requires the additional identity scopes *role*, *email* and *phone*. +* It requires the API resource scopes *BackendAdminAppGateway*, *IdentityService* and *ProductService* because it will use these services as APIs. + +IdentityServer client settings are stored inside the `appsettings.json` file: + +````json +"AuthServer": { + "Authority": "http://localhost:64999", + "ClientId": "backend-admin-app-client", + "ClientSecret": "1q2w3e*" +} +```` + +#### User Interface + +The BackendAdminApp.Host project itself has not a single UI element/page. It is only used to serve UI pages of the Identity and Product Management modules. `BackendAdminAppHostModule` adds dependencies to `AbpIdentityWebModule` (*[Volo.Abp.Identity.Web](https://www.nuget.org/packages/Volo.Abp.Identity.Web)* package) and `ProductManagementWebModule` (*ProductManagement.Web* project) for that purpose. + +A screenshot from the user management page: + +![microservice-sample-backend-ui](../images/microservice-sample-backend-ui.png) + +A screenshot from the permission management modal for a role: + +![microservice-sample-backend-ui-permissions](../images/microservice-sample-backend-ui-permissions.png) + +#### Using Microservices + +Backend admin application uses the Identity and Product microservices for all operations, over the Backend Admin Gateway (BackendAdminAppGateway.Host). + +##### Remote End Point + +`appsettings.json` file contains the `RemoteServices` section to declare the remote service endpoint(s). Each microservice will normally have different endpoints. However, this solution uses the API Gateway pattern to provide a single endpoint for the applications: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65115/" + } +} +```` + +`http://localhost:65115/` is the URL of the *BackendAdminAppGateway.Host* project. It knows where are Identity and Product services are located. + +##### HTTP Clients + +ABP application modules generally provides C# client libraries to consume services (APIs) easily (they generally uses the [Dynamic C# API Clients](../AspNetCore/Dynamic-CSharp-API-Clients.md) feature of the ABP framework). That means if you need to consume Identity service API, you can reference to its client package and easily use the APIs by provided interfaces. + +For that purpose, `BackendAdminAppHostModule` class declares dependencies for `AbpIdentityHttpApiClientModule` and `ProductManagementHttpApiClientModule`. + +Once you refer these client packages, you can directly inject an application service interface (e.g. `IIdentityUserAppService`) and use its methods like a local method call. It actually invokes remote service calls over HTTP to the related service endpoint. + +##### Passing the Access Token + +Since microservices requires authentication & authorization, each remote service call should contain an Authentication header. This header is obtained from the `access_token` inside the current `HttpContext` for the current user. This is automatically done when you use the `Volo.Abp.Http.Client.IdentityModel` package. `BackendAdminAppHostModule` declares dependencies to this package and to the related `AbpHttpClientIdentityModelModule` class. It is integrated to the HTTP Clients explained above. + +#### Dependencies + +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Public Web Site (PublicWebSite.Host) + +This is a public web site project that has a web blog and product list page. + +#### Authentication + +PublicWebSite can show blog posts and product list without login. If you login, you can also manage blogs. It redirects to the AuthServer for authentication. Once the user enters a correct username & password, the page is redirected to the public web site application again. Authentication configuration is setup in the `PublicWebSiteHostModule` class: + +```charp +context.Services.AddAuthentication(options => +{ + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; +}) +.AddCookie("Cookies", options => +{ + options.Cookie.Expiration = TimeSpan.FromDays(365); + options.ExpireTimeSpan = TimeSpan.FromDays(365); +}) +.AddOpenIdConnect("oidc", options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ClientId = configuration["AuthServer:ClientId"]; + options.ClientSecret = configuration["AuthServer:ClientSecret"]; + options.RequireHttpsMetadata = false; + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.Scope.Add("role"); + options.Scope.Add("email"); + options.Scope.Add("phone"); + options.Scope.Add("PublicWebSiteGateway"); + options.Scope.Add("ProductService"); + options.Scope.Add("BloggingService"); + options.ClaimActions.MapAbpClaimTypes(); +}); +``` + +- It adds "Cookies" authentication as the primary authentication type. +- "oidc" authentication is configured to use the AuthServer application as the authentication server. +- It requires the additional identity scopes *role*, *email* and *phone*. +- It requires the API resource scopes *PublicWebSiteGateway*, *BloggingService* and *ProductService* because it will use these services as APIs. + +IdentityServer client settings are stored inside the `appsettings.json` file: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ClientId": "public-website-client", + "ClientSecret": "1q2w3e*" +} +``` + +#### User Interface + +The PublicWebSite.Host project has a page to list products (`Pages/Products.cshtml`). It also uses the UI from the blogging module. `PublicWebSiteHostModule` adds dependencies to `BloggingWebModule` (*[Volo.Blogging.Web](https://www.nuget.org/packages/Volo.Blogging.Web)* package) for that purpose. + +A screenshot from the Products page: + +![microservice-sample-public-product-list](../images/microservice-sample-public-product-list.png) + +#### Using Microservices + +Publc web site application uses the Blogging and Product microservices for all operations, over the Public Web Site Gateway (PublicWebSiteGateway.Host). + +##### Remote End Point + +`appsettings.json` file contains the `RemoteServices` section to declare the remote service endpoint(s). Each microservice will normally have different endpoints. However, this solution uses the API Gateway pattern to provide a single endpoint for the applications: + +```json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:64897/" + } +} +``` + +`http://localhost:64897/` is the URL of the *PublicWebSiteGateway.Host* project. It knows where are Blogging and Product services are located. + +##### HTTP Clients + +`PublicWebSiteHostModule` class declares dependencies for `BloggingHttpApiClientModule` and `ProductManagementHttpApiClientModule` to be able to use remote HTTP APIs for these services. + +##### Passing the Access Token + +Just like explained in the Backend Admin Application section, Public Web Site project also uses the `AbpHttpClientIdentityModelModule` to pass `access_token` to the calling services for authentication. + +#### Dependencies + +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Console Client Demo + +Finally, the solution includes a very simple console application, named ConsoleClientDemo, that uses Identity and Product services by authenticating through the AuthServer. It uses the Internal Gateway (InternalGateway.Host) to perform HTTP API calls. + +#### Remote Service Configuration + +`RemoteService` configuration in the `appsettings.json` file is simple: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65129/" + } +} +```` + +`http://localhost:65129/` is the URL of the Internal Gateway. All API calls to the services are performed over this URL. + +#### Authentication (IdentityServer Client) Configuration + +`appsettings.json` also has a configuration for the IdentityServer authentication: + +````json +"IdentityClients": { + "Default": { + "GrantType": "client_credentials", + "ClientId": "console-client-demo", + "ClientSecret": "1q2w3e*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService ProductService" + } +} +```` + +This sample uses the `client_credentials` grant type which requires a `ClientId` and `ClientSecret` for the authentication process. There are also [other grant types](http://docs.identityserver.io/en/latest/topics/grant_types.html). For example, you can use the following configuration to swith to the `password` (Resource Owner Password) grant type: + +````json +"IdentityClients": { + "Default": { + "GrantType": "password", + "ClientId": "console-client-demo", + "ClientSecret": "1q2w3e*", + "UserName": "admin", + "UserPassword": "1q2w3E*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService ProductService" + } +} +```` + +Resource Owner Password requires a `UserName` & `UserPassword` in addition to client credentials. This grant type is useful to call remote services on behalf of a user. + +`Scope` declares the APIs (and the gateway) to grant access. This application uses the Internal Gateway. + +#### HTTP Client Dependencies + +`ConsoleClientDemoModule` has dependencies to `AbpIdentityHttpApiClientModule` and `ProductManagementHttpApiClientModule` in order to use Identity and Product APIs. It also has `AbpHttpClientIdentityModelModule` dependency to authenticate via IdentityServer. + +#### Using the Services + +Using the services is straightforward. See the `ClientDemoService` class which simply injects `IIdentityUserAppService` and `IProductAppService` and uses them. This class also shows a manual HTTP call using an `HttpClient` object. See source code of the `ClientDemoService` for details. + +## API Gateways / BFFs (Backend for Frontend) + +Gateways are used to provide a **single entry point** to the applications. In this way, an application only deal with a single service address (API endpoint) instead of a different addresses for each services. Gateways are also used for rate limiting, security, authentication, load balancing and many more requirements. + +"**Backend for Frontend**" (BFF) is a common architectural pattern which offers to build a **dedicated and specialized** gateway for each different application / client type. This solution uses this pattern and has multiple gateways. + +This solution uses the [Ocelot](https://github.com/ThreeMammals/Ocelot) library to build API Gateways. It's a widely accepted API Gateway library for ASP.NET Core. + +### Backend Admin Application Gateway (BackendAdminAppGateway.Host) + +This is backend (server side API) for the "Backend Admin Application" (don't confuse about the naming; Backend Admin Application is a frontend web application actually, but used by system admins rather than regular users). + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +````csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +```` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `BackendAdminAppGateway` in this case. So, this solution defines gateways as API resources. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +````json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "BackendAdminAppGateway" +} +```` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +````json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/identity/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 63568 + } + ], + "UpstreamPathTemplate": "/api/identity/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:65115" +} +```` + +`ReRoutes` is an array of URL mappings. `BaseUrl` in the `GlobalConfiguration` section is the URL of this gateway (Ocelot needs to know its own URL). See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the configuration. + +Ocelot is a finalizer ASP.NET Core middleware and should be written as the last item in the pipeline: + +````csharp +app.UseOcelot().Wait(); +```` + +It handles and redirects requests based on the configuration above. + +#### ABP Configuration Endpoints + +ABP provides some built-in APIs to get some configuration and information from the server. Examples: + +* `/api/abp/application-configuration` returns localization texts, permission and setting values (try http://localhost:65115/api/abp/application-configuration for this gateway). +* `/Abp/ServiceProxyScript` returns dynamic javascript proxies to call services from a javascript client (try http://localhost:65115/Abp/ServiceProxyScript for this gateway). + +These endpoints should be served by the gateway service, not by microservices. A microservice can only know permissions related to that microservice. But, once properly configured, gateway can aggregate permission values for multiple services as a single list which is more suitable for clients. + +For this purpose, the ASP.NET Core pipeline was configured to handle some specific routes via MVC, instead of Ocelot. To make this possible, MapWhen extension method is used like that: + +````csharp +app.MapWhen(ctx => ctx.Request.Path.ToString().StartsWith("/api/abp/") || + ctx.Request.Path.ToString().StartsWith("/Abp/"), + app2 => + { + app2.UseMvcWithDefaultRouteAndArea(); + }); + +app.UseOcelot().Wait(); +```` + +This configuration uses standard MVC middleware when request path starts with `/api/abp/` or `/Abp/`. + +#### Swagger + +This gateway is configured to use the [swagger UI](https://swagger.io/tools/swagger-ui/), a popular tool to discover & test HTTP APIs. Normally, Ocelot does not support to show APIs on the swagger, because it can not know details of each microservice API. But it is possible when you follow ABP layered module architecture [best practices](../Best-Practices/Index.md). + +`BackendAdminAppGatewayHostModule` adds dependency to `AbpIdentityHttpApiModule` (*[Volo.Abp.Identity.HttpApi](https://www.nuget.org/packages/Volo.Abp.Identity.HttpApi)* package) and `ProductManagementHttpApiModule` (*ProductManagement.HttpApi* project) to include their HTTP API Controllers. In this way, swagger can discover them. While it references to the API layer, it does not reference to the implementation of application services, because they will be running in the related microservice endpoints and redirected by the Ocelot based on the request URL. + +Anyway, when you open the URL `http://localhost:65115/swagger/index.html`, you will see APIs of all configured microservices. + +#### Permission Management + +Backend Admin Application provides a permission management UI (seen before) and uses this gateway to get/set permissions. Permission management API is hosted inside the gateway, instead of a separate service. This is a design decision, but it could be hosted as another microservice if you would like. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Public Web Site Gateway (PublicWebSiteGateway.Host) + +This is backend (server side API gateway) for the "Public Web Site" application. + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `PublicWebSiteGateway` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "PublicWebSiteGateway" +} +``` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +```json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/blogging/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 62157 + } + ], + "UpstreamPathTemplate": "/api/blogging/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:64897" +} +``` + +See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the Ocelot configuration. + +#### Other + +See the "ABP Configuration Endpoints" and "Swagger" topics inside the "Backend Admin Application Gateway" section which are very similar for this gateway. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Internal Gateway (InternalGateway.Host) + +This gateway is not a BFF. It is designed for inter-microservice communication and is not exposed publicly. + +#### Authentication + +This gateway uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`AddIdentityServerAuthentication` extension method comes from the [IdentityServer4.AccessTokenValidation](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) package, part of the IdentityServer4 project (see [its documentation](http://docs.identityserver.io/en/latest/topics/apis.html)). + +`ApiName` is the API which is being protected, `InternalGateway` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "InternalGateway" +} +``` + +#### Ocelot Configuration + +Ocelot needs to know the real URLs of the microservices to be able to redirect HTTP requests. The configuration for this gateway is like below: + +```json +"ReRoutes": [ + { + "DownstreamPathTemplate": "/api/identity/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 63568 + } + ], + "UpstreamPathTemplate": "/api/identity/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/blogging/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 62157 + } + ], + "UpstreamPathTemplate": "/api/blogging/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } +], +"GlobalConfiguration": { + "BaseUrl": "http://localhost:65129" +} +``` + +`ReRoutes` configuration covers all microservices in the system. See [its own documentation](https://ocelot.readthedocs.io/en/latest/features/configuration.html) to better understand the Ocelot configuration. + +#### Other + +See the "ABP Configuration Endpoints" and "Swagger" topics inside the "Backend Admin Application Gateway" section which are very similar for this gateway. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +## Microservices + +Microservices are standalone HTTP APIs those implement the business of the system in a distributed manner. + +* They are used by applications and other microservices through the gateways and HTTP APIs. +* They can raise or register to events in the system. +* They can communicate to each other via asynchronous messaging. + +### Identity Service (IdentityService.Host) + +This service provides user and role management APIs. + +#### Database + +Shares the same database (MsDemo_Identity) with the AuthServer application. + +#### Identity Module + +This service actually just hosts the ABP Identity package/module. Does not include any API itself. In order to host it, adds the following dependencies: + +* `AbpIdentityHttpApiModule` (*[Volo.Abp.Identity.HttpApi](https://www.nuget.org/packages/Volo.Abp.Identity.HttpApi)* package) to provide Identity APIs. +* `AbpIdentityApplicationModule` (*[Volo.Abp.Identity.Application](https://www.nuget.org/packages/Volo.Abp.Identity.Application)* package) to host the implementation of the application and domain layers of the module. +* `AbpIdentityEntityFrameworkCoreModule` (*[Volo.Abp.Identity.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Abp.Identity.EntityFrameworkCore)* package) to use EF Core as database API. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `IdentityService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "IdentityService" +} +``` + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:63568/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Blogging Service (BloggingService.Host) + +This service hosts the blogging API. + +#### Database + +It has a dedicated MongoDB database (MsDemo_Blogging) to store blog and posts. It also uses the MsDemo_Identity SQL database for audit logs, permissions and settings. So, there are two connection strings in the `appsettings.json` file: + +````json +"ConnectionStrings": { + "Default": "Server=localhost;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true", + "Blogging": "mongodb://localhost|MsDemo_Blogging" +} +```` + +#### Blogging Module + +This service actually just hosts the ABP Blogging package/module. Does not include any API itself. In order to host it, adds the following dependencies: + +- `BloggingHttpApiModule` (*[Volo.Blogging.HttpApi](https://www.nuget.org/packages/Volo.Blogging.HttpApi)* package) to provide Blogging APIs. +- `BloggingApplicationModule` (*[Volo.Blogging.Application](https://www.nuget.org/packages/Volo.Blogging.Application)* package) to host the implementation of the application and domain layers of the module. +- `BloggingMongoDbModule` (*[Volo.Blogging.MongoDB](https://www.nuget.org/packages/Volo.Abp.Identity.EntityFrameworkCore)* package) to use MongoDB as the database. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `BloggingService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "BloggingService" +} +``` + +#### IdentityServer Client + +This microservice also uses the Identity microservice API through the Internal Gateway, because it needs to query user details (username, email, phone, name and surname) in some cases. So, it is also a client for the IdentityServer and defines a section in the `appsettings.json` file for that: + +````json +"IdentityClients": { + "Default": { + "GrantType": "client_credentials", + "ClientId": "blogging-service-client", + "ClientSecret": "1q2w3e*", + "Authority": "http://localhost:64999", + "Scope": "InternalGateway IdentityService" + } +} +```` + +Since it uses the Internal Gateway, it should also configure the remote endpoint of the gateway: + +````json +"RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:65129/", + "UseCurrentAccessToken": "false" + } +} +```` + +When you set `UseCurrentAccessToken` to `false`, ABP ignores the current `access_token` in the current `HttpContext` and authenticates to the AuthServer with the credentials defined above. + +Why not using the token of the current user in the current request? Because, the user may not have required permissions on the Identity module, so it can not just pass the current authentication token directly to the Identity service. In addition, some of the blog service APIs are anonymous (not requires authenticated user), so in some cases there is no "current user" in the HTTP request. For these reasons, Blogging service should be defined as a client for the Identity service with its own credentials and permissions. + +If you check the `AbpPermissionGrants` table in the `MsDemo_Identity` database, you can see the related permission for the `blogging-service-client`. + +![microservice-sample-blogservice-permission-in-database](../images/microservice-sample-blogservice-permission-in-database.png) + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:62157/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +### Product Service (ProductService.Host) + +This service hosts the Product Management API. + +#### Database & EF Core Migrations + +It has a separated SQL database, named **MsDemo_ProductManagement**, for the product management module. It uses EF Core as the database provider and has a DbContext named `ProductServiceMigrationDbContext`: + +````csharp +public class ProductServiceMigrationDbContext : AbpDbContext +{ + public ProductServiceMigrationDbContext( + DbContextOptions options + ) : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureProductManagement(); + } +} +```` + +Actual model configuration is done inside the `modelBuilder.ConfigureProductManagement()` extension method. This project maintains the database schema using EF Core migrations. + +Notice that this DbContext is only for database migrations. Product Management module has its own `DbContext` class that is used in the runtime (See `ProductManagementDbContext` class in the ProductManagement.EntityFrameworkCore project). + +There are two connection strings in the `appsettings.json` file: + +````json +"ConnectionStrings": { + "Default": "Server=localhost;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true", + "ProductManagement": "Server=localhost;Database=MsDemo_ProductManagement;Trusted_Connection=True;MultipleActiveResultSets=true" +} +```` + +`Default` connection strings points to the MsDemo_Identity database that is used for audit logging, permission and setting stores. `ProductManagement` connection string is used by the product module. + +#### Product Module + +This service actually just hosts the Product Management module. Does not include any API itself. In order to host it, adds the following dependencies: + +- `ProductManagementHttpApiModule` to provide product management APIs. +- `ProductManagementApplicationModule` to host the implementation of the application and domain layers of the module. +- `ProductManagementEntityFrameworkCoreModule` to use EF Core as database API. + +See the [module architecture best practice guide](../Best-Practices/Module-Architecture) to understand the layering better. See the Product Management module section below for more information about this module. + +#### Authentication + +This microservice uses IdentityServer `Bearer` authentication and configured like that: + +```csharp +context.Services.AddAuthentication("Bearer") +.AddIdentityServerAuthentication(options => +{ + options.Authority = configuration["AuthServer:Authority"]; + options.ApiName = configuration["AuthServer:ApiName"]; + options.RequireHttpsMetadata = false; + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = + AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; +}); +``` + +`ApiName` is the API which is being protected, `ProductService` in this case. Rest of the configuration is related to claims mapping (which is planned to be automated in next ABP versions). The configuration related to authentication in the `appsettings.json` is simple: + +```json +"AuthServer": { + "Authority": "http://localhost:64999", + "ApiName": "ProductService" +} +``` + +#### Swagger + +Swagger UI is configured and is the default page for this service. If you navigate to the URL `http://localhost:60244/`, you are redirected to the swagger page to see and test the API. + +#### Dependencies + +- **RabbitMQ** for messaging to other services. +- **Redis** for distributed/shared caching. +- **Elasticsearch** for storing logs. + +## Modules + +ABP provides a strong infrastructure to make modular application development easier by providing services and architecture (see the [module development best practices guide](../Best-Practices/Index.md)). + +This solution demonstrate how to use [prebuilt application modules](../Modules/Index.md) in a distributed architecture. The solution also includes a simple "Product Management" module to show the implementation of a well layered module example. + +### Product Management + +Product Management is a module that consists of several layers and packages/projects: + +![microservice-sample-product-module-in-solution](../images/microservice-sample-product-module-in-solution.png) + +* `ProductManagement.Domain.Shared` contains constants and types shared among all layers. +* `ProductManagement.Domain` contains the domain logic and defines entities, domain services, domain events, business/domain exceptions. +* `ProductManagement.Application.Contracts` contains application service interfaces and DTOs. +* `ProductManagement.Application` contains the implementation of application services. +* `ProductManagement.EntityFrameworkCore` contains DbConext and other EF Core related classes and configuration. +* `ProductManagement.HttpApi` contains API Controllers. +* `ProductManagement.HttpApi.Client` contains C# proxies to directly use the HTTP API remotely. Uses [Dynamic C# API Clients](../AspNetCore/Dynamic-CSharp-API-Clients.md) feature of the ABP framework. +* `ProductManagement.Web` contains the UI elements (pages, scripts, styles... etc). + +By the help of this layering, it is possible to use the same module as a package reference in a monolithic application or use as a service that runs in another server. It is possible to separate UI (Web) and API layers, so they run in different servers. + +In this solution, Web layer runs in the Backend Admin Application while API layer is hosted by the Product microservice. + +This tutorial will highlight some important aspects of the module. But, it's suggested to see the source code for a better understanding. + +#### Domain Layer + +`Product` is the main [Aggregate Root](../Entities.md) of this module: + +````csharp +public class Product : AuditedAggregateRoot +{ + /// + /// A unique value for this product. + /// ProductManager ensures the uniqueness of it. + /// It can not be changed after creation of the product. + /// + [NotNull] + public string Code { get; private set; } + + [NotNull] + public string Name { get; private set; } + + public float Price { get; private set; } + + public int StockCount { get; private set; } + + //... +} +```` + +All of its properties have private setters which prevents any direct change of the properties from out of the class. Product class ensures its own integrity and validity by its own constructors and methods. + +It has two constructors: + +````csharp +private Product() +{ + //Default constructor is needed for ORMs. +} + +internal Product( + Guid id, + [NotNull] string code, + [NotNull] string name, + float price = 0.0f, + int stockCount = 0) +{ + Check.NotNullOrWhiteSpace(code, nameof(code)); + + if (code.Length >= ProductConsts.MaxCodeLength) + { + throw new ArgumentException( + $"Product code can not be longer than {ProductConsts.MaxCodeLength}" + ); + } + + Id = id; + Code = code; + SetName(Check.NotNullOrWhiteSpace(name, nameof(name))); + SetPrice(price); + SetStockCountInternal(stockCount, triggerEvent: false); +} + +```` + +Default (**parameterless**) constructor is private and is not used in the application code. It is needed because most ORMs requires a parameterless constructor on deserializing entities while getting from the database. + +Second constructor is **internal** that means it can only be used inside the domain layer. This enforces to use the `ProductManager` while creating a new `Product`. Because, `ProductManager` should implement a business rule on a new product creation. This constructor only requires the minimal required arguments to create a new product with some optional arguments. It checks some simple business rules to ensure that the entity is created as a valid product. + +Rest of the class has methods to manipulate properties of the entity. Example: + +````csharp +public Product SetPrice(float price) +{ + if (price < 0.0f) + { + throw new ArgumentException($"{nameof(price)} can not be less than 0.0!"); + } + + Price = price; + return this; +} + +```` + +`SetPrice` method is used to change the price of the product in a safe manner (by checking a validation rule). + +`SetStockCount` is another method that is used to change stock count of a product: + +````csharp +public Product SetStockCount(int stockCount) +{ + return SetStockCountInternal(stockCount); +} + +private Product SetStockCountInternal(int stockCount, bool triggerEvent = true) +{ + if (StockCount < 0) + { + throw new ArgumentException($"{nameof(stockCount)} can not be less than 0!"); + } + + if (StockCount == stockCount) + { + return this; + } + + if (triggerEvent) + { + AddDistributedEvent( + new ProductStockCountChangedEto( + Id, StockCount, stockCount + ) + ); + } + + StockCount = stockCount; + return this; +} + +```` + +This method also triggers a **distributed event** with the `ProductStockCountChangedEto` parameter (Eto is a conventional postfix stands for **E**vent **T**ransfer **O**bject, but not required) to notify listeners that stock count of a product has changed. Any subscriber can receive this event and perform an action based on that knowledge. + +Events are distributed by RabbitMQ for this solution. But ABP is message broker independent by providing necessary abstractions (see the [Event Bus](../Event-Bus.md) document). + +As said before, this module forces to always use the `ProductManager` to create a new `Product`. `ProductManager` is a simple domain service defined as shown: + +````csharp +public class ProductManager : DomainService +{ + private readonly IRepository _productRepository; + + public ProductManager(IRepository productRepository) + { + _productRepository = productRepository; + } + + public async Task CreateAsync( + [NotNull] string code, + [NotNull] string name, + float price = 0.0f, + int stockCount = 0) + { + var existingProduct = + await _productRepository.FirstOrDefaultAsync(p => p.Code == code); + + if (existingProduct != null) + { + throw new ProductCodeAlreadyExistsException(code); + } + + return await _productRepository.InsertAsync( + new Product( + GuidGenerator.Create(), + code, + name, + price, + stockCount + ) + ); + } +} +```` + +* It checks if given code is used before. Throws `ProductCodeAlreadyExistsException` so. +* If uses the `GuidGenerator` (`IGuidGenerator`) service to create a new `Guid`. +* It inserts the entity to the repository. + +So, with this design, uniqueness of the product code is guaranteed. + +`ProductCodeAlreadyExistsException` is a domain/business exception defined as like below: + +````csharp +public class ProductCodeAlreadyExistsException : BusinessException +{ + public ProductCodeAlreadyExistsException(string productCode) + : base("PM:000001", $"A product with code {productCode} has already exists!") + { + + } +} +```` + +`PM:000001` is a code for the exception type that is sent to the clients, so they can understand the error type. Not implemented for this case, but it is also possible to localize business exceptions. See the [exception handling documentation](../Exception-Handling.md). + +#### Application Layer + +Application layer of this module has two services: + +* `ProductAppService` is mainly used by the Backend Admin Application to manage (create, update, delete...) products. It requires permission to perform any operation. +* `PublicProductAppService` is used by the Public Web Site to show list of products to the visitors. It does not require any permission since most of the visitors are not logged in to the application. + +Notice that; instead of putting two application service into the same project, it might be a better principle to have separated application layers per application. But we unified them for simplicity in this solution. + +As an example, `ProductAppService` has the following method to update a product: + +````csharp +[Authorize(ProductManagementPermissions.Products.Update)] +public async Task UpdateAsync(Guid id, UpdateProductDto input) +{ + var product = await _productRepository.GetAsync(id); + + product.SetName(input.Name); + product.SetPrice(input.Price); + product.SetStockCount(input.StockCount); + + return ObjectMapper.Map(product); +} +```` + +* It defines the required permission (*ProductManagementPermissions.Products.Update* is a constant with value `ProductManagement.Update`) to perform this operation. +* Gets the id of the product and a DTO contains the values to update. +* Gets the related product entity from the repository. +* Uses the related methods (like `SetName`) of the `Product` class to change properties, because they are with private setters and the only way to change a value is to use an entity method. +* Returns an updated `ProductDto` to the client (client may need it for some reason) by using the [ObjectMapper](../Object-To-Object-Mapping.md). + +The implementation may vary based on the requirements. This implementation follows the [best practices offered here](../Best-Practices/Application-Services.md). + +#### Other Layers + +See other layers from the source code. + +## Infrastructure + +### Messaging and RabbitMQ + +Asynchronous Messaging is a key concept in distributed systems. It makes possible to communicate as a loosely coupled manner with fault tolerance. It does not require both sides to be online at the moment of messaging. So, it is a widely used communication pattern in microservice architecture. + +#### Distributed Event Bus + +Distributed Events (Event Bus) is a way of messaging where a service raise/trigger events while other services registers/listens to these events to be notified when an important event occurs. ABP makes distributed events easier to use by providing conventions, services and integrations. + +You have seen that the `Product` class publishing an event using the following code line: + +````csharp +AddDistributedEvent(new ProductStockCountChangedEto(Id, StockCount, stockCount)); +```` + +`ProductStockCountChangedEto` was defined as shown below: + +````csharp +[Serializable] +public class ProductStockCountChangedEto : EtoBase +{ + public Guid Id { get; } + + public int OldCount { get; set; } + + public int CurrentCount { get; set; } + + private ProductStockCountChangedEto() + { + //Default constructor is needed for deserialization. + } + + public ProductStockCountChangedEto(Guid id, int oldCount, int currentCount) + { + Id = id; + OldCount = oldCount; + CurrentCount = currentCount; + } +} +```` + +This object stores necessary information about the event. Another service can easily register to this event by implementing the `IDistributedEventHandler` interface with the generic `ProductStockCountChangedEto` parameter: + +````csharp +public class MyHandler : IDistributedEventHandler +{ + public async Task HandleEventAsync(ProductStockCountChangedEto eventData) + { + var productId = eventData.Id; + //... + } +} +```` + +All the integration and communication are done by the ABP framework when you use the [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) package. If you need to publish events out of an entity, just inject the `IDistributedEventBus` and use the `PublishAsync` method. + +See the [Event Bus](../Event-Bus.md) documentation for more information about the distributed event system. + +#### RabbitMQ Configuration + +In this solution, [RabbitMQ](https://www.rabbitmq.com/) is used for messaging & distributed events. + +[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) package is required to integrate to the RabbitMQ for distributed event system. Then you need to add dependency to the `AbpEventBusRabbitMqModule` for your module. For example, `ProductServiceHostModule` declares this dependency. + +`AbpEventBusRabbitMqModule` gets configuration from the `appsettings.json` by default. For example, the Product Service has such a configuration: + +````json +"RabbitMQ": { + "Connections": { + "Default": { + "HostName": "localhost" + } + }, + "EventBus": { + "ClientName": "MsDemo_ProductService", + "ExchangeName": "MsDemo" + } +} +```` + +### Caching and Redis + +A distributed system obviously needs to a distributed and shared cache, instead of isolated in-memory caches for each service. + +[Redis](https://redis.io/) is used as a distributed cache in this solution. The solution uses Microsoft's standard [Microsoft.Extensions.Caching.Redis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Redis) package for integration. All applications and services uses Redis cache when you use and configure this package. See [Microsoft's documentation](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) for more. + +The solution also uses the [Microsoft.AspNetCore.DataProtection.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.AspNetCore.DataProtection.StackExchangeRedis) package to share data protection keys between applications and services over Redis cache. + +### Logging, Serilog, Elasticsearch and Kibana + +This solution uses [Serilog](https://serilog.net/) as a logging library. It is a widely used library which has many data source integrations including [Elasticsearch](https://www.elastic.co/products/elasticsearch). + +Logging configurations are done in `Program.cs` files using a code block similar to the given below: + +````csharp +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.WithProperty("Application", "ProductService") + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .WriteTo.Elasticsearch( + new ElasticsearchSinkOptions(new Uri(configuration["ElasticSearch:Url"])) + { + AutoRegisterTemplate = true, + AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6, + IndexFormat = "msdemo-log-{0:yyyy.MM}" + }) + .CreateLogger(); +```` + +This configures multiple log target: File and Elasticsearch. `Application` property is set to `ProductService` for this example. This is a way of distinguishing the logs of multiple services in a single database. You can then query logs by the `Application` name. + +Elasticsearch URL is read from the `appsettings.json` configuration file: + +````json +"ElasticSearch": { + "Url": "http://localhost:9200" +} +```` + +If you use Kibana, which is a Visualization tool that is well integrated to Elasticsearch, you can see some fancy UI about your logs: + +![microservice-sample-kibana-2](../images/microservice-sample-kibana-2.png) + +*Figure - A dashboard that shows log and error counts by service/application.* + +![microservice-sample-kibana-1](../images/microservice-sample-kibana-1.png) + +*Figure - A list of log entries* + +Kibana URL is `http://localhost:5601/` by default. + +### Audit Logging + +ABP provides automatic audit logging which saves every request in detail (who is the current user, what is the browser/client, what actions performed, which entities changed, even which properties of entities has been updated). See the [audit logging document](../Audit-Logging.md) for details. + +All of the services and applications are configured to write audit logs. Audit logs are saved to the MsDemo_Identity SQL database. So, you can query all audit logs of all applications from a single point. + +An Audit Log record has a `CorrelationId` property that can be used to track a request. When a service calls another service in a single web request, they both save audit logs with the same `CorrelationId`. See the `AbpAuditLogs` table in the database. \ No newline at end of file diff --git a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md index a9e333690f..34acc3f01f 100644 --- a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md @@ -238,7 +238,7 @@ namespace Acme.BookStore 你通常需要创建 **Controllers** 将应用服务暴露为 **HTTP API**.这样浏览器或第三方客户端可以通过AJAX的方式访问它们. -ABP可以 **自动地** 将应用服务转换成MVC API Controllers. +ABP可以 **自动地** (../../AspNetCore/Auto-API-Controllers.md)将应用服务转换成MVC API Controllers. #### Swagger UI diff --git a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md index 418c29a119..6b31e9ba84 100644 --- a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md +++ b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md @@ -1,6 +1,6 @@ -## ASP.NET Core MVC Tutorial - Part III +## ASP.NET Core MVC 教程 - 第三章 -### About this Tutorial +### 关于本教程 这是本教程所有章节中的第三章.下面是所有的章节: @@ -214,4 +214,4 @@ public async Task Should_Not_Create_A_Book_Without_Name() ### 测试 Web 页面 -TODO \ No newline at end of file +TODO diff --git a/docs/zh-Hans/Unit-Of-Work.md b/docs/zh-Hans/Unit-Of-Work.md new file mode 100644 index 0000000000..dc281a0974 --- /dev/null +++ b/docs/zh-Hans/Unit-Of-Work.md @@ -0,0 +1,3 @@ +## Unit of Work + +待添加 diff --git a/docs/zh-Hans/Validation.md b/docs/zh-Hans/Validation.md new file mode 100644 index 0000000000..c2b128f0bc --- /dev/null +++ b/docs/zh-Hans/Validation.md @@ -0,0 +1,3 @@ +## Validation + +待添加 diff --git a/docs/zh-Hans/Virtual-File-System.md b/docs/zh-Hans/Virtual-File-System.md index e25d7f61b4..05d8f59a85 100644 --- a/docs/zh-Hans/Virtual-File-System.md +++ b/docs/zh-Hans/Virtual-File-System.md @@ -109,7 +109,7 @@ public class MyService 假设你正在开发一个包含嵌入式JavaScript文件的模块. 当你更改文件时, 你必须重新编译项目, 重新启动应用程序并刷新浏览器页面以进行更改. 显然, 这是非常耗时和乏味的. -我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. `ReplaceEmbeddedByPyhsical` 方法使其成为可能. +我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. `ReplaceEmbeddedByPhysical` 方法使其成为可能. 下面的示例展示了应用程序依赖于包含嵌入文件的模块("MyModule"), 并且应用程序可以在开发过程中直接使用模块的源代码. @@ -125,8 +125,8 @@ public class MyWebAppModule : AbpModule { Configure(options => { - //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project - options.FileSets.ReplaceEmbeddedByPyhsical( + //ReplaceEmbeddedByPhysical gets the root folder of the MyModule project + options.FileSets.ReplaceEmbeddedByPhysical( Path.Combine(hostingEnvironment.ContentRootPath, "..\\MyModuleProject") ); }); diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 362e6fbc65..56575a4755 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -16,11 +16,11 @@ "text": "从空项目开始", "items": [ { - "text": "使用Console Application", + "text": "使用ASP.NET Core Web Application", "path": "Getting-Started-AspNetCore-Application.md" }, { - "text": "使用 ASP.NET Core Web Application", + "text": "使用Console Application", "path": "Getting-Started-Console-Application.md" } ] @@ -49,7 +49,8 @@ "path": "Dependency-Injection.md", "items": [ { - "text": "AutoFac 集成" + "text": "AutoFac 集成", + "path": "Autofac-Integration.md" } ] }, @@ -66,7 +67,8 @@ "path": "Exception-Handling.md" }, { - "text": "验证" + "text": "验证", + "path": "Validation.md" }, { "text": "授权" @@ -159,7 +161,8 @@ "path": "Repositories.md" }, { - "text": "领域服务" + "text": "领域服务", + "path": "Domain-Services.md" }, { "text": "规约" @@ -170,23 +173,35 @@ "text": "应用服务层", "items": [ { - "text": "应用服务" + "text": "应用服务", + "path": "Application-Services.md" }, { "text": "数据传输对象(DTO)" }, { - "text": "工作单元" + "text": "工作单元", + "path": "Unit-Of-Work.md" } ] } ] }, { - "text": "ASP.NET Core MVC", + "text": "ASP.NET Core", "items": [ { - "text": "API 版本控制" + "text": "API", + "items": [ + { + "text": "自动API控制器", + "path": "AspNetCore/Auto-API-Controllers.md" + }, + { + "text": "动态C# API客户端", + "path": "AspNetCore/Dynamic-CSharp-API-Clients.md" + } + ] }, { "text": "用户界面", @@ -243,6 +258,23 @@ } ] }, + { + "text": "示例", + "items": [ + { + "text": "微服务示例", + "path": "Samples/Microservice-Demo.md" + } + ] + }, + { + "text": "应用模块", + "path": "Modules/Index.md" + }, + { + "text": "微服务架构", + "path": "Microservice-Architecture.md" + }, { "text": "测试" }, @@ -251,4 +283,4 @@ "path": "Contribution/Index.md" } ] -} \ No newline at end of file +} diff --git a/docs/zh-Hans/images/bookstore-apis.png b/docs/zh-Hans/images/bookstore-apis.png new file mode 100644 index 0000000000..aedd79c7f1 Binary files /dev/null and b/docs/zh-Hans/images/bookstore-apis.png differ diff --git a/docs/zh-Hans/images/docs-module_download-new-abp-project.png b/docs/zh-Hans/images/docs-module_download-new-abp-project.png new file mode 100644 index 0000000000..0da3b7a67a Binary files /dev/null and b/docs/zh-Hans/images/docs-module_download-new-abp-project.png differ diff --git a/docs/zh-Hans/images/docs-module_download-sample-navigation-menu.png b/docs/zh-Hans/images/docs-module_download-sample-navigation-menu.png new file mode 100644 index 0000000000..9a1232f198 Binary files /dev/null and b/docs/zh-Hans/images/docs-module_download-sample-navigation-menu.png differ diff --git a/docs/zh-Hans/images/docs-module_solution-explorer.png b/docs/zh-Hans/images/docs-module_solution-explorer.png new file mode 100644 index 0000000000..cafc38f0b0 Binary files /dev/null and b/docs/zh-Hans/images/docs-module_solution-explorer.png differ diff --git a/docs/zh-Hans/images/microservice-sample-authserver-home.png b/docs/zh-Hans/images/microservice-sample-authserver-home.png new file mode 100644 index 0000000000..7ae62ad6d5 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-authserver-home.png differ diff --git a/docs/zh-Hans/images/microservice-sample-authserver-login.png b/docs/zh-Hans/images/microservice-sample-authserver-login.png new file mode 100644 index 0000000000..f6e8dfaa9f Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-authserver-login.png differ diff --git a/docs/zh-Hans/images/microservice-sample-backend-ui-permissions.png b/docs/zh-Hans/images/microservice-sample-backend-ui-permissions.png new file mode 100644 index 0000000000..02769be3e5 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-backend-ui-permissions.png differ diff --git a/docs/zh-Hans/images/microservice-sample-backend-ui.png b/docs/zh-Hans/images/microservice-sample-backend-ui.png new file mode 100644 index 0000000000..0935a6047a Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-backend-ui.png differ diff --git a/docs/zh-Hans/images/microservice-sample-blogservice-permission-in-database.png b/docs/zh-Hans/images/microservice-sample-blogservice-permission-in-database.png new file mode 100644 index 0000000000..f99cd39893 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-blogservice-permission-in-database.png differ diff --git a/docs/zh-Hans/images/microservice-sample-diagram.png b/docs/zh-Hans/images/microservice-sample-diagram.png new file mode 100644 index 0000000000..b1d9f6c66e Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-diagram.png differ diff --git a/docs/zh-Hans/images/microservice-sample-kibana-1.png b/docs/zh-Hans/images/microservice-sample-kibana-1.png new file mode 100644 index 0000000000..f3a51bd349 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-kibana-1.png differ diff --git a/docs/zh-Hans/images/microservice-sample-kibana-2.png b/docs/zh-Hans/images/microservice-sample-kibana-2.png new file mode 100644 index 0000000000..31b281486c Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-kibana-2.png differ diff --git a/docs/zh-Hans/images/microservice-sample-product-module-in-solution.png b/docs/zh-Hans/images/microservice-sample-product-module-in-solution.png new file mode 100644 index 0000000000..27e841cdd5 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-product-module-in-solution.png differ diff --git a/docs/zh-Hans/images/microservice-sample-public-product-list.png b/docs/zh-Hans/images/microservice-sample-public-product-list.png new file mode 100644 index 0000000000..cf8649bbe5 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-public-product-list.png differ diff --git a/docs/zh-Hans/images/microservice-sample-solution.png b/docs/zh-Hans/images/microservice-sample-solution.png new file mode 100644 index 0000000000..4c8344ed68 Binary files /dev/null and b/docs/zh-Hans/images/microservice-sample-solution.png differ diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 92c46299f4..f99d6cebbc 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -214,9 +214,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCor EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Localization.Abstractions", "src\Volo.Abp.Localization.Abstractions\Volo.Abp.Localization.Abstractions.csproj", "{20513A4E-FAC7-4106-8976-5D79A3BDFED1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Client.IdentityModel", "src\Volo.Abp.Http.Client.IdentityModel\Volo.Abp.Http.Client.IdentityModel.csproj", "{D211A446-38FA-4F97-9A95-1F004A0FFF69}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityModel", "src\Volo.Abp.IdentityModel\Volo.Abp.IdentityModel.csproj", "{64D99E19-EE25-465A-82E5-17B25F4C4E18}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.Client", "src\Volo.Abp.AspNetCore.Mvc.Client\Volo.Abp.AspNetCore.Mvc.Client.csproj", "{E803DDB8-81EA-454B-9A66-9C2941100B67}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.Contracts", "src\Volo.Abp.AspNetCore.Mvc.Contracts\Volo.Abp.AspNetCore.Mvc.Contracts.csproj", "{88F6D091-CA16-4B71-9499-8D5B8FA2E712}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Features", "src\Volo.Abp.Features\Volo.Abp.Features.csproj", "{01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -616,6 +626,26 @@ Global {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.Build.0 = Debug|Any CPU {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.Build.0 = Release|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Release|Any CPU.Build.0 = Release|Any CPU + {64D99E19-EE25-465A-82E5-17B25F4C4E18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64D99E19-EE25-465A-82E5-17B25F4C4E18}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64D99E19-EE25-465A-82E5-17B25F4C4E18}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64D99E19-EE25-465A-82E5-17B25F4C4E18}.Release|Any CPU.Build.0 = Release|Any CPU + {E803DDB8-81EA-454B-9A66-9C2941100B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E803DDB8-81EA-454B-9A66-9C2941100B67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E803DDB8-81EA-454B-9A66-9C2941100B67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E803DDB8-81EA-454B-9A66-9C2941100B67}.Release|Any CPU.Build.0 = Release|Any CPU + {88F6D091-CA16-4B71-9499-8D5B8FA2E712}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88F6D091-CA16-4B71-9499-8D5B8FA2E712}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88F6D091-CA16-4B71-9499-8D5B8FA2E712}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88F6D091-CA16-4B71-9499-8D5B8FA2E712}.Release|Any CPU.Build.0 = Release|Any CPU + {01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -721,6 +751,11 @@ Global {20513A4E-FAC7-4106-8976-5D79A3BDFED1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {7CE07034-7E02-4C78-B981-F1039412CA5E} = {447C8A77-E5F0-4538-8687-7383196D04EA} {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {D211A446-38FA-4F97-9A95-1F004A0FFF69} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {64D99E19-EE25-465A-82E5-17B25F4C4E18} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {E803DDB8-81EA-454B-9A66-9C2941100B67} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {88F6D091-CA16-4B71-9499-8D5B8FA2E712} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {01E3D389-8872-4EB1-9D3D-13B6ED54DE0E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj index 42b81370fd..722b6033ed 100644 --- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs index 7f00a58069..7ba8766dd8 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs @@ -14,10 +14,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy { Configure(options => { - options.TenantResolvers.Add(new QueryStringTenantResolveContributer()); - options.TenantResolvers.Add(new RouteTenantResolveContributer()); - options.TenantResolvers.Add(new HeaderTenantResolveContributer()); - options.TenantResolvers.Add(new CookieTenantResolveContributer()); + options.TenantResolvers.Add(new QueryStringTenantResolveContributor()); + options.TenantResolvers.Add(new RouteTenantResolveContributor()); + options.TenantResolvers.Add(new HeaderTenantResolveContributor()); + options.TenantResolvers.Add(new CookieTenantResolveContributor()); }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributer.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributer.cs deleted file mode 100644 index ebce890ea9..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Volo.Abp.MultiTenancy; - -namespace Volo.Abp.AspNetCore.MultiTenancy -{ - public class CookieTenantResolveContributer : HttpTenantResolveContributerBase - { - protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) - { - return httpContext.Request?.Cookies[context.GetAspNetCoreMultiTenancyOptions().TenantKey]; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs new file mode 100644 index 0000000000..5b27a9d93c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Http; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + public class CookieTenantResolveContributor : HttpTenantResolveContributorBase + { + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + return httpContext.Request?.Cookies[context.GetAspNetCoreMultiTenancyOptions().TenantKey]; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributer.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributer.cs deleted file mode 100644 index 2894fcf0df..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributer.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Microsoft.AspNetCore.Http; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Text.Formatting; - -namespace Volo.Abp.AspNetCore.MultiTenancy -{ - //TODO: Create a better domain format. We can accept regex for example. - - public class DomainTenantResolveContributer : HttpTenantResolveContributerBase - { - private readonly string _domainFormat; - - public DomainTenantResolveContributer(string domainFormat) - { - _domainFormat = domainFormat.RemovePreFix("http://", "https://"); - } - - protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) - { - if (httpContext.Request?.Host == null) - { - return null; - } - - var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://"); - var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true); - - if (!extractResult.IsMatch) - { - return null; - } - - return extractResult.Matches[0].Value; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs new file mode 100644 index 0000000000..e342cb8f40 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.AspNetCore.Http; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Text.Formatting; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + //TODO: Create a better domain format. We can accept regex for example. + + public class DomainTenantResolveContributor : HttpTenantResolveContributorBase + { + private readonly string _domainFormat; + + public DomainTenantResolveContributor(string domainFormat) + { + _domainFormat = domainFormat.RemovePreFix("http://", "https://"); + } + + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + if (httpContext.Request?.Host == null) + { + return null; + } + + var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://"); + var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true); + + if (!extractResult.IsMatch) + { + return null; + } + + return extractResult.Matches[0].Value; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributer.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributer.cs deleted file mode 100644 index 58acdc493c..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Volo.Abp.MultiTenancy; - -namespace Volo.Abp.AspNetCore.MultiTenancy -{ - public class HeaderTenantResolveContributer : HttpTenantResolveContributerBase - { - protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) - { - if (httpContext.Request == null || httpContext.Request.Headers.IsNullOrEmpty()) - { - return null; - } - - var tenantIdKey = context.GetAspNetCoreMultiTenancyOptions().TenantKey; - - var tenantIdHeader = httpContext.Request.Headers[tenantIdKey]; - if (tenantIdHeader == string.Empty || tenantIdHeader.Count < 1) - { - return null; - } - - if (tenantIdHeader.Count > 1) - { - Log(context, $"HTTP request includes more than one {tenantIdKey} header value. First one will be used. All of them: {tenantIdHeader.JoinAsString(", ")}"); - } - - return tenantIdHeader.First(); - } - - protected virtual void Log(ITenantResolveContext context, string text) - { - context - .ServiceProvider - .GetRequiredService>() - .LogWarning(text); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs new file mode 100644 index 0000000000..3f5e93bd36 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + public class HeaderTenantResolveContributor : HttpTenantResolveContributorBase + { + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + if (httpContext.Request == null || httpContext.Request.Headers.IsNullOrEmpty()) + { + return null; + } + + var tenantIdKey = context.GetAspNetCoreMultiTenancyOptions().TenantKey; + + var tenantIdHeader = httpContext.Request.Headers[tenantIdKey]; + if (tenantIdHeader == string.Empty || tenantIdHeader.Count < 1) + { + return null; + } + + if (tenantIdHeader.Count > 1) + { + Log(context, $"HTTP request includes more than one {tenantIdKey} header value. First one will be used. All of them: {tenantIdHeader.JoinAsString(", ")}"); + } + + return tenantIdHeader.First(); + } + + protected virtual void Log(ITenantResolveContext context, string text) + { + context + .ServiceProvider + .GetRequiredService>() + .LogWarning(text); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs index 51bdc57323..d2971063a5 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs @@ -7,7 +7,7 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.AspNetCore.MultiTenancy { - public abstract class HttpTenantResolveContributerBase : ITenantResolveContributer + public abstract class HttpTenantResolveContributorBase : ITenantResolveContributor { public virtual void Resolve(ITenantResolveContext context) { @@ -24,7 +24,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy catch (Exception e) { context.ServiceProvider - .GetRequiredService>() + .GetRequiredService>() .LogWarning(e.ToString()); } } diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributer.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributer.cs deleted file mode 100644 index 88bd3bcc0d..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Volo.Abp.MultiTenancy; - -namespace Volo.Abp.AspNetCore.MultiTenancy -{ - public class QueryStringTenantResolveContributer : HttpTenantResolveContributerBase - { - protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) - { - if (httpContext.Request == null || !httpContext.Request.QueryString.HasValue) - { - return null; - } - - return httpContext.Request.Query[context.GetAspNetCoreMultiTenancyOptions().TenantKey]; - } - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs new file mode 100644 index 0000000000..9899e2613e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Http; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + public class QueryStringTenantResolveContributor : HttpTenantResolveContributorBase + { + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + if (httpContext.Request == null || !httpContext.Request.QueryString.HasValue) + { + return null; + } + + return httpContext.Request.Query[context.GetAspNetCoreMultiTenancyOptions().TenantKey]; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributer.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributer.cs deleted file mode 100644 index 10d4f1ebe1..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributer.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; -using Volo.Abp.MultiTenancy; - -namespace Volo.Abp.AspNetCore.MultiTenancy -{ - public class RouteTenantResolveContributer : HttpTenantResolveContributerBase - { - protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) - { - var tenantId = httpContext.GetRouteValue(context.GetAspNetCoreMultiTenancyOptions().TenantKey); - if (tenantId == null) - { - return null; - } - - return Convert.ToString(tenantId); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs new file mode 100644 index 0000000000..3be155c68d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs @@ -0,0 +1,21 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + public class RouteTenantResolveContributor : HttpTenantResolveContributorBase + { + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + var tenantId = httpContext.GetRouteValue(context.GetAspNetCoreMultiTenancyOptions().TenantKey); + if (tenantId == null) + { + return null; + } + + return Convert.ToString(tenantId); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenancyOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenancyOptionsExtensions.cs index 8e6d3ae7ea..a162f1750e 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenancyOptionsExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenancyOptionsExtensions.cs @@ -8,8 +8,8 @@ namespace Volo.Abp.MultiTenancy public static void AddDomainTenantResolver(this TenantResolveOptions options, string domainFormat) { options.TenantResolvers.InsertAfter( - r => r is CurrentClaimsPrincipalTenantResolveContributer, - new DomainTenantResolveContributer(domainFormat) + r => r is CurrentClaimsPrincipalTenantResolveContributor, + new DomainTenantResolveContributor(domainFormat) ); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj new file mode 100644 index 0000000000..9d05c9e34b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj @@ -0,0 +1,23 @@ + + + + + + netstandard2.0 + Volo.Abp.AspNetCore.Mvc.Client + Volo.Abp.AspNetCore.Mvc.Client + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs new file mode 100644 index 0000000000..6c306073c5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Caching; +using Volo.Abp.Http.Client; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + [DependsOn( + typeof(AbpHttpClientModule), + typeof(AbpAspNetCoreMvcContractsModule), + typeof(AbpCachingModule), + typeof(AbpLocalizationModule) + )] + public class AbpAspNetCoreMvcClientModule : AbpModule + { + public const string RemoteServiceName = "AbpMvcClient"; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(AbpAspNetCoreMvcContractsModule).Assembly, + RemoteServiceName, + asDefaultServices: false + ); + + Configure(options => + { + options.GlobalContributors.Add(); + }); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs new file mode 100644 index 0000000000..4ceb8bdd1c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs @@ -0,0 +1,66 @@ +using System; +using System.Globalization; +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Caching.Distributed; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.DynamicProxying; +using Volo.Abp.Users; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public class CachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency + { + public IHttpContextAccessor HttpContextAccessor { get; set; } + + protected IHttpClientProxy Proxy { get; } + protected ICurrentUser CurrentUser { get; } + protected IDistributedCache Cache { get; } + + public CachedApplicationConfigurationClient( + IDistributedCache cache, + IHttpClientProxy proxy, + ICurrentUser currentUser, + IHttpContextAccessor httpContextAccessor) + { + Proxy = proxy; + CurrentUser = currentUser; + HttpContextAccessor = httpContextAccessor; + Cache = cache; + } + + public async Task GetAsync() + { + var cacheKey = CreateCacheKey(); + var httpContext = HttpContextAccessor?.HttpContext; + + if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration) + { + return configuration; + } + + configuration = await Cache.GetOrAddAsync( + CreateCacheKey(), + async () => await Proxy.Service.GetAsync(), + () => new DistributedCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60) //TODO: Should be configurable. Default value should be higher (5 mins would be good). + } + ); + + if (httpContext != null) + { + httpContext.Items[cacheKey] = configuration; + } + + return configuration; + } + + protected virtual string CreateCacheKey() + { + return $"ApplicationConfiguration_{CurrentUser.Id?.ToString("N") ?? "Anonymous"}_{CultureInfo.CurrentUICulture.Name}"; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClientExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClientExtensions.cs new file mode 100644 index 0000000000..601a2d1088 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClientExtensions.cs @@ -0,0 +1,13 @@ +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.Threading; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public static class CachedApplicationConfigurationClientExtensions + { + public static ApplicationConfigurationDto Get(this ICachedApplicationConfigurationClient client) + { + return AsyncHelper.RunSync(client.GetAsync); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs new file mode 100644 index 0000000000..71d9d8cddf --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public interface ICachedApplicationConfigurationClient + { + Task GetAsync(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs new file mode 100644 index 0000000000..d994a84335 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Localization; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public class RemoteLocalizationContributor : ILocalizationResourceContributor + { + private LocalizationResource _resource; + private ICachedApplicationConfigurationClient _applicationConfigurationClient; + private ILogger _logger; + + public void Initialize(LocalizationResourceInitializationContext context) + { + _resource = context.Resource; + _applicationConfigurationClient = context.ServiceProvider.GetRequiredService(); + _logger = context.ServiceProvider.GetService>() + ?? NullLogger.Instance; + } + + public LocalizedString GetOrNull(string cultureName, string name) + { + var resource = GetResourceOrNull(); + if (resource == null) + { + return null; + } + + var value = resource.GetOrDefault(name); + if (value == null) + { + return null; + } + + return new LocalizedString(name, value); + } + + public void Fill(string cultureName, Dictionary dictionary) + { + var resource = GetResourceOrNull(); + if (resource == null) + { + return; + } + + foreach (var keyValue in resource) + { + dictionary[keyValue.Key] = new LocalizedString(keyValue.Key, keyValue.Value); + } + } + + private Dictionary GetResourceOrNull() + { + var resource = _applicationConfigurationClient + .Get() + .Localization.Values + .GetOrDefault(_resource.ResourceName); + + if (resource == null) + { + _logger.LogWarning($"Could not find the localization resource {_resource.ResourceName} on the remote server!"); + } + + return resource; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs new file mode 100644 index 0000000000..cbddb7c3c7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs @@ -0,0 +1,30 @@ +using System.Security.Claims; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public class RemotePermissionChecker : IPermissionChecker, ITransientDependency + { + protected ICachedApplicationConfigurationClient ConfigurationClient { get; } + + public RemotePermissionChecker(ICachedApplicationConfigurationClient configurationClient) + { + ConfigurationClient = configurationClient; + } + + public async Task IsGrantedAsync(string name) + { + var configuration = await ConfigurationClient.GetAsync(); + + return configuration.Auth.GrantedPolicies.ContainsKey(name); + } + + public Task IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string name) + { + /* This provider always works for the current principal. */ + return IsGrantedAsync(name); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs new file mode 100644 index 0000000000..db3ea6e9a6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Settings; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public class RemoteSettingProvider : ISettingProvider, ITransientDependency + { + protected ICachedApplicationConfigurationClient ConfigurationClient { get; } + + public RemoteSettingProvider(ICachedApplicationConfigurationClient configurationClient) + { + ConfigurationClient = configurationClient; + } + + public async Task GetOrNullAsync(string name) + { + var configuration = await ConfigurationClient.GetAsync(); + return configuration.Setting.Values.GetOrDefault(name); + } + + public async Task> GetAllAsync() + { + var configuration = await ConfigurationClient.GetAsync(); + return configuration + .Setting.Values + .Select(s => new SettingValue(s.Key, s.Value)) + .ToList(); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj new file mode 100644 index 0000000000..8141097dc6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj @@ -0,0 +1,20 @@ + + + + + + netstandard2.0 + Volo.Abp.AspNetCore.Mvc.Contracts + Volo.Abp.AspNetCore.Mvc.Contracts + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs new file mode 100644 index 0000000000..54a7589dd4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc +{ + [DependsOn( + typeof(AbpDddApplicationModule) + )] + public class AbpAspNetCoreMvcContractsModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs new file mode 100644 index 0000000000..39b3ca394b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + [Serializable] + public class ApplicationAuthConfigurationDto + { + public Dictionary Policies { get; set; } + + public Dictionary GrantedPolicies { get; set; } + + public ApplicationAuthConfigurationDto() + { + Policies = new Dictionary(); + GrantedPolicies = new Dictionary(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs new file mode 100644 index 0000000000..6f41399c29 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + [Serializable] + public class ApplicationConfigurationDto + { + public ApplicationLocalizationConfigurationDto Localization { get; set; } + + public ApplicationAuthConfigurationDto Auth { get; set; } + + public ApplicationSettingConfigurationDto Setting { get; set; } + + public CurrentUserDto CurrentUser { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs new file mode 100644 index 0000000000..05b5d8c7a6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + [Serializable] + public class ApplicationLocalizationConfigurationDto + { + public Dictionary> Values { get; set; } + + public ApplicationLocalizationConfigurationDto() + { + Values = new Dictionary>(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationSettingConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationSettingConfigurationDto.cs new file mode 100644 index 0000000000..40cbd89fd1 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationSettingConfigurationDto.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + [Serializable] + public class ApplicationSettingConfigurationDto + { + public Dictionary Values { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs new file mode 100644 index 0000000000..702af56dba --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + [Serializable] + public class CurrentUserDto + { + public bool IsAuthenticated { get; set; } + + public Guid? Id { get; set; } + + public Guid? TenantId { get; set; } + + public string UserName { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IAbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IAbpApplicationConfigurationAppService.cs new file mode 100644 index 0000000000..4c521b9efc --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IAbpApplicationConfigurationAppService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + public interface IAbpApplicationConfigurationAppService : IApplicationService + { + Task GetAsync(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperLocalizer.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperLocalizer.cs new file mode 100644 index 0000000000..9f047c5b3c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperLocalizer.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.Localization; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers +{ + public class AbpTagHelperLocalizer : IAbpTagHelperLocalizer + { + private readonly IStringLocalizerFactory _stringLocalizerFactory; + private readonly AbpMvcDataAnnotationsLocalizationOptions _options; + + public AbpTagHelperLocalizer(IOptions options, IStringLocalizerFactory stringLocalizerFactory) + { + _stringLocalizerFactory = stringLocalizerFactory; + _options = options.Value; + } + + public string GetLocalizedText(string text, ModelExplorer explorer) + { + var resourceType = GetResourceTypeFromModelExplorer(explorer); + var localizer = GetStringLocalizer(resourceType); + + return localizer == null ? text : localizer[text].Value; + } + + public IStringLocalizer GetLocalizer(ModelExplorer explorer) + { + var resourceType = GetResourceTypeFromModelExplorer(explorer); + return GetStringLocalizer(resourceType); + } + + public IStringLocalizer GetLocalizer(Assembly assembly) + { + var resourceType = _options.AssemblyResources.GetOrDefault(assembly); + return GetStringLocalizer(resourceType); + } + + public IStringLocalizer GetLocalizer(Type resourceType) + { + return GetStringLocalizer(resourceType); + } + + private IStringLocalizer GetStringLocalizer(Type resourceType) + { + return resourceType == null ? null : _stringLocalizerFactory.Create(resourceType); + } + + private Type GetResourceTypeFromModelExplorer(ModelExplorer explorer) + { + var assembly = explorer.Container.ModelType.Assembly; + return _options.AssemblyResources.GetOrDefault(assembly); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 332210271b..566cbcffbc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -56,91 +56,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers Process(context, output); return Task.CompletedTask; } - - protected virtual TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false) - { - var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) - { - TagMode = tagMode - }; - - var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); - - if (runAsync) - { - AsyncHelper.RunSync(() => tagHelper.ProcessAsync(innerContext, innerOutput)); - } - else - { - tagHelper.Process(innerContext, innerOutput); - } - - return innerOutput; - } - - protected virtual string RenderTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false) - { - var innerOutput = GetInnerTagHelper(attributeList, context, tagHelper, tagName, tagMode, runAsync); - - return RenderTagHelperOutput(innerOutput, htmlEncoder); - } - - protected virtual string RenderTagHelperOutput(TagHelperOutput output, HtmlEncoder htmlEncoder) - { - using (var writer = new StringWriter()) - { - output.WriteTo(writer, htmlEncoder); - return writer.ToString(); - } - } - - protected virtual T GetAttribute(ModelExplorer property) where T : Attribute - { - return property?.Metadata?.ContainerType?.GetTypeInfo()?.GetProperty(property.Metadata.PropertyName)?.GetCustomAttribute(); - } - - protected virtual List GetFormGroupContentsList(TagHelperContext context, out bool surpress) - { - var items = GetValueFromContext>(context, FormGroupContents); - surpress = items != null; - - return items ?? new List(); - } - - protected virtual T GetValueFromContext(TagHelperContext context, string key) - { - if (!context.Items.ContainsKey(key)) - { - return default(T); - } - - return (T)context.Items[key]; - } - - protected virtual string GetIdAttributeAsString(TagHelperOutput inputTag) - { - var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); - - return idAttr != null ? "for=\"" + idAttr.Value + "\"" : ""; - } - - protected virtual int GetInputOrder(ModelExplorer explorer) - { - return GetAttribute(explorer)?.Number ?? DisplayOrder.Default; - } - - protected virtual void AddGroupToFormGroupContents(TagHelperContext context, string propertyName, string html, int order, out bool surpress) - { - var list = GetFormGroupContentsList(context, out surpress); - - if (list != null && !list.Any(igc => igc.HtmlContent.Contains("id=\"" + propertyName.Replace('.', '_') + "\""))) - { - list.Add(new FormGroupItem - { - HtmlContent = html, - Order = order - }); - } - } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbItemTagHelperService.cs index c19ac3acd8..1d6204373a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbItemTagHelperService.cs @@ -2,6 +2,7 @@ using System.Text.Encodings.Web; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Breadcrumb { @@ -20,13 +21,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Breadcrumb output.Attributes.AddClass("breadcrumb-item"); output.Attributes.AddClass(AbpBreadcrumbItemActivePlaceholder); - var list = GetValueFromContext>(context, BreadcrumbItemsContent); + var list = context.GetValue>(BreadcrumbItemsContent); output.Content.SetHtmlContent(GetInnerHtml(context, output)); list.Add(new BreadcrumbItem { - Html = RenderTagHelperOutput(output, _encoder), + Html = output.Render(_encoder), Active = TagHelper.Active }); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSize.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSize.cs index 65a0842d7b..dd07ff22bf 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSize.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSize.cs @@ -5,6 +5,10 @@ Default, Small, Medium, - Large + Large, + Block, + Block_Small, + Block_Medium, + Block_Large, } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSizeExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSizeExtensions.cs index 4231ac7ba6..408ba37573 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSizeExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonSizeExtensions.cs @@ -12,6 +12,14 @@ return "btn-md"; case AbpButtonSize.Large: return "btn-lg"; + case AbpButtonSize.Block: + return "btn-block"; + case AbpButtonSize.Block_Small: + return "btn-sm btn-block"; + case AbpButtonSize.Block_Medium: + return "btn-md btn-block"; + case AbpButtonSize.Block_Large: + return "btn-lg btn-block"; case AbpButtonSize.Default: return ""; default: diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs index afd718da8f..56143ea059 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs @@ -9,14 +9,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button public AbpButtonSize Size { get; set; } = AbpButtonSize.Default; - public bool? Block { get; set; } = false; - public string BusyText { get; set; } public string Text { get; set; } public string Icon { get; set; } + public bool? Disabled { get; set; } + public FontIconType IconType { get; set; } = FontIconType.FontAwesome; public AbpButtonTagHelper(AbpButtonTagHelperService service) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs index b6f2e8f3d1..419aff7c08 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs @@ -13,6 +13,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button AddClasses(context, output); AddIcon(context, output); AddText(context, output); + AddDisabled(context, output); } protected virtual void NormalizeTagMode(TagHelperContext context, TagHelperOutput output) @@ -33,11 +34,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button { output.Attributes.AddClass(TagHelper.Size.ToClassName()); } - - if (TagHelper.Block ?? false) - { - output.Attributes.AddClass("btn-block"); - } } protected virtual void AddIcon(TagHelperContext context, TagHelperOutput output) @@ -70,5 +66,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button output.Content.AppendHtml($"{TagHelper.Text}"); } + + protected virtual void AddDisabled(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Disabled ?? false) + { + output.Attributes.Add("disabled", "disabled"); + } + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs new file mode 100644 index 0000000000..7c716b88f8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonToolbarTagHelper : AbpTagHelper + { + public AbpButtonToolbarTagHelper(AbpButtonToolbarTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs new file mode 100644 index 0000000000..87b378e559 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonToolbarTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("btn-toolbar"); + output.Attributes.Add("role","toolbar"); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs index 8e517ea493..9a553a1be5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs @@ -11,12 +11,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button public AbpButtonSize Size { get; set; } = AbpButtonSize.Default; - public bool? Block { get; set; } = false; - public string Text { get; set; } public string Icon { get; set; } + public bool? Disabled { get; set; } + public FontIconType IconType { get; } = FontIconType.FontAwesome; public AbpLinkButtonTagHelper(AbpLinkButtonTagHelperService service) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs index dbe20def2a..ee88c4d294 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs @@ -6,12 +6,12 @@ AbpButtonSize Size { get; } - bool? Block { get;} - string Text { get; } string Icon { get; } + bool? Disabled { get; } + FontIconType IconType { get; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs new file mode 100644 index 0000000000..5e95e8bf87 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + [HtmlTargetElement("abp-card", Attributes = "background")] + [HtmlTargetElement("abp-card-header", Attributes = "background")] + [HtmlTargetElement("abp-card-body", Attributes = "background")] + [HtmlTargetElement("abp-card-footer", Attributes = "background")] + public class AbpCardBackgroundTagHelper : AbpTagHelper + { + public AbpCardBackgroundType Background { get; set; } = AbpCardBackgroundType.Default; + + public AbpCardBackgroundTagHelper(AbpCardBackgroundTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs new file mode 100644 index 0000000000..248d737648 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardBackgroundTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + SetBackground(context, output); + } + + protected virtual void SetBackground(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Background == AbpCardBackgroundType.Default) + { + return; + } + + output.Attributes.AddClass("bg-" + TagHelper.Background.ToString().ToLowerInvariant()); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs new file mode 100644 index 0000000000..2eb9732ce8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs @@ -0,0 +1,15 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardBackgroundType + { + Default, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark, + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs new file mode 100644 index 0000000000..0f5ccc3363 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs @@ -0,0 +1,15 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardBorderColorType + { + Default, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark, + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs new file mode 100644 index 0000000000..44b8588576 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardFooterTagHelper : AbpTagHelper + { + public AbpCardFooterTagHelper(AbpCardFooterTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs new file mode 100644 index 0000000000..2a127a495b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardFooterTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("card-footer"); + output.TagName = "div"; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs index 6bafed3376..4a173968d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs @@ -3,6 +3,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card { [HtmlTargetElement("img", Attributes = "abp-card-image", TagStructure = TagStructure.WithoutEndTag)] + [HtmlTargetElement("abp-image", Attributes = "abp-card-image", TagStructure = TagStructure.WithoutEndTag)] public class AbpCardImageTagHelper : AbpTagHelper { [HtmlAttributeName("abp-card-image")] diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs index 4dcf439e01..c186e8857c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs @@ -2,6 +2,8 @@ { public class AbpCardTagHelper : AbpTagHelper { + public AbpCardBorderColorType Border { get; set; } = AbpCardBorderColorType.Default; + public AbpCardTagHelper(AbpCardTagHelperService tagHelperService) : base(tagHelperService) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs index 4eb0c286f8..29a462797d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs @@ -9,6 +9,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card { output.TagName = "div"; output.Attributes.AddClass("card"); + + SetBorder(context, output); + } + protected virtual void SetBorder(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Border == AbpCardBorderColorType.Default) + { + return; + } + + output.Attributes.AddClass("border-" + TagHelper.Border.ToString().ToLowerInvariant()); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs new file mode 100644 index 0000000000..f9787b1f18 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + [HtmlTargetElement("abp-card", Attributes = "text-color")] + [HtmlTargetElement("abp-card-header", Attributes = "text-color")] + [HtmlTargetElement("abp-card-body", Attributes = "text-color")] + [HtmlTargetElement("abp-card-footer", Attributes = "text-color")] + public class AbpCardTextColorTagHelper : AbpTagHelper + { + public AbpCardTextColorType TextColor { get; set; } = AbpCardTextColorType.Default; + + public AbpCardTextColorTagHelper(AbpCardTextColorTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs new file mode 100644 index 0000000000..36484a33f8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardTextColorTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + SetTextColor(context, output); + } + + protected virtual void SetTextColor(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.TextColor == AbpCardTextColorType.Default) + { + return; + } + + output.Attributes.AddClass("text-" + TagHelper.TextColor.ToString().ToLowerInvariant()); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs new file mode 100644 index 0000000000..eb415945b0 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs @@ -0,0 +1,16 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardTextColorType + { + Default, + White, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselItemTagHelperService.cs index 9b44254f17..5a4bafd47d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselItemTagHelperService.cs @@ -3,6 +3,7 @@ using System.Text; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Carousel { @@ -32,9 +33,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Carousel private void AddToContext(TagHelperContext context, TagHelperOutput output) { - var getOutputAsHtml = RenderTagHelperOutput(output, _encoder); + var getOutputAsHtml = output.Render(_encoder); - var itemList = GetValueFromContext>(context, CarouselItemsContent); + var itemList = context.GetValue>(CarouselItemsContent); itemList.Add(new CarouselItem(getOutputAsHtml, TagHelper.Active ?? false)); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs index 749218cab0..ffba80fb6f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs @@ -127,7 +127,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Carousel { if (string.IsNullOrWhiteSpace(TagHelper.Id)) { - TagHelper.Id = Guid.NewGuid().ToString("N"); + TagHelper.Id = "C" + Guid.NewGuid().ToString("N"); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs index fabdb36452..9dc279334b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { @@ -15,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse var html = GetAccordionHeaderItem(context, output) + GetAccordionContentItem(context, output, innerContent); - var tabHeaderItems = GetValueFromContext>(context, AccordionItems); + var tabHeaderItems = context.GetValue>(AccordionItems); tabHeaderItems.Add(html); @@ -59,7 +60,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { if (string.IsNullOrWhiteSpace(TagHelper.Id)) { - TagHelper.Id = Guid.NewGuid().ToString("N"); + TagHelper.Id = "A" + Guid.NewGuid().ToString("N"); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs index 1d0a9234fd..20e62604a9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs @@ -55,7 +55,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { if (string.IsNullOrWhiteSpace(TagHelper.Id)) { - TagHelper.Id = Guid.NewGuid().ToString("N"); + TagHelper.Id = "A" + Guid.NewGuid().ToString("N"); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs index 0d4aecab31..a50907addb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs @@ -4,6 +4,8 @@ { public string Id { get; set; } + public bool? Multi { get; set; } + public bool? Show { get; set; } public AbpCollapseBodyTagHelper(AbpCollapseBodyTagHelperService tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs index 56b04df63d..10e49b92a7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs @@ -17,16 +17,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse output.Attributes.AddClass("show"); } - var innerContent = (await output.GetChildContentAsync()).GetContent(); - - var body = GetBody(context, output, innerContent); + if (TagHelper.Multi ?? false) + { + output.Attributes.AddClass("multi-collapse"); + } - output.Content.SetHtmlContent(body); - } + var innerContent = (await output.GetChildContentAsync()).GetContent(); - protected virtual string GetBody(TagHelperContext context, TagHelperOutput output, string innerContent) - { - return "
    " + innerContent + "
    "; + output.Content.SetHtmlContent(innerContent); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs index 2e6da81cf0..6b8fc8c30b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs @@ -1,11 +1,14 @@ -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { + + [HtmlTargetElement("abp-button", Attributes = "abp-collapse-id")] + [HtmlTargetElement("a", Attributes = "abp-collapse-id")] public class AbpCollapseButtonTagHelper : AbpTagHelper { - public AbpButtonType ButonType { get; set; } = AbpButtonType.Default; - + [HtmlAttributeName("abp-collapse-id")] public string BodyId { get; set; } public AbpCollapseButtonTagHelper(AbpCollapseButtonTagHelperService tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs index c2221035c1..6b7d74b866 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs @@ -8,20 +8,48 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { public override void Process(TagHelperContext context, TagHelperOutput output) { - output.TagName = "button"; - output.Attributes.AddClass("btn"); - output.Attributes.Add("data-toggle","collapse"); - output.Attributes.Add("aria-expanded","false"); - output.Attributes.Add("type","button"); - output.Attributes.Add("data-target", "#" +TagHelper.BodyId); + + + AddCommonAttributes(context, output); + + if (output.TagName == "abp-button" || output.TagName == "button") + { + AddButtonAttributes(context,output); + } + else if (output.TagName == "a") + { + AddLinkAttributes(context, output); + } + } + + protected virtual void AddCommonAttributes(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.Add("data-toggle", "collapse"); + output.Attributes.Add("aria-expanded", "false"); output.Attributes.Add("aria-controls", TagHelper.BodyId); + } + protected virtual void AddButtonAttributes(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.BodyId.Trim().Split(' ').Length > 1) + { + output.Attributes.Add("data-target", ".multi-collapse"); + return; + } - if (TagHelper.ButonType != AbpButtonType.Default) + output.Attributes.Add("data-target", "#" + TagHelper.BodyId); + } + + protected virtual void AddLinkAttributes(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.BodyId.Trim().Split(' ').Length > 1) { - output.Attributes.AddClass("btn-" + TagHelper.ButonType.ToString().ToLowerInvariant()); + output.Attributes.Add("href", ".multi-collapse"); + return; } + + output.Attributes.Add("href", "#" + TagHelper.BodyId); } - + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs index 60a34a71f1..ee17262d96 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs @@ -1,10 +1,12 @@ using System; using System.Text; using System.Text.Encodings.Web; +using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown { @@ -22,22 +24,25 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown _serviceProvider = serviceProvider; } - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { - var buttonsAsHtml = GetButtonsAsHtml(context, output); + var content = await output.GetChildContentAsync(); + + var buttonsAsHtml = GetButtonsAsHtml(context, output, content); output.PreElement.SetHtmlContent(buttonsAsHtml); output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; + output.Content.SetContent(""); output.Attributes.Clear(); } - protected virtual string GetButtonsAsHtml(TagHelperContext context, TagHelperOutput output) + protected virtual string GetButtonsAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperContent content) { var buttonBuilder = new StringBuilder(""); - var mainButton = GetMainButton(context, output); + var mainButton = GetMainButton(context, output, content); buttonBuilder.AppendLine(mainButton); @@ -51,10 +56,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown return buttonBuilder.ToString(); } - protected virtual string GetMainButton(TagHelperContext context, TagHelperOutput output) + protected virtual string GetMainButton(TagHelperContext context, TagHelperOutput output, TagHelperContent content) { var abpButtonTagHelper = _serviceProvider.GetRequiredService(); - + abpButtonTagHelper.Icon = TagHelper.Icon; abpButtonTagHelper.Text = TagHelper.Text; abpButtonTagHelper.IconType = TagHelper.IconType; @@ -62,15 +67,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown abpButtonTagHelper.ButtonType = TagHelper.ButtonType; var attributes = GetAttributesForMainButton(context, output); - var buttonTag = GetInnerTagHelper(attributes, context, abpButtonTagHelper, "button", TagMode.StartTagAndEndTag); + var buttonTag = abpButtonTagHelper.ProcessAndGetOutput(attributes, context, "button", TagMode.StartTagAndEndTag); + + buttonTag.PreContent.SetHtmlContent(content.GetContent()); if ((TagHelper.NavLink ?? false) || (TagHelper.Link ?? false)) { var linkTag = ConvertButtonToLink(buttonTag); - return RenderTagHelperOutput(linkTag, _htmlEncoder); + return linkTag.Render(_htmlEncoder); } - return RenderTagHelperOutput(buttonTag, _htmlEncoder); + return buttonTag.Render(_htmlEncoder); } protected virtual string GetSplitButton(TagHelperContext context, TagHelperOutput output) @@ -81,7 +88,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown abpButtonTagHelper.ButtonType = TagHelper.ButtonType; var attributes = GetAttributesForSplitButton(context, output); - return RenderTagHelper(attributes, context, abpButtonTagHelper, _htmlEncoder, "button", TagMode.StartTagAndEndTag); + return abpButtonTagHelper.Render(attributes, context, _htmlEncoder, "button", TagMode.StartTagAndEndTag); } protected virtual TagHelperAttributeList GetAttributesForMainButton(TagHelperContext context, TagHelperOutput output) @@ -125,6 +132,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown buttonTag.TagName = "a"; buttonTag.Attributes.RemoveAll("type"); buttonTag.Attributes.Add("roles", "button"); + buttonTag.Attributes.Add("href", "#"); if (TagHelper.NavLink??false) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs new file mode 100644 index 0000000000..4c5e82fac7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown +{ + public class AbpDropdownItemTextTagHelper : AbpTagHelper + { + public AbpDropdownItemTextTagHelper(AbpDropdownItemTextTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs new file mode 100644 index 0000000000..8cd84eade6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown +{ + public class AbpDropdownItemTextTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("dropdown-item-text"); + output.TagName = "span"; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs index 945221ff2d..8f37fca5ee 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs @@ -8,6 +8,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; + output.Attributes.AddClass("dropdown"); output.Attributes.AddClass("btn-group"); SetDirection(context, output); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/ModelExplorerExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/ModelExplorerExtensions.cs new file mode 100644 index 0000000000..b6bedac11b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/ModelExplorerExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions +{ + public static class ModelExplorerExtensions + { + public static T GetAttribute(this ModelExplorer property) where T : Attribute + { + return property?.Metadata?.ContainerType?.GetTypeInfo()?.GetProperty(property.Metadata.PropertyName)?.GetCustomAttribute(); + } + + public static int GetDisplayOrder(this ModelExplorer explorer) + { + return GetAttribute(explorer)?.Number ?? DisplayOrder.Default; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperAttributeExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperAttributeExtensions.cs new file mode 100644 index 0000000000..ef581529a6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperAttributeExtensions.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions +{ + public static class TagHelperAttributeExtensions + { + public static string ToHtmlAttributeAsString(this TagHelperAttribute attribute) + { + return attribute.Name + "=\"" + attribute.Value + "\""; + } + + public static string ToHtmlAttributesAsString(this List attributes) + { + var attributesAsString = ""; + + foreach (var attribute in attributes) + { + attributesAsString += attribute.ToHtmlAttributeAsString() + " "; + } + + return attributesAsString; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperContextExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperContextExtensions.cs new file mode 100644 index 0000000000..c2b3e41192 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperContextExtensions.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions +{ + public static class TagHelperContextExtensions + { + public static T GetValue(this TagHelperContext context, string key) + { + if (!context.Items.ContainsKey(key)) + { + return default(T); + } + + return (T)context.Items[key]; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperExtensions.cs new file mode 100644 index 0000000000..ee984474d2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperExtensions.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.TagHelpers; +using System.Text.Encodings.Web; +using Volo.Abp.Threading; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions +{ + public static class TagHelperExtensions + { + public static TagHelperOutput ProcessAndGetOutput(this TagHelper tagHelper, TagHelperAttributeList attributeList, TagHelperContext context, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false) + { + var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) + { + TagMode = tagMode + }; + + var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); + + tagHelper.Init(context); + + if (runAsync) + { + AsyncHelper.RunSync(() => tagHelper.ProcessAsync(innerContext, innerOutput)); + } + else + { + tagHelper.Process(innerContext, innerOutput); + } + + return innerOutput; + } + + public static string Render(this TagHelper tagHelper, TagHelperAttributeList attributeList, TagHelperContext context, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false) + { + var innerOutput = tagHelper.ProcessAndGetOutput(attributeList, context, tagName, tagMode, runAsync); + + return innerOutput.Render(htmlEncoder); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperOutputExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperOutputExtensions.cs new file mode 100644 index 0000000000..0cc9bae6e2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Extensions/TagHelperOutputExtensions.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using System.IO; +using System.Text.Encodings.Web; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions +{ + public static class TagHelperOutputExtensions + { + public static string Render(this TagHelperOutput output, HtmlEncoder htmlEncoder) + { + using (var writer = new StringWriter()) + { + output.WriteTo(writer, htmlEncoder); + return writer.ToString(); + } + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs index a6c5c80c06..141d995fd7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs @@ -18,6 +18,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public bool? SubmitButton { get; set; } + public bool? RequiredSymbols { get; set; } = true; + #region MvcFormTagHelperAttiributes private const string ActionAttributeName = "asp-action"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 3d7504f72d..a9f3bb9c62 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { @@ -66,7 +67,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ViewContext = TagHelper.ViewContext }; - var formTagOutput = GetInnerTagHelper(output.Attributes, context, formTagHelper, "form", TagMode.StartTagAndEndTag); + var formTagOutput = formTagHelper.ProcessAndGetOutput(output.Attributes, context, "form", TagMode.StartTagAndEndTag); await formTagOutput.GetChildContentAsync(); @@ -146,7 +147,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { var abpSelectTagHelper = GetSelectGroupTagHelper(context, output, model); - RenderTagHelper(new TagHelperAttributeList(), context, abpSelectTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag); + abpSelectTagHelper.Render(new TagHelperAttributeList(), context, _htmlEncoder, "div", TagMode.StartTagAndEndTag); } protected virtual AbpTagHelper GetSelectGroupTagHelper(TagHelperContext context, TagHelperOutput output, ModelExpression model) @@ -156,7 +157,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form GetSelectTagHelper(model); } - private AbpTagHelper GetSelectTagHelper(ModelExpression model) + protected virtual AbpTagHelper GetSelectTagHelper(ModelExpression model) { var abpSelectTagHelper = _serviceProvider.GetRequiredService(); abpSelectTagHelper.AspFor = model; @@ -165,9 +166,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return abpSelectTagHelper; } - private AbpTagHelper GetAbpRadioInputTagHelper(ModelExpression model) + protected virtual AbpTagHelper GetAbpRadioInputTagHelper(ModelExpression model) { - var radioButtonAttribute = GetAttribute(model.ModelExplorer); + var radioButtonAttribute = model.ModelExplorer.GetAttribute(); var abpRadioInputTagHelper = _serviceProvider.GetRequiredService(); abpRadioInputTagHelper.AspFor = model; abpRadioInputTagHelper.AspItems = null; @@ -184,7 +185,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form abpButtonTagHelper.Text = "Submit"; abpButtonTagHelper.ButtonType = AbpButtonType.Primary; - return RenderTagHelper(attributes, context, abpButtonTagHelper, _htmlEncoder, "button", TagMode.StartTagAndEndTag); + return abpButtonTagHelper.Render(attributes, context, _htmlEncoder, "button", TagMode.StartTagAndEndTag); } protected virtual void ProcessInputGroup(TagHelperContext context, TagHelperOutput output, ModelExpression model) @@ -192,8 +193,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var abpInputTagHelper = _serviceProvider.GetRequiredService(); abpInputTagHelper.AspFor = model; abpInputTagHelper.ViewContext = TagHelper.ViewContext; + abpInputTagHelper.DisplayRequiredSymbol = TagHelper.RequiredSymbols ?? true; - RenderTagHelper(new TagHelperAttributeList(), context, abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag); + abpInputTagHelper.Render(new TagHelperAttributeList(), context, _htmlEncoder, "div", TagMode.StartTagAndEndTag); } protected virtual List GetModels(TagHelperContext context, TagHelperOutput output) @@ -279,12 +281,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual bool AreSelectItemsProvided(ModelExplorer explorer) { - return GetAttribute(explorer) != null; + return explorer.GetAttribute() != null; } protected virtual bool IsRadioGroup(ModelExplorer explorer) { - return GetAttribute(explorer) != null; + return explorer.GetAttribute() != null; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs new file mode 100644 index 0000000000..79070b559e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public enum AbpFormControlSize + { + Default, + Small, + Medium, + Large + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index de93ff4b1d..10ce263032 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -10,14 +10,22 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public string Label { get; set; } + [HtmlAttributeName("info")] + public string InfoText { get; set; } + [HtmlAttributeName("disabled")] public bool IsDisabled { get; set; } = false; [HtmlAttributeName("readonly")] - public bool IsReadonly { get; set; } = false; + public bool? IsReadonly { get; set; } = false; public bool AutoFocus { get; set; } + public AbpFormControlSize Size { get; set; } = AbpFormControlSize.Default; + + [HtmlAttributeName("required-symbol")] + public bool DisplayRequiredSymbol { get; set; } = true; + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index b5abe780ae..cdf1f30788 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -1,10 +1,13 @@ using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { @@ -12,18 +15,20 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { private readonly IHtmlGenerator _generator; private readonly HtmlEncoder _encoder; + private readonly IAbpTagHelperLocalizer _tagHelperLocalizer; - public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder) + public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IAbpTagHelperLocalizer tagHelperLocalizer) { _generator = generator; _encoder = encoder; + _tagHelperLocalizer = tagHelperLocalizer; } public override void Process(TagHelperContext context, TagHelperOutput output) { var innerHtml = GetFormInputGroupAsHtml(context, output, out var isCheckbox); - var order = GetInputOrder(TagHelper.AspFor.ModelExplorer); + var order = TagHelper.AspFor.ModelExplorer.GetDisplayOrder(); AddGroupToFormGroupContents( context, @@ -42,7 +47,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form output.TagMode = TagMode.StartTagAndEndTag; output.TagName = "div"; LeaveOnlyGroupAttributes(context, output); - output.Attributes.AddClass(isCheckbox ? "form-check" : "form-group"); + output.Attributes.AddClass(isCheckbox ? "custom-checkbox" : "form-group"); + output.Attributes.AddClass(isCheckbox ? "custom-control" : ""); + output.Attributes.AddClass(isCheckbox ? "mb-2" : ""); output.Content.SetHtmlContent(output.Content.GetContent() + innerHtml); } } @@ -50,17 +57,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output, out bool isCheckbox) { var inputTag = GetInputTagHelperOutput(context, output, out isCheckbox); - var inputHtml = RenderTagHelperOutput(inputTag, _encoder); + + var inputHtml = inputTag.Render(_encoder); var label = GetLabelAsHtml(context, output, inputTag, isCheckbox); - + var info = GetInfoAsHtml(context, output, inputTag, isCheckbox); var validation = isCheckbox ? "" : GetValidationAsHtml(context, output, inputTag); - return GetContent(context, output, label, inputHtml, validation, isCheckbox); + return GetContent(context, output, label, inputHtml, validation, info, isCheckbox); } protected virtual string GetValidationAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag) { - if (inputTag.Attributes.Any(a => a.Name.ToLowerInvariant() == "type" && a.Value.ToString().ToLowerInvariant() == "hidden")) + if (IsOutputHidden(inputTag)) { return ""; } @@ -73,29 +81,28 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var attributeList = new TagHelperAttributeList { { "class", "text-danger" } }; - return RenderTagHelper(attributeList, context, validationMessageTagHelper, _encoder, "span", TagMode.StartTagAndEndTag, true); + return validationMessageTagHelper.Render(attributeList, context, _encoder, "span", TagMode.StartTagAndEndTag, true); } - protected virtual string GetContent(TagHelperContext context, TagHelperOutput output, string label, string inputHtml, string validation, bool isCheckbox) + protected virtual string GetContent(TagHelperContext context, TagHelperOutput output, string label, string inputHtml, string validation, string infoHtml, bool isCheckbox) { var innerContent = isCheckbox ? - inputHtml + Environment.NewLine + label : - label + Environment.NewLine + inputHtml; + inputHtml + label : + label + inputHtml; - return Environment.NewLine + innerContent + Environment.NewLine + - Environment.NewLine + validation + Environment.NewLine; + return innerContent + infoHtml + validation; } protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml, bool isCheckbox) { - return "
    " + + return "
    " + Environment.NewLine + innerHtml + Environment.NewLine + "
    "; } protected virtual TagHelper GetInputTagHelper(TagHelperContext context, TagHelperOutput output) { - var textAreaAttribute = GetAttribute"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + div.style.position = "absolute"; + scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + ) ); + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + val = curCSS( elem, dimension, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox; + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = valueIsBorderBox && + ( support.boxSizingReliable() || val === elem.style[ dimension ] ); + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + if ( val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { + + val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; + + // offsetWidth/offsetHeight provide border-box values + valueIsBorderBox = true; + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra && boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ); + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && support.scrollboxSize() === styles.position ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( "",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},o={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},r={cN:"literal",b:/\$(null|true|false)\b/},n={cN:"string",v:[{b:/"/,e:/"/},{b:/@"/,e:/^"@/}],c:[t,o,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",v:[{b:/'/,e:/'/},{b:/@'/,e:/^'@/}]},i={cN:"doctag",v:[{b:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{b:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]},s=e.inherit(e.C(null,null),{v:[{b:/#/,e:/$/},{b:/<#/,e:/#>/}],c:[i]});return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",built_in:"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct",nomarkup:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[t,e.NM,n,a,r,o,s]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C("'","$",{rB:!0,c:[{cN:"doctag",b:"'''|",c:[e.PWM]},{cN:"doctag",b:"",c:[e.PWM]}]}),e.CNM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end region externalsource"}}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},r=e.inherit(t,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},c=e.inherit(a,{i:/\n/}),n={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,c]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},c]});a.c=[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c=[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,n,t,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("vbscript",function(e){return{aliases:["vbs"],cI:!0,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C(/'/,/$/,{r:0}),e.CNM]}});hljs.registerLanguage("vbscript-html",function(r){return{sL:"xml",c:[{b:"<%",e:"%>",sL:"vbscript"}]}});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],s=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},b=function(e,r,t){return{cN:e,b:r,r:t}},n={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,s("'"),s('"'),e.CSSNM,{b:"(url|data-uri)\\(",starts:{cN:"string",e:"[\\)\\n]",eE:!0}},b("number","#[0-9A-Fa-f]+\\b"),n,b("variable","@@?"+r,10),b("variable","@{"+r+"}"),b("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0},{cN:"meta",b:"!important"});var i=c.concat({b:"{",e:"}",c:a}),o={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},u={b:t+"\\s*:",rB:!0,e:"[;}]",r:0,c:[{cN:"attribute",b:t,e:":",eE:!0,starts:{eW:!0,i:"[<=$]",r:0,c:c}}]},l={cN:"keyword",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},C={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:i}},p={v:[{b:"[\\.#:&\\[>]",e:"[;{}]"},{b:t,e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",r:0,c:[e.CLCM,e.CBCM,o,b("keyword","all\\b"),b("variable","@{"+r+"}"),b("selector-tag",t+"%?",0),b("selector-id","#"+t),b("selector-class","\\."+t,0),b("selector-tag","&",0),{cN:"selector-attr",b:"\\[",e:"\\]"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"\\(",e:"\\)",c:i},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,C,u,p),{cI:!0,i:"[=>'/<($\"]",c:a}});hljs.registerLanguage("dos",function(e){var r=e.C(/^\s*@?rem\b/,/$/,{r:10}),t={cN:"symbol",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,i:/\/\*/,k:{keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"},c:[{cN:"variable",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/agate.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/agate.css new file mode 100644 index 0000000000..8d64547c58 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/agate.css @@ -0,0 +1,108 @@ +/*! + * Agate by Taufik Nurrohman + * ---------------------------------------------------- + * + * #ade5fc + * #a2fca2 + * #c6b4f0 + * #d36363 + * #fcc28c + * #fc9b9b + * #ffa + * #fff + * #333 + * #62c8f3 + * #888 + * + */ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #333; + color: white; +} + +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-code, +.hljs-emphasis { + font-style: italic; +} + +.hljs-tag { + color: #62c8f3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-selector-id, +.hljs-selector-class { + color: #ade5fc; +} + +.hljs-string, +.hljs-bullet { + color: #a2fca2; +} + +.hljs-type, +.hljs-title, +.hljs-section, +.hljs-attribute, +.hljs-quote, +.hljs-built_in, +.hljs-builtin-name { + color: #ffa; +} + +.hljs-number, +.hljs-symbol, +.hljs-bullet { + color: #d36363; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal { + color: #fcc28c; +} + +.hljs-comment, +.hljs-deletion, +.hljs-code { + color: #888; +} + +.hljs-regexp, +.hljs-link { + color: #c6b4f0; +} + +.hljs-meta { + color: #fc9b9b; +} + +.hljs-deletion { + background-color: #fc9b9b; + color: #333; +} + +.hljs-addition { + background-color: #a2fca2; + color: #333; +} + +.hljs a { + color: inherit; +} + +.hljs a:focus, +.hljs a:hover { + color: inherit; + text-decoration: underline; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/androidstudio.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/androidstudio.css new file mode 100644 index 0000000000..bc8e473b59 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/androidstudio.css @@ -0,0 +1,66 @@ +/* +Date: 24 Fev 2015 +Author: Pedro Oliveira +*/ + +.hljs { + color: #a9b7c6; + background: #282b2e; + display: block; + overflow-x: auto; + padding: 0.5em; +} + +.hljs-number, +.hljs-literal, +.hljs-symbol, +.hljs-bullet { + color: #6897BB; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-deletion { + color: #cc7832; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-link { + color: #629755; +} + +.hljs-comment, +.hljs-quote { + color: #808080; +} + +.hljs-meta { + color: #bbb529; +} + +.hljs-string, +.hljs-attribute, +.hljs-addition { + color: #6A8759; +} + +.hljs-section, +.hljs-title, +.hljs-type { + color: #ffc66d; +} + +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #e8bf6a; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arduino-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arduino-light.css new file mode 100644 index 0000000000..4b8b7fd3c9 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arduino-light.css @@ -0,0 +1,88 @@ +/* + +Arduino® Light Theme - Stefania Mellai + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #FFFFFF; +} + +.hljs, +.hljs-subst { + color: #434f54; +} + +.hljs-keyword, +.hljs-attribute, +.hljs-selector-tag, +.hljs-doctag, +.hljs-name { + color: #00979D; +} + +.hljs-built_in, +.hljs-literal, +.hljs-bullet, +.hljs-code, +.hljs-addition { + color: #D35400; +} + +.hljs-regexp, +.hljs-symbol, +.hljs-variable, +.hljs-template-variable, +.hljs-link, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #00979D; +} + +.hljs-type, +.hljs-string, +.hljs-selector-id, +.hljs-selector-class, +.hljs-quote, +.hljs-template-tag, +.hljs-deletion { + color: #005C5F; +} + +.hljs-title, +.hljs-section { + color: #880000; + font-weight: bold; +} + +.hljs-comment { + color: rgba(149,165,166,.8); +} + +.hljs-meta-keyword { + color: #728E00; +} + +.hljs-meta { + color: #728E00; + color: #434f54; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-function { + color: #728E00; +} + +.hljs-number { + color: #8A7B52; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arta.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arta.css new file mode 100644 index 0000000000..75ef3a9e59 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/arta.css @@ -0,0 +1,73 @@ +/* +Date: 17.V.2011 +Author: pumbur +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #222; +} + +.hljs, +.hljs-subst { + color: #aaa; +} + +.hljs-section { + color: #fff; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #444; +} + +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-regexp { + color: #ffcc33; +} + +.hljs-number, +.hljs-addition { + color: #00cc66; +} + +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-template-variable, +.hljs-attribute, +.hljs-link { + color: #32aaee; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #6644aa; +} + +.hljs-title, +.hljs-variable, +.hljs-deletion, +.hljs-template-tag { + color: #bb1166; +} + +.hljs-section, +.hljs-doctag, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ascetic.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ascetic.css new file mode 100644 index 0000000000..48397e889d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ascetic.css @@ -0,0 +1,45 @@ +/* + +Original style from softwaremaniacs.org (c) Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-symbol, +.hljs-bullet, +.hljs-section, +.hljs-addition, +.hljs-attribute, +.hljs-link { + color: #888; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta, +.hljs-deletion { + color: #ccc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-section, +.hljs-name, +.hljs-type, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-dark.css new file mode 100644 index 0000000000..65428f3b12 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-dark.css @@ -0,0 +1,83 @@ +/* Base16 Atelier Cave Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Cave Comment */ +.hljs-comment, +.hljs-quote { + color: #7e7887; +} + +/* Atelier-Cave Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-regexp, +.hljs-link, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #be4678; +} + +/* Atelier-Cave Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #aa573c; +} + +/* Atelier-Cave Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #2a9292; +} + +/* Atelier-Cave Blue */ +.hljs-title, +.hljs-section { + color: #576ddb; +} + +/* Atelier-Cave Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #955ae7; +} + +.hljs-deletion, +.hljs-addition { + color: #19171c; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #be4678; +} + +.hljs-addition { + background-color: #2a9292; +} + +.hljs { + display: block; + overflow-x: auto; + background: #19171c; + color: #8b8792; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-light.css new file mode 100644 index 0000000000..b419f9fd8f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-cave-light.css @@ -0,0 +1,85 @@ +/* Base16 Atelier Cave Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Cave Comment */ +.hljs-comment, +.hljs-quote { + color: #655f6d; +} + +/* Atelier-Cave Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #be4678; +} + +/* Atelier-Cave Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #aa573c; +} + +/* Atelier-Cave Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #2a9292; +} + +/* Atelier-Cave Blue */ +.hljs-title, +.hljs-section { + color: #576ddb; +} + +/* Atelier-Cave Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #955ae7; +} + +.hljs-deletion, +.hljs-addition { + color: #19171c; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #be4678; +} + +.hljs-addition { + background-color: #2a9292; +} + +.hljs { + display: block; + overflow-x: auto; + background: #efecf4; + color: #585260; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-dark.css new file mode 100644 index 0000000000..1684f5225a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Dune Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Dune Comment */ +.hljs-comment, +.hljs-quote { + color: #999580; +} + +/* Atelier-Dune Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d73737; +} + +/* Atelier-Dune Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b65611; +} + +/* Atelier-Dune Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #60ac39; +} + +/* Atelier-Dune Blue */ +.hljs-title, +.hljs-section { + color: #6684e1; +} + +/* Atelier-Dune Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b854d4; +} + +.hljs { + display: block; + overflow-x: auto; + background: #20201d; + color: #a6a28c; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-light.css new file mode 100644 index 0000000000..547719de82 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-dune-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Dune Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Dune Comment */ +.hljs-comment, +.hljs-quote { + color: #7d7a68; +} + +/* Atelier-Dune Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d73737; +} + +/* Atelier-Dune Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b65611; +} + +/* Atelier-Dune Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #60ac39; +} + +/* Atelier-Dune Blue */ +.hljs-title, +.hljs-section { + color: #6684e1; +} + +/* Atelier-Dune Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b854d4; +} + +.hljs { + display: block; + overflow-x: auto; + background: #fefbec; + color: #6e6b5e; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-dark.css new file mode 100644 index 0000000000..a5e507187e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-dark.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Estuary Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Estuary Comment */ +.hljs-comment, +.hljs-quote { + color: #878573; +} + +/* Atelier-Estuary Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ba6236; +} + +/* Atelier-Estuary Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #ae7313; +} + +/* Atelier-Estuary Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #7d9726; +} + +/* Atelier-Estuary Blue */ +.hljs-title, +.hljs-section { + color: #36a166; +} + +/* Atelier-Estuary Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #5f9182; +} + +.hljs-deletion, +.hljs-addition { + color: #22221b; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #ba6236; +} + +.hljs-addition { + background-color: #7d9726; +} + +.hljs { + display: block; + overflow-x: auto; + background: #22221b; + color: #929181; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-light.css new file mode 100644 index 0000000000..1daee5d985 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-estuary-light.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Estuary Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Estuary Comment */ +.hljs-comment, +.hljs-quote { + color: #6c6b5a; +} + +/* Atelier-Estuary Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ba6236; +} + +/* Atelier-Estuary Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #ae7313; +} + +/* Atelier-Estuary Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #7d9726; +} + +/* Atelier-Estuary Blue */ +.hljs-title, +.hljs-section { + color: #36a166; +} + +/* Atelier-Estuary Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #5f9182; +} + +.hljs-deletion, +.hljs-addition { + color: #22221b; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #ba6236; +} + +.hljs-addition { + background-color: #7d9726; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f4f3ec; + color: #5f5e4e; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-dark.css new file mode 100644 index 0000000000..0ef4fae317 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Forest Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Forest Comment */ +.hljs-comment, +.hljs-quote { + color: #9c9491; +} + +/* Atelier-Forest Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #f22c40; +} + +/* Atelier-Forest Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #df5320; +} + +/* Atelier-Forest Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #7b9726; +} + +/* Atelier-Forest Blue */ +.hljs-title, +.hljs-section { + color: #407ee7; +} + +/* Atelier-Forest Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6666ea; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1b1918; + color: #a8a19f; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-light.css new file mode 100644 index 0000000000..bbedde18a0 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-forest-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Forest Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Forest Comment */ +.hljs-comment, +.hljs-quote { + color: #766e6b; +} + +/* Atelier-Forest Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #f22c40; +} + +/* Atelier-Forest Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #df5320; +} + +/* Atelier-Forest Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #7b9726; +} + +/* Atelier-Forest Blue */ +.hljs-title, +.hljs-section { + color: #407ee7; +} + +/* Atelier-Forest Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6666ea; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f1efee; + color: #68615e; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-dark.css new file mode 100644 index 0000000000..fe01ff721b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Heath Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Heath Comment */ +.hljs-comment, +.hljs-quote { + color: #9e8f9e; +} + +/* Atelier-Heath Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ca402b; +} + +/* Atelier-Heath Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #a65926; +} + +/* Atelier-Heath Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #918b3b; +} + +/* Atelier-Heath Blue */ +.hljs-title, +.hljs-section { + color: #516aec; +} + +/* Atelier-Heath Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #7b59c0; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1b181b; + color: #ab9bab; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-light.css new file mode 100644 index 0000000000..ee43786d12 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-heath-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Heath Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Heath Comment */ +.hljs-comment, +.hljs-quote { + color: #776977; +} + +/* Atelier-Heath Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ca402b; +} + +/* Atelier-Heath Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #a65926; +} + +/* Atelier-Heath Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #918b3b; +} + +/* Atelier-Heath Blue */ +.hljs-title, +.hljs-section { + color: #516aec; +} + +/* Atelier-Heath Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #7b59c0; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f7f3f7; + color: #695d69; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-dark.css new file mode 100644 index 0000000000..a937d3bf5f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Lakeside Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Lakeside Comment */ +.hljs-comment, +.hljs-quote { + color: #7195a8; +} + +/* Atelier-Lakeside Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d22d72; +} + +/* Atelier-Lakeside Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #935c25; +} + +/* Atelier-Lakeside Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #568c3b; +} + +/* Atelier-Lakeside Blue */ +.hljs-title, +.hljs-section { + color: #257fad; +} + +/* Atelier-Lakeside Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6b6bb8; +} + +.hljs { + display: block; + overflow-x: auto; + background: #161b1d; + color: #7ea2b4; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-light.css new file mode 100644 index 0000000000..6c7e8f9ef2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-lakeside-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Lakeside Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Lakeside Comment */ +.hljs-comment, +.hljs-quote { + color: #5a7b8c; +} + +/* Atelier-Lakeside Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d22d72; +} + +/* Atelier-Lakeside Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #935c25; +} + +/* Atelier-Lakeside Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #568c3b; +} + +/* Atelier-Lakeside Blue */ +.hljs-title, +.hljs-section { + color: #257fad; +} + +/* Atelier-Lakeside Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6b6bb8; +} + +.hljs { + display: block; + overflow-x: auto; + background: #ebf8ff; + color: #516d7b; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-dark.css new file mode 100644 index 0000000000..3bb052693c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-dark.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Plateau Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Plateau Comment */ +.hljs-comment, +.hljs-quote { + color: #7e7777; +} + +/* Atelier-Plateau Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ca4949; +} + +/* Atelier-Plateau Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b45a3c; +} + +/* Atelier-Plateau Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #4b8b8b; +} + +/* Atelier-Plateau Blue */ +.hljs-title, +.hljs-section { + color: #7272ca; +} + +/* Atelier-Plateau Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #8464c4; +} + +.hljs-deletion, +.hljs-addition { + color: #1b1818; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #ca4949; +} + +.hljs-addition { + background-color: #4b8b8b; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1b1818; + color: #8a8585; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-light.css new file mode 100644 index 0000000000..5f0222bec1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-plateau-light.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Plateau Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Plateau Comment */ +.hljs-comment, +.hljs-quote { + color: #655d5d; +} + +/* Atelier-Plateau Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #ca4949; +} + +/* Atelier-Plateau Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b45a3c; +} + +/* Atelier-Plateau Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #4b8b8b; +} + +/* Atelier-Plateau Blue */ +.hljs-title, +.hljs-section { + color: #7272ca; +} + +/* Atelier-Plateau Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #8464c4; +} + +.hljs-deletion, +.hljs-addition { + color: #1b1818; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #ca4949; +} + +.hljs-addition { + background-color: #4b8b8b; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f4ecec; + color: #585050; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-dark.css new file mode 100644 index 0000000000..38f831431c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-dark.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Savanna Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Savanna Comment */ +.hljs-comment, +.hljs-quote { + color: #78877d; +} + +/* Atelier-Savanna Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #b16139; +} + +/* Atelier-Savanna Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #9f713c; +} + +/* Atelier-Savanna Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #489963; +} + +/* Atelier-Savanna Blue */ +.hljs-title, +.hljs-section { + color: #478c90; +} + +/* Atelier-Savanna Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #55859b; +} + +.hljs-deletion, +.hljs-addition { + color: #171c19; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #b16139; +} + +.hljs-addition { + background-color: #489963; +} + +.hljs { + display: block; + overflow-x: auto; + background: #171c19; + color: #87928a; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-light.css new file mode 100644 index 0000000000..1ccd7c6858 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-savanna-light.css @@ -0,0 +1,84 @@ +/* Base16 Atelier Savanna Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Savanna Comment */ +.hljs-comment, +.hljs-quote { + color: #5f6d64; +} + +/* Atelier-Savanna Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #b16139; +} + +/* Atelier-Savanna Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #9f713c; +} + +/* Atelier-Savanna Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #489963; +} + +/* Atelier-Savanna Blue */ +.hljs-title, +.hljs-section { + color: #478c90; +} + +/* Atelier-Savanna Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #55859b; +} + +.hljs-deletion, +.hljs-addition { + color: #171c19; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #b16139; +} + +.hljs-addition { + background-color: #489963; +} + +.hljs { + display: block; + overflow-x: auto; + background: #ecf4ee; + color: #526057; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-dark.css new file mode 100644 index 0000000000..df29949c69 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Seaside Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Seaside Comment */ +.hljs-comment, +.hljs-quote { + color: #809980; +} + +/* Atelier-Seaside Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #e6193c; +} + +/* Atelier-Seaside Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #87711d; +} + +/* Atelier-Seaside Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #29a329; +} + +/* Atelier-Seaside Blue */ +.hljs-title, +.hljs-section { + color: #3d62f5; +} + +/* Atelier-Seaside Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #ad2bee; +} + +.hljs { + display: block; + overflow-x: auto; + background: #131513; + color: #8ca68c; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-light.css new file mode 100644 index 0000000000..9d960f29f3 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-seaside-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Seaside Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Seaside Comment */ +.hljs-comment, +.hljs-quote { + color: #687d68; +} + +/* Atelier-Seaside Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #e6193c; +} + +/* Atelier-Seaside Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #87711d; +} + +/* Atelier-Seaside Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #29a329; +} + +/* Atelier-Seaside Blue */ +.hljs-title, +.hljs-section { + color: #3d62f5; +} + +/* Atelier-Seaside Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #ad2bee; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f4fbf4; + color: #5e6e5e; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-dark.css new file mode 100644 index 0000000000..c2ab7938d8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-dark.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Sulphurpool Dark - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Sulphurpool Comment */ +.hljs-comment, +.hljs-quote { + color: #898ea4; +} + +/* Atelier-Sulphurpool Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #c94922; +} + +/* Atelier-Sulphurpool Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #c76b29; +} + +/* Atelier-Sulphurpool Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #ac9739; +} + +/* Atelier-Sulphurpool Blue */ +.hljs-title, +.hljs-section { + color: #3d8fd1; +} + +/* Atelier-Sulphurpool Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6679cc; +} + +.hljs { + display: block; + overflow-x: auto; + background: #202746; + color: #979db4; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-light.css new file mode 100644 index 0000000000..96c47d0860 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-light.css @@ -0,0 +1,69 @@ +/* Base16 Atelier Sulphurpool Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Sulphurpool Comment */ +.hljs-comment, +.hljs-quote { + color: #6b7394; +} + +/* Atelier-Sulphurpool Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #c94922; +} + +/* Atelier-Sulphurpool Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #c76b29; +} + +/* Atelier-Sulphurpool Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #ac9739; +} + +/* Atelier-Sulphurpool Blue */ +.hljs-title, +.hljs-section { + color: #3d8fd1; +} + +/* Atelier-Sulphurpool Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #6679cc; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f5f7ff; + color: #5e6687; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-dark.css new file mode 100644 index 0000000000..1616aafe31 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-dark.css @@ -0,0 +1,96 @@ +/* + +Atom One Dark by Daniel Gamage +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +base: #282c34 +mono-1: #abb2bf +mono-2: #818896 +mono-3: #5c6370 +hue-1: #56b6c2 +hue-2: #61aeee +hue-3: #c678dd +hue-4: #98c379 +hue-5: #e06c75 +hue-5-2: #be5046 +hue-6: #d19a66 +hue-6-2: #e6c07b + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #abb2bf; + background: #282c34; +} + +.hljs-comment, +.hljs-quote { + color: #5c6370; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #c678dd; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e06c75; +} + +.hljs-literal { + color: #56b6c2; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #98c379; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #e6c07b; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #d19a66; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #61aeee; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-light.css new file mode 100644 index 0000000000..d5bd1d2a9a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/atom-one-light.css @@ -0,0 +1,96 @@ +/* + +Atom One Light by Daniel Gamage +Original One Light Syntax theme from https://github.com/atom/one-light-syntax + +base: #fafafa +mono-1: #383a42 +mono-2: #686b77 +mono-3: #a0a1a7 +hue-1: #0184bb +hue-2: #4078f2 +hue-3: #a626a4 +hue-4: #50a14f +hue-5: #e45649 +hue-5-2: #c91243 +hue-6: #986801 +hue-6-2: #c18401 + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #383a42; + background: #fafafa; +} + +.hljs-comment, +.hljs-quote { + color: #a0a1a7; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #a626a4; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e45649; +} + +.hljs-literal { + color: #0184bb; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #50a14f; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #c18401; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #986801; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #4078f2; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-paper.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-paper.css new file mode 100644 index 0000000000..f0197b924c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-paper.css @@ -0,0 +1,64 @@ +/* + +Brown Paper style from goldblog.com.ua (c) Zaripov Yura + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background:#b7a68e url(./brown-papersq.png); +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal { + color:#005599; + font-weight:bold; +} + +.hljs, +.hljs-subst { + color: #363c69; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-built_in, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable, +.hljs-link, +.hljs-name { + color: #2c009f; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta, +.hljs-deletion { + color: #802022; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-papersq.png b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-papersq.png new file mode 100644 index 0000000000..3813903dbf Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/brown-papersq.png differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/codepen-embed.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/codepen-embed.css new file mode 100644 index 0000000000..195c4a0784 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/codepen-embed.css @@ -0,0 +1,60 @@ +/* + codepen.io Embed Theme + Author: Justin Perry + Original theme - https://github.com/chriskempson/tomorrow-theme +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #222; + color: #fff; +} + +.hljs-comment, +.hljs-quote { + color: #777; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-regexp, +.hljs-meta, +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-params, +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-deletion { + color: #ab875d; +} + +.hljs-section, +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-type, +.hljs-attribute { + color: #9b869b; +} + +.hljs-string, +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #8f9c6c; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/color-brewer.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/color-brewer.css new file mode 100644 index 0000000000..7934d986a7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/color-brewer.css @@ -0,0 +1,71 @@ +/* + +Colorbrewer theme +Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock +Ported by Fabrício Tavares de Oliveira + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fff; +} + +.hljs, +.hljs-subst { + color: #000; +} + +.hljs-string, +.hljs-meta, +.hljs-symbol, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition { + color: #756bb1; +} + +.hljs-comment, +.hljs-quote { + color: #636363; +} + +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-bullet, +.hljs-link { + color: #31a354; +} + +.hljs-deletion, +.hljs-variable { + color: #88f; +} + + + +.hljs-keyword, +.hljs-selector-tag, +.hljs-title, +.hljs-section, +.hljs-built_in, +.hljs-doctag, +.hljs-type, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-strong { + color: #3182bd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-attribute { + color: #e6550d; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darcula.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darcula.css new file mode 100644 index 0000000000..be182d0b50 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darcula.css @@ -0,0 +1,77 @@ +/* + +Darcula color scheme from the JetBrains family of IDEs + +*/ + + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #2b2b2b; +} + +.hljs { + color: #bababa; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-link, +.hljs-number, +.hljs-regexp, +.hljs-literal { + color: #6896ba; +} + +.hljs-code, +.hljs-selector-class { + color: #a6e22e; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-section, +.hljs-attribute, +.hljs-name, +.hljs-variable { + color: #cb7832; +} + +.hljs-params { + color: #b9b9b9; +} + +.hljs-string { + color: #6a8759; +} + +.hljs-subst, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-symbol, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition { + color: #e0c46c; +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #7f7f7f; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dark.css new file mode 100644 index 0000000000..b4724f5f50 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dark.css @@ -0,0 +1,63 @@ +/* + +Dark style from softwaremaniacs.org (c) Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #444; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-link { + color: white; +} + +.hljs, +.hljs-subst { + color: #ddd; +} + +.hljs-string, +.hljs-title, +.hljs-name, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-built_in, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #d88; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #777; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darkula.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darkula.css new file mode 100644 index 0000000000..f4646c3c5d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/darkula.css @@ -0,0 +1,6 @@ +/* + Deprecated due to a typo in the name and left here for compatibility purpose only. + Please use darcula.css instead. +*/ + +@import url('darcula.css'); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/default.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/default.css new file mode 100644 index 0000000000..f1bfade31e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/default.css @@ -0,0 +1,99 @@ +/* + +Original highlight.js style (c) Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #F0F0F0; +} + + +/* Base color: saturation 0; */ + +.hljs, +.hljs-subst { + color: #444; +} + +.hljs-comment { + color: #888888; +} + +.hljs-keyword, +.hljs-attribute, +.hljs-selector-tag, +.hljs-meta-keyword, +.hljs-doctag, +.hljs-name { + font-weight: bold; +} + + +/* User color: hue: 0 */ + +.hljs-type, +.hljs-string, +.hljs-number, +.hljs-selector-id, +.hljs-selector-class, +.hljs-quote, +.hljs-template-tag, +.hljs-deletion { + color: #880000; +} + +.hljs-title, +.hljs-section { + color: #880000; + font-weight: bold; +} + +.hljs-regexp, +.hljs-symbol, +.hljs-variable, +.hljs-template-variable, +.hljs-link, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #BC6060; +} + + +/* Language color: hue: 90; */ + +.hljs-literal { + color: #78A960; +} + +.hljs-built_in, +.hljs-bullet, +.hljs-code, +.hljs-addition { + color: #397300; +} + + +/* Meta color: hue: 200 */ + +.hljs-meta { + color: #1f7199; +} + +.hljs-meta-string { + color: #4d99bf; +} + + +/* Misc effects */ + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/docco.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/docco.css new file mode 100644 index 0000000000..db366be372 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/docco.css @@ -0,0 +1,97 @@ +/* +Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine (@thingsinjars) +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #000; + background: #f8f8ff; +} + +.hljs-comment, +.hljs-quote { + color: #408080; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-subst { + color: #954121; +} + +.hljs-number { + color: #40a070; +} + +.hljs-string, +.hljs-doctag { + color: #219161; +} + +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #19469d; +} + +.hljs-params { + color: #00f; +} + +.hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-variable, +.hljs-template-variable { + color: #008080; +} + +.hljs-regexp, +.hljs-link { + color: #b68; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dracula.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dracula.css new file mode 100644 index 0000000000..d591db6801 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/dracula.css @@ -0,0 +1,76 @@ +/* + +Dracula Theme v1.2.0 + +https://github.com/zenorocha/dracula-theme + +Copyright 2015, All rights reserved + +Code licensed under the MIT license +http://zenorocha.mit-license.org + +@author Éverton Ribeiro +@author Zeno Rocha + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282a36; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-link { + color: #8be9fd; +} + +.hljs-function .hljs-keyword { + color: #ff79c6; +} + +.hljs, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-string, +.hljs-title, +.hljs-name, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #f1fa8c; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #6272a4; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/far.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/far.css new file mode 100644 index 0000000000..2b3f87b562 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/far.css @@ -0,0 +1,71 @@ +/* + +FAR Style (c) MajestiC + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #000080; +} + +.hljs, +.hljs-subst { + color: #0ff; +} + +.hljs-string, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-built_in, +.hljs-builtin-name, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition { + color: #ff0; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-section, +.hljs-type, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-variable { + color: #fff; +} + +.hljs-comment, +.hljs-quote, +.hljs-doctag, +.hljs-deletion { + color: #888; +} + +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-link { + color: #0f0; +} + +.hljs-meta { + color: #008080; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/foundation.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/foundation.css new file mode 100644 index 0000000000..f1fe64b377 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/foundation.css @@ -0,0 +1,88 @@ +/* +Description: Foundation 4 docs style for highlight.js +Author: Dan Allen +Website: http://foundation.zurb.com/docs/ +Version: 1.0 +Date: 2013-04-02 +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #eee; color: black; +} + +.hljs-link, +.hljs-emphasis, +.hljs-attribute, +.hljs-addition { + color: #070; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong, +.hljs-string, +.hljs-deletion { + color: #d14; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-quote, +.hljs-comment { + color: #998; + font-style: italic; +} + +.hljs-section, +.hljs-title { + color: #900; +} + +.hljs-class .hljs-title, +.hljs-type { + color: #458; +} + +.hljs-variable, +.hljs-template-variable { + color: #336699; +} + +.hljs-bullet { + color: #997700; +} + +.hljs-meta { + color: #3344bb; +} + +.hljs-code, +.hljs-number, +.hljs-literal, +.hljs-keyword, +.hljs-selector-tag { + color: #099; +} + +.hljs-regexp { + background-color: #fff0ff; + color: #880088; +} + +.hljs-symbol { + color: #990073; +} + +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #007700; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github-gist.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github-gist.css new file mode 100644 index 0000000000..155f0b9160 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github-gist.css @@ -0,0 +1,71 @@ +/** + * GitHub Gist Theme + * Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro + */ + +.hljs { + display: block; + background: white; + padding: 0.5em; + color: #333333; + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #a71d5d; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-title, +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github.css new file mode 100644 index 0000000000..791932b87e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/github.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/googlecode.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/googlecode.css new file mode 100644 index 0000000000..884ad63538 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/googlecode.css @@ -0,0 +1,89 @@ +/* + +Google Code style (c) Aahan Krish + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, +.hljs-quote { + color: #800; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-section, +.hljs-title, +.hljs-name { + color: #008; +} + +.hljs-variable, +.hljs-template-variable { + color: #660; +} + +.hljs-string, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-regexp { + color: #080; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-meta, +.hljs-number, +.hljs-link { + color: #066; +} + +.hljs-title, +.hljs-doctag, +.hljs-type, +.hljs-attr, +.hljs-built_in, +.hljs-builtin-name, +.hljs-params { + color: #606; +} + +.hljs-attribute, +.hljs-subst { + color: #000; +} + +.hljs-formula { + background-color: #eee; + font-style: italic; +} + +.hljs-selector-id, +.hljs-selector-class { + color: #9B703F +} + +.hljs-addition { + background-color: #baeeba; +} + +.hljs-deletion { + background-color: #ffc8bd; +} + +.hljs-doctag, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/grayscale.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/grayscale.css new file mode 100644 index 0000000000..5376f34064 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/grayscale.css @@ -0,0 +1,101 @@ +/* + +grayscale style (c) MY Sun + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #fff; +} + +.hljs-comment, +.hljs-quote { + color: #777; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal { + color: #777; +} + +.hljs-string, +.hljs-doctag, +.hljs-formula { + color: #333; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC) repeat; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #000; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.hljs-name { + color: #333; + font-weight: bold; +} + +.hljs-tag { + color: #333; +} + +.hljs-regexp { + color: #333; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #000; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==) repeat; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #000; + text-decoration: underline; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + color: #fff; + background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat; +} + +.hljs-addition { + color: #000; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC) repeat; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-dark.css new file mode 100644 index 0000000000..f563811a86 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-dark.css @@ -0,0 +1,108 @@ +/* + +Gruvbox style (dark) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox) + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282828; +} + +.hljs, +.hljs-subst { + color: #ebdbb2; +} + +/* Gruvbox Red */ +.hljs-deletion, +.hljs-formula, +.hljs-keyword, +.hljs-link, +.hljs-selector-tag { + color: #fb4934; +} + +/* Gruvbox Blue */ +.hljs-built_in, +.hljs-emphasis, +.hljs-name, +.hljs-quote, +.hljs-strong, +.hljs-title, +.hljs-variable { + color: #83a598; +} + +/* Gruvbox Yellow */ +.hljs-attr, +.hljs-params, +.hljs-template-tag, +.hljs-type { + color: #fabd2f; +} + +/* Gruvbox Purple */ +.hljs-builtin-name, +.hljs-doctag, +.hljs-literal, +.hljs-number { + color: #8f3f71; +} + +/* Gruvbox Orange */ +.hljs-code, +.hljs-meta, +.hljs-regexp, +.hljs-selector-id, +.hljs-template-variable { + color: #fe8019; +} + +/* Gruvbox Green */ +.hljs-addition, +.hljs-meta-string, +.hljs-section, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-string, +.hljs-symbol { + color: #b8bb26; +} + +/* Gruvbox Aqua */ +.hljs-attribute, +.hljs-bullet, +.hljs-class, +.hljs-function, +.hljs-function .hljs-keyword, +.hljs-meta-keyword, +.hljs-selector-pseudo, +.hljs-tag { + color: #8ec07c; +} + +/* Gruvbox Gray */ +.hljs-comment { + color: #928374; +} + +/* Gruvbox Purple */ +.hljs-link_label, +.hljs-literal, +.hljs-number { + color: #d3869b; +} + +.hljs-comment, +.hljs-emphasis { + font-style: italic; +} + +.hljs-section, +.hljs-strong, +.hljs-tag { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-light.css new file mode 100644 index 0000000000..ff45468eb2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/gruvbox-light.css @@ -0,0 +1,108 @@ +/* + +Gruvbox style (light) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox) + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fbf1c7; +} + +.hljs, +.hljs-subst { + color: #3c3836; +} + +/* Gruvbox Red */ +.hljs-deletion, +.hljs-formula, +.hljs-keyword, +.hljs-link, +.hljs-selector-tag { + color: #9d0006; +} + +/* Gruvbox Blue */ +.hljs-built_in, +.hljs-emphasis, +.hljs-name, +.hljs-quote, +.hljs-strong, +.hljs-title, +.hljs-variable { + color: #076678; +} + +/* Gruvbox Yellow */ +.hljs-attr, +.hljs-params, +.hljs-template-tag, +.hljs-type { + color: #b57614; +} + +/* Gruvbox Purple */ +.hljs-builtin-name, +.hljs-doctag, +.hljs-literal, +.hljs-number { + color: #8f3f71; +} + +/* Gruvbox Orange */ +.hljs-code, +.hljs-meta, +.hljs-regexp, +.hljs-selector-id, +.hljs-template-variable { + color: #af3a03; +} + +/* Gruvbox Green */ +.hljs-addition, +.hljs-meta-string, +.hljs-section, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-string, +.hljs-symbol { + color: #79740e; +} + +/* Gruvbox Aqua */ +.hljs-attribute, +.hljs-bullet, +.hljs-class, +.hljs-function, +.hljs-function .hljs-keyword, +.hljs-meta-keyword, +.hljs-selector-pseudo, +.hljs-tag { + color: #427b58; +} + +/* Gruvbox Gray */ +.hljs-comment { + color: #928374; +} + +/* Gruvbox Purple */ +.hljs-link_label, +.hljs-literal, +.hljs-number { + color: #8f3f71; +} + +.hljs-comment, +.hljs-emphasis { + font-style: italic; +} + +.hljs-section, +.hljs-strong, +.hljs-tag { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hopscotch.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hopscotch.css new file mode 100644 index 0000000000..32e60d230a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hopscotch.css @@ -0,0 +1,83 @@ +/* + * Hopscotch + * by Jan T. Sott + * https://github.com/idleberg/Hopscotch + * + * This work is licensed under the Creative Commons CC0 1.0 Universal License + */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #989498; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-link, +.hljs-deletion { + color: #dd464c; +} + +/* Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #fd8b19; +} + +/* Yellow */ +.hljs-class .hljs-title { + color: #fdcc59; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #8fc13e; +} + +/* Aqua */ +.hljs-meta { + color: #149b93; +} + +/* Blue */ +.hljs-function, +.hljs-section, +.hljs-title { + color: #1290bf; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #c85e7c; +} + +.hljs { + display: block; + background: #322931; + color: #b9b5b8; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hybrid.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hybrid.css new file mode 100644 index 0000000000..29735a1890 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/hybrid.css @@ -0,0 +1,102 @@ +/* + +vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) + +*/ + +/*background color*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #1d1f21; +} + +/*selection color*/ +.hljs::selection, +.hljs span::selection { + background: #373b41; +} + +.hljs::-moz-selection, +.hljs span::-moz-selection { + background: #373b41; +} + +/*foreground color*/ +.hljs { + color: #c5c8c6; +} + +/*color: fg_yellow*/ +.hljs-title, +.hljs-name { + color: #f0c674; +} + +/*color: fg_comment*/ +.hljs-comment, +.hljs-meta, +.hljs-meta .hljs-keyword { + color: #707880; +} + +/*color: fg_red*/ +.hljs-number, +.hljs-symbol, +.hljs-literal, +.hljs-deletion, +.hljs-link { + color: #cc6666 +} + +/*color: fg_green*/ +.hljs-string, +.hljs-doctag, +.hljs-addition, +.hljs-regexp, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #b5bd68; +} + +/*color: fg_purple*/ +.hljs-attribute, +.hljs-code, +.hljs-selector-id { + color: #b294bb; +} + +/*color: fg_blue*/ +.hljs-keyword, +.hljs-selector-tag, +.hljs-bullet, +.hljs-tag { + color: #81a2be; +} + +/*color: fg_aqua*/ +.hljs-subst, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #8abeb7; +} + +/*color: fg_orange*/ +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-quote, +.hljs-section, +.hljs-selector-class { + color: #de935f; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/idea.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/idea.css new file mode 100644 index 0000000000..3bf1892bd4 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/idea.css @@ -0,0 +1,97 @@ +/* + +Intellij Idea-like styling (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #000; + background: #fff; +} + +.hljs-subst, +.hljs-title { + font-weight: normal; + color: #000; +} + +.hljs-comment, +.hljs-quote { + color: #808080; + font-style: italic; +} + +.hljs-meta { + color: #808000; +} + +.hljs-tag { + background: #efefef; +} + +.hljs-section, +.hljs-name, +.hljs-literal, +.hljs-keyword, +.hljs-selector-tag, +.hljs-type, +.hljs-selector-id, +.hljs-selector-class { + font-weight: bold; + color: #000080; +} + +.hljs-attribute, +.hljs-number, +.hljs-regexp, +.hljs-link { + font-weight: bold; + color: #0000ff; +} + +.hljs-number, +.hljs-regexp, +.hljs-link { + font-weight: normal; +} + +.hljs-string { + color: #008000; + font-weight: bold; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-formula { + color: #000; + background: #d0eded; + font-style: italic; +} + +.hljs-doctag { + text-decoration: underline; +} + +.hljs-variable, +.hljs-template-variable { + color: #660e7a; +} + +.hljs-addition { + background: #baeeba; +} + +.hljs-deletion { + background: #ffc8bd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ir-black.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ir-black.css new file mode 100644 index 0000000000..bd4c755ed8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ir-black.css @@ -0,0 +1,73 @@ +/* + IR_Black style (c) Vasily Mikhailitchenko +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #000; + color: #f8f8f8; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7c7c7c; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag, +.hljs-name { + color: #96cbfe; +} + +.hljs-attribute, +.hljs-selector-id { + color: #ffffb6; +} + +.hljs-string, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition { + color: #a8ff60; +} + +.hljs-subst { + color: #daefa3; +} + +.hljs-regexp, +.hljs-link { + color: #e9c062; +} + +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-doctag { + color: #ffffb6; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-variable, +.hljs-template-variable, +.hljs-literal { + color: #c6c5fe; +} + +.hljs-number, +.hljs-deletion { + color:#ff73fd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.dark.css new file mode 100644 index 0000000000..d139cb5d0c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.dark.css @@ -0,0 +1,74 @@ +/* + Name: Kimbie (dark) + Author: Jan T. Sott + License: Creative Commons Attribution-ShareAlike 4.0 Unported License + URL: https://github.com/idleberg/Kimbie-highlight.js +*/ + +/* Kimbie Comment */ +.hljs-comment, +.hljs-quote { + color: #d6baad; +} + +/* Kimbie Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-meta { + color: #dc3958; +} + +/* Kimbie Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-deletion, +.hljs-link { + color: #f79a32; +} + +/* Kimbie Yellow */ +.hljs-title, +.hljs-section, +.hljs-attribute { + color: #f06431; +} + +/* Kimbie Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #889b4a; +} + +/* Kimbie Purple */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-function { + color: #98676a; +} + +.hljs { + display: block; + overflow-x: auto; + background: #221a0f; + color: #d3af86; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.light.css new file mode 100644 index 0000000000..04ff6ed3a2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/kimbie.light.css @@ -0,0 +1,74 @@ +/* + Name: Kimbie (light) + Author: Jan T. Sott + License: Creative Commons Attribution-ShareAlike 4.0 Unported License + URL: https://github.com/idleberg/Kimbie-highlight.js +*/ + +/* Kimbie Comment */ +.hljs-comment, +.hljs-quote { + color: #a57a4c; +} + +/* Kimbie Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-meta { + color: #dc3958; +} + +/* Kimbie Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-deletion, +.hljs-link { + color: #f79a32; +} + +/* Kimbie Yellow */ +.hljs-title, +.hljs-section, +.hljs-attribute { + color: #f06431; +} + +/* Kimbie Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #889b4a; +} + +/* Kimbie Purple */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-function { + color: #98676a; +} + +.hljs { + display: block; + overflow-x: auto; + background: #fbebd4; + color: #84613d; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/magula.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/magula.css new file mode 100644 index 0000000000..44dee5e8e1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/magula.css @@ -0,0 +1,70 @@ +/* +Description: Magula style for highligh.js +Author: Ruslan Keba +Website: http://rukeba.com/ +Version: 1.0 +Date: 2009-01-03 +Music: Aphex Twin / Xtal +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background-color: #f4f4f4; +} + +.hljs, +.hljs-subst { + color: black; +} + +.hljs-string, +.hljs-title, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #050; +} + +.hljs-comment, +.hljs-quote { + color: #777; +} + +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-type, +.hljs-link { + color: #800; +} + +.hljs-deletion, +.hljs-meta { + color: #00e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-built_in, +.hljs-tag, +.hljs-name { + font-weight: bold; + color: navy; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/mono-blue.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/mono-blue.css new file mode 100644 index 0000000000..884c97c767 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/mono-blue.css @@ -0,0 +1,59 @@ +/* + Five-color theme from a single blue hue. +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #eaeef3; +} + +.hljs { + color: #00193a; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-comment { + color: #738191; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-built_in, +.hljs-literal, +.hljs-type, +.hljs-addition, +.hljs-tag, +.hljs-quote, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #0048ab; +} + +.hljs-meta, +.hljs-subst, +.hljs-symbol, +.hljs-regexp, +.hljs-attribute, +.hljs-deletion, +.hljs-variable, +.hljs-template-variable, +.hljs-link, +.hljs-bullet { + color: #4c81c9; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai-sublime.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai-sublime.css new file mode 100644 index 0000000000..2864170daf --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai-sublime.css @@ -0,0 +1,83 @@ +/* + +Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #23241f; +} + +.hljs, +.hljs-tag, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-link { + color: #ae81ff; +} + +.hljs-code, +.hljs-title, +.hljs-section, +.hljs-selector-class { + color: #a6e22e; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-attr { + color: #f92672; +} + +.hljs-symbol, +.hljs-attribute { + color: #66d9ef; +} + +.hljs-params, +.hljs-class .hljs-title { + color: #f8f8f2; +} + +.hljs-string, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-variable { + color: #e6db74; +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai.css new file mode 100644 index 0000000000..775d53f91a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/monokai.css @@ -0,0 +1,70 @@ +/* +Monokai style - ported by Luigi Maselli - http://grigio.org +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #272822; color: #ddd; +} + +.hljs-tag, +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-strong, +.hljs-name { + color: #f92672; +} + +.hljs-code { + color: #66d9ef; +} + +.hljs-class .hljs-title { + color: white; +} + +.hljs-attribute, +.hljs-symbol, +.hljs-regexp, +.hljs-link { + color: #bf79db; +} + +.hljs-string, +.hljs-bullet, +.hljs-subst, +.hljs-title, +.hljs-section, +.hljs-emphasis, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #a6e22e; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-selector-id { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/obsidian.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/obsidian.css new file mode 100644 index 0000000000..356630fa23 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/obsidian.css @@ -0,0 +1,88 @@ +/** + * Obsidian style + * ported by Alexander Marenin (http://github.com/ioncreature) + */ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282b2e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-selector-id { + color: #93c763; +} + +.hljs-number { + color: #ffcd22; +} + +.hljs { + color: #e0e2e4; +} + +.hljs-attribute { + color: #668bb0; +} + +.hljs-code, +.hljs-class .hljs-title, +.hljs-section { + color: white; +} + +.hljs-regexp, +.hljs-link { + color: #d39745; +} + +.hljs-meta { + color: #557182; +} + +.hljs-tag, +.hljs-name, +.hljs-bullet, +.hljs-subst, +.hljs-emphasis, +.hljs-type, +.hljs-built_in, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #8cbbad; +} + +.hljs-string, +.hljs-symbol { + color: #ec7600; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion { + color: #818e96; +} + +.hljs-selector-class { + color: #A082BD +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ocean.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ocean.css new file mode 100644 index 0000000000..5901581b40 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/ocean.css @@ -0,0 +1,74 @@ +/* Ocean Dark Theme */ +/* https://github.com/gavsiu */ +/* Original theme - https://github.com/chriskempson/base16 */ + +/* Ocean Comment */ +.hljs-comment, +.hljs-quote { + color: #65737e; +} + +/* Ocean Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #bf616a; +} + +/* Ocean Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #d08770; +} + +/* Ocean Yellow */ +.hljs-attribute { + color: #ebcb8b; +} + +/* Ocean Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #a3be8c; +} + +/* Ocean Blue */ +.hljs-title, +.hljs-section { + color: #8fa1b3; +} + +/* Ocean Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b48ead; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2b303b; + color: #c0c5ce; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-dark.css new file mode 100644 index 0000000000..e7292401c6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-dark.css @@ -0,0 +1,72 @@ +/* + Paraíso (dark) + Created by Jan T. Sott (http://github.com/idleberg) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) +*/ + +/* Paraíso Comment */ +.hljs-comment, +.hljs-quote { + color: #8d8687; +} + +/* Paraíso Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-link, +.hljs-meta { + color: #ef6155; +} + +/* Paraíso Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-deletion { + color: #f99b15; +} + +/* Paraíso Yellow */ +.hljs-title, +.hljs-section, +.hljs-attribute { + color: #fec418; +} + +/* Paraíso Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #48b685; +} + +/* Paraíso Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #815ba4; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2f1e2e; + color: #a39e9b; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-light.css new file mode 100644 index 0000000000..944857cd8d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/paraiso-light.css @@ -0,0 +1,72 @@ +/* + Paraíso (light) + Created by Jan T. Sott (http://github.com/idleberg) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) +*/ + +/* Paraíso Comment */ +.hljs-comment, +.hljs-quote { + color: #776e71; +} + +/* Paraíso Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-link, +.hljs-meta { + color: #ef6155; +} + +/* Paraíso Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-deletion { + color: #f99b15; +} + +/* Paraíso Yellow */ +.hljs-title, +.hljs-section, +.hljs-attribute { + color: #fec418; +} + +/* Paraíso Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #48b685; +} + +/* Paraíso Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #815ba4; +} + +.hljs { + display: block; + overflow-x: auto; + background: #e7e9db; + color: #4f424c; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.css new file mode 100644 index 0000000000..2e07847b2b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.css @@ -0,0 +1,83 @@ +/* + +Pojoaque Style by Jason Tate +http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html +Based on Solarized Style from http://ethanschoonover.com/solarized + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #dccf8f; + background: url(./pojoaque.jpg) repeat scroll left top #181914; +} + +.hljs-comment, +.hljs-quote { + color: #586e75; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-addition { + color: #b64926; +} + +.hljs-number, +.hljs-string, +.hljs-doctag, +.hljs-regexp { + color: #468966; +} + +.hljs-title, +.hljs-section, +.hljs-built_in, +.hljs-name { + color: #ffb03b; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type, +.hljs-tag { + color: #b58900; +} + +.hljs-attribute { + color: #b89859; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-subst, +.hljs-meta { + color: #cb4b16; +} + +.hljs-deletion { + color: #dc322f; +} + +.hljs-selector-id, +.hljs-selector-class { + color: #d3a60c; +} + +.hljs-formula { + background: #073642; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.jpg b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.jpg new file mode 100644 index 0000000000..9c07d4ab40 Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/pojoaque.jpg differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/purebasic.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/purebasic.css new file mode 100644 index 0000000000..5ce9b9e071 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/purebasic.css @@ -0,0 +1,96 @@ +/* + +PureBASIC native IDE style ( version 1.0 - April 2016 ) + +by Tristano Ajmone + +Public Domain + +NOTE_1: PureBASIC code syntax highlighting only applies the following classes: + .hljs-comment + .hljs-function + .hljs-keywords + .hljs-string + .hljs-symbol + + Other classes are added here for the benefit of styling other languages with the look and feel of PureBASIC native IDE style. + If you need to customize a stylesheet for PureBASIC only, remove all non-relevant classes -- PureBASIC-related classes are followed by + a "--- used for PureBASIC ... ---" comment on same line. + +NOTE_2: Color names provided in comments were derived using "Name that Color" online tool: + http://chir.ag/projects/name-that-color +*/ + +.hljs { /* Common set of rules required by highlight.js (don'r remove!) */ + display: block; + overflow-x: auto; + padding: 0.5em; + background: #FFFFDF; /* Half and Half (approx.) */ +/* --- Uncomment to add PureBASIC native IDE styled font! + font-family: Consolas; +*/ +} + +.hljs, /* --- used for PureBASIC base color --- */ +.hljs-type, /* --- used for PureBASIC Procedures return type --- */ +.hljs-function, /* --- used for wrapping PureBASIC Procedures definitions --- */ +.hljs-name, +.hljs-number, +.hljs-attr, +.hljs-params, +.hljs-subst { + color: #000000; /* Black */ +} + +.hljs-comment, /* --- used for PureBASIC Comments --- */ +.hljs-regexp, +.hljs-section, +.hljs-selector-pseudo, +.hljs-addition { + color: #00AAAA; /* Persian Green (approx.) */ +} + +.hljs-title, /* --- used for PureBASIC Procedures Names --- */ +.hljs-tag, +.hljs-variable, +.hljs-code { + color: #006666; /* Blue Stone (approx.) */ +} + +.hljs-keyword, /* --- used for PureBASIC Keywords --- */ +.hljs-class, +.hljs-meta-keyword, +.hljs-selector-class, +.hljs-built_in, +.hljs-builtin-name { + color: #006666; /* Blue Stone (approx.) */ + font-weight: bold; +} + +.hljs-string, /* --- used for PureBASIC Strings --- */ +.hljs-selector-attr { + color: #0080FF; /* Azure Radiance (approx.) */ +} + +.hljs-symbol, /* --- used for PureBASIC Constants --- */ +.hljs-link, +.hljs-deletion, +.hljs-attribute { + color: #924B72; /* Cannon Pink (approx.) */ +} + +.hljs-meta, +.hljs-literal, +.hljs-selector-id { + color: #924B72; /* Cannon Pink (approx.) */ + font-weight: bold; +} + +.hljs-strong, +.hljs-name { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_dark.css new file mode 100644 index 0000000000..7aa56a3655 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_dark.css @@ -0,0 +1,83 @@ +/* + +Qt Creator dark color scheme + +*/ + + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #000000; +} + +.hljs, +.hljs-subst, +.hljs-tag, +.hljs-title { + color: #aaaaaa; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal { + color: #ff55ff; +} + +.hljs-code +.hljs-selector-class { + color: #aaaaff; +} + +.hljs-emphasis, +.hljs-stronge, +.hljs-type { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-function, +.hljs-section, +.hljs-symbol, +.hljs-name { + color: #ffff55; +} + +.hljs-attribute { + color: #ff5555; +} + +.hljs-variable, +.hljs-params, +.hljs-class .hljs-title { + color: #8888ff; +} + +.hljs-string, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition, +.hljs-link { + color: #ff55ff; +} + +.hljs-comment, +.hljs-meta, +.hljs-deletion { + color: #55ffff; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_light.css new file mode 100644 index 0000000000..1efa2c660f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/qtcreator_light.css @@ -0,0 +1,83 @@ +/* + +Qt Creator light color scheme + +*/ + + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #ffffff; +} + +.hljs, +.hljs-subst, +.hljs-tag, +.hljs-title { + color: #000000; +} + +.hljs-strong, +.hljs-emphasis { + color: #000000; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal { + color: #000080; +} + +.hljs-code +.hljs-selector-class { + color: #800080; +} + +.hljs-emphasis, +.hljs-stronge, +.hljs-type { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-function, +.hljs-section, +.hljs-symbol, +.hljs-name { + color: #808000; +} + +.hljs-attribute { + color: #800000; +} + +.hljs-variable, +.hljs-params, +.hljs-class .hljs-title { + color: #0055AF; +} + +.hljs-string, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition, +.hljs-link { + color: #008000; +} + +.hljs-comment, +.hljs-meta, +.hljs-deletion { + color: #008000; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/railscasts.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/railscasts.css new file mode 100644 index 0000000000..008cdc5bf1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/railscasts.css @@ -0,0 +1,106 @@ +/* + +Railscasts-like style (c) Visoft, Inc. (Damien White) + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #232323; + color: #e6e1dc; +} + +.hljs-comment, +.hljs-quote { + color: #bc9458; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag { + color: #c26230; +} + +.hljs-string, +.hljs-number, +.hljs-regexp, +.hljs-variable, +.hljs-template-variable { + color: #a5c261; +} + +.hljs-subst { + color: #519f50; +} + +.hljs-tag, +.hljs-name { + color: #e8bf6a; +} + +.hljs-type { + color: #da4939; +} + + +.hljs-symbol, +.hljs-bullet, +.hljs-built_in, +.hljs-builtin-name, +.hljs-attr, +.hljs-link { + color: #6d9cbe; +} + +.hljs-params { + color: #d0d0ff; +} + +.hljs-attribute { + color: #cda869; +} + +.hljs-meta { + color: #9b859d; +} + +.hljs-title, +.hljs-section { + color: #ffc66d; +} + +.hljs-addition { + background-color: #144212; + color: #e6e1dc; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #600; + color: #e6e1dc; + display: inline-block; + width: 100%; +} + +.hljs-selector-class { + color: #9b703f; +} + +.hljs-selector-id { + color: #8b98ab; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/rainbow.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/rainbow.css new file mode 100644 index 0000000000..905eb8ef18 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/rainbow.css @@ -0,0 +1,85 @@ +/* + +Style with support for rainbow parens + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #474949; + color: #d1d9e1; +} + + +.hljs-comment, +.hljs-quote { + color: #969896; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-type, +.hljs-addition { + color: #cc99cc; +} + +.hljs-number, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #f99157; +} + +.hljs-string, +.hljs-doctag, +.hljs-regexp { + color: #8abeb7; +} + +.hljs-title, +.hljs-name, +.hljs-section, +.hljs-built_in { + color: #b5bd68; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-selector-id, +.hljs-class .hljs-title { + color: #ffcc66; +} + +.hljs-section, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-link { + color: #f99157; +} + +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-attr, +.hljs-attribute { + color: #81a2be; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/routeros.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/routeros.css new file mode 100644 index 0000000000..ebe23990da --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/routeros.css @@ -0,0 +1,108 @@ +/* + + highlight.js style for Microtik RouterOS script + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #F0F0F0; +} + +/* Base color: saturation 0; */ + +.hljs, +.hljs-subst { + color: #444; +} + +.hljs-comment { + color: #888888; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-meta-keyword, +.hljs-doctag, +.hljs-name { + font-weight: bold; +} + +.hljs-attribute { + color: #0E9A00; +} + +.hljs-function { + color: #99069A; +} + +.hljs-builtin-name { + color: #99069A; +} + +/* User color: hue: 0 */ + +.hljs-type, +.hljs-string, +.hljs-number, +.hljs-selector-id, +.hljs-selector-class, +.hljs-quote, +.hljs-template-tag, +.hljs-deletion { + color: #880000; +} + +.hljs-title, +.hljs-section { + color: #880000; + font-weight: bold; +} + +.hljs-regexp, +.hljs-symbol, +.hljs-variable, +.hljs-template-variable, +.hljs-link, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #BC6060; +} + + +/* Language color: hue: 90; */ + +.hljs-literal { + color: #78A960; +} + +.hljs-built_in, +.hljs-bullet, +.hljs-code, +.hljs-addition { + color: #0C9A9A; +} + + +/* Meta color: hue: 200 */ + +.hljs-meta { + color: #1f7199; +} + +.hljs-meta-string { + color: #4d99bf; +} + + +/* Misc effects */ + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.css new file mode 100644 index 0000000000..964b51d841 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.css @@ -0,0 +1,72 @@ +/* + +School Book style from goldblog.com.ua (c) Zaripov Yura + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 15px 0.5em 0.5em 30px; + font-size: 11px; + line-height:16px; +} + +pre{ + background:#f6f6ae url(./school-book.png); + border-top: solid 2px #d2e8b9; + border-bottom: solid 1px #d2e8b9; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal { + color:#005599; + font-weight:bold; +} + +.hljs, +.hljs-subst { + color: #3e5915; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute, +.hljs-built_in, +.hljs-builtin-name, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable, +.hljs-link { + color: #2c009f; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #e60415; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-name, +.hljs-selector-id, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.png b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.png new file mode 100644 index 0000000000..956e9790a0 Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/school-book.png differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-dark.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-dark.css new file mode 100644 index 0000000000..b4c0da1f78 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-dark.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #002b36; + color: #839496; +} + +.hljs-comment, +.hljs-quote { + color: #586e75; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #073642; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-light.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-light.css new file mode 100644 index 0000000000..fdcfcc72c4 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/solarized-light.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} + +.hljs-comment, +.hljs-quote { + color: #93a1a1; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/sunburst.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/sunburst.css new file mode 100644 index 0000000000..f56dd5e9b6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/sunburst.css @@ -0,0 +1,102 @@ +/* + +Sunburst-like style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #000; + color: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #aeaeae; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #e28964; +} + +.hljs-string { + color: #65b042; +} + +.hljs-subst { + color: #daefa3; +} + +.hljs-regexp, +.hljs-link { + color: #e9c062; +} + +.hljs-title, +.hljs-section, +.hljs-tag, +.hljs-name { + color: #89bdff; +} + +.hljs-class .hljs-title, +.hljs-doctag { + text-decoration: underline; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-number { + color: #3387cc; +} + +.hljs-params, +.hljs-variable, +.hljs-template-variable { + color: #3e87e3; +} + +.hljs-attribute { + color: #cda869; +} + +.hljs-meta { + color: #8996a8; +} + +.hljs-formula { + background-color: #0e2231; + color: #f8f8f8; + font-style: italic; +} + +.hljs-addition { + background-color: #253b22; + color: #f8f8f8; +} + +.hljs-deletion { + background-color: #420e09; + color: #f8f8f8; +} + +.hljs-selector-class { + color: #9b703f; +} + +.hljs-selector-id { + color: #8b98ab; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-blue.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-blue.css new file mode 100644 index 0000000000..78e59cc8cb --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-blue.css @@ -0,0 +1,75 @@ +/* Tomorrow Night Blue Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #7285b7; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #ff9da4; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #ffc58f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #ffeead; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #d1f1a9; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #bbdaff; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #ebbbff; +} + +.hljs { + display: block; + overflow-x: auto; + background: #002451; + color: white; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-bright.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-bright.css new file mode 100644 index 0000000000..e05af8ae24 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-bright.css @@ -0,0 +1,74 @@ +/* Tomorrow Night Bright Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #d54e53; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #e78c45; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #e7c547; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #b9ca4a; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #7aa6da; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #c397d8; +} + +.hljs { + display: block; + overflow-x: auto; + background: black; + color: #eaeaea; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-eighties.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-eighties.css new file mode 100644 index 0000000000..08fd51c742 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night-eighties.css @@ -0,0 +1,74 @@ +/* Tomorrow Night Eighties Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #999999; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #f2777a; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f99157; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #ffcc66; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #99cc99; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #6699cc; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #cc99cc; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2d2d2d; + color: #cccccc; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night.css new file mode 100644 index 0000000000..ddd270a4e7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow-night.css @@ -0,0 +1,75 @@ +/* Tomorrow Night Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #cc6666; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #de935f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #f0c674; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #b5bd68; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #81a2be; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b294bb; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1d1f21; + color: #c5c8c6; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow.css new file mode 100644 index 0000000000..026a62fe3b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/tomorrow.css @@ -0,0 +1,72 @@ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #8e908c; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #c82829; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f5871f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #eab700; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #718c00; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #4271ae; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #8959a8; +} + +.hljs { + display: block; + overflow-x: auto; + background: white; + color: #4d4d4c; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs.css new file mode 100644 index 0000000000..c5d07d3115 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs.css @@ -0,0 +1,68 @@ +/* + +Visual Studio-like style based on original C# coloring by Jason Diamond + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, +.hljs-quote, +.hljs-variable { + color: #008000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-built_in, +.hljs-name, +.hljs-tag { + color: #00f; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-attribute, +.hljs-literal, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-addition { + color: #a31515; +} + +.hljs-deletion, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-meta { + color: #2b91af; +} + +.hljs-doctag { + color: #808080; +} + +.hljs-attr { + color: #f00; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #00b0e8; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs2015.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs2015.css new file mode 100644 index 0000000000..d1d9be3caa --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/vs2015.css @@ -0,0 +1,115 @@ +/* + * Visual Studio 2015 dark style + * Author: Nicolas LLOBERA + */ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #1E1E1E; + color: #DCDCDC; +} + +.hljs-keyword, +.hljs-literal, +.hljs-symbol, +.hljs-name { + color: #569CD6; +} +.hljs-link { + color: #569CD6; + text-decoration: underline; +} + +.hljs-built_in, +.hljs-type { + color: #4EC9B0; +} + +.hljs-number, +.hljs-class { + color: #B8D7A3; +} + +.hljs-string, +.hljs-meta-string { + color: #D69D85; +} + +.hljs-regexp, +.hljs-template-tag { + color: #9A5334; +} + +.hljs-subst, +.hljs-function, +.hljs-title, +.hljs-params, +.hljs-formula { + color: #DCDCDC; +} + +.hljs-comment, +.hljs-quote { + color: #57A64A; + font-style: italic; +} + +.hljs-doctag { + color: #608B4E; +} + +.hljs-meta, +.hljs-meta-keyword, +.hljs-tag { + color: #9B9B9B; +} + +.hljs-variable, +.hljs-template-variable { + color: #BD63C5; +} + +.hljs-attr, +.hljs-attribute, +.hljs-builtin-name { + color: #9CDCFE; +} + +.hljs-section { + color: gold; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +/*.hljs-code { + font-family:'Monospace'; +}*/ + +.hljs-bullet, +.hljs-selector-tag, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #D7BA7D; +} + +.hljs-addition { + background-color: #144212; + display: inline-block; + width: 100%; +} + +.hljs-deletion { + background-color: #600; + display: inline-block; + width: 100%; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xcode.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xcode.css new file mode 100644 index 0000000000..43dddad84d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xcode.css @@ -0,0 +1,93 @@ +/* + +XCode style (c) Angel Garcia + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fff; + color: black; +} + +.hljs-comment, +.hljs-quote { + color: #006a00; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal { + color: #aa0d91; +} + +.hljs-name { + color: #008; +} + +.hljs-variable, +.hljs-template-variable { + color: #660; +} + +.hljs-string { + color: #c41a16; +} + +.hljs-regexp, +.hljs-link { + color: #080; +} + +.hljs-title, +.hljs-tag, +.hljs-symbol, +.hljs-bullet, +.hljs-number, +.hljs-meta { + color: #1c00cf; +} + +.hljs-section, +.hljs-class .hljs-title, +.hljs-type, +.hljs-attr, +.hljs-built_in, +.hljs-builtin-name, +.hljs-params { + color: #5c2699; +} + +.hljs-attribute, +.hljs-subst { + color: #000; +} + +.hljs-formula { + background-color: #eee; + font-style: italic; +} + +.hljs-addition { + background-color: #baeeba; +} + +.hljs-deletion { + background-color: #ffc8bd; +} + +.hljs-selector-id, +.hljs-selector-class { + color: #9b703f; +} + +.hljs-doctag, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xt256.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xt256.css new file mode 100644 index 0000000000..58df82cb75 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/xt256.css @@ -0,0 +1,92 @@ + +/* + xt256.css + + Contact: initbar [at] protonmail [dot] ch + : github.com/initbar +*/ + +.hljs { + display: block; + overflow-x: auto; + color: #eaeaea; + background: #000; + padding: 0.5; +} + +.hljs-subst { + color: #eaeaea; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-builtin-name, +.hljs-type { + color: #eaeaea; +} + +.hljs-params { + color: #da0000; +} + +.hljs-literal, +.hljs-number, +.hljs-name { + color: #ff0000; + font-weight: bolder; +} + +.hljs-comment { + color: #969896; +} + +.hljs-selector-id, +.hljs-quote { + color: #00ffff; +} + +.hljs-template-variable, +.hljs-variable, +.hljs-title { + color: #00ffff; + font-weight: bold; +} + +.hljs-selector-class, +.hljs-keyword, +.hljs-symbol { + color: #fff000; +} + +.hljs-string, +.hljs-bullet { + color: #00ff00; +} + +.hljs-tag, +.hljs-section { + color: #000fff; +} + +.hljs-selector-tag { + color: #000fff; + font-weight: bold; +} + +.hljs-attribute, +.hljs-built_in, +.hljs-regexp, +.hljs-link { + color: #ff00ff; +} + +.hljs-meta { + color: #fff; + font-weight: bolder; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/zenburn.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/zenburn.css new file mode 100644 index 0000000000..07be502016 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/highlight.js/styles/zenburn.css @@ -0,0 +1,80 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov +based on dark.css by Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #3f3f3f; + color: #dcdcdc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #e3ceab; +} + +.hljs-template-tag { + color: #dcdcdc; +} + +.hljs-number { + color: #8cd0d3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute { + color: #efdcbc; +} + +.hljs-literal { + color: #efefaf; +} + +.hljs-subst { + color: #8f8f8f; +} + +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #efef8f; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #dca3a3; +} + +.hljs-deletion, +.hljs-string, +.hljs-built_in, +.hljs-builtin-name { + color: #cc9393; +} + +.hljs-addition, +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7f9f7f; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-form/jquery.form.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-form/jquery.form.min.js new file mode 100644 index 0000000000..9a447f7cc8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-form/jquery.form.min.js @@ -0,0 +1,23 @@ +/*! + * jQuery Form Plugin + * version: 4.2.2 + * Requires jQuery v1.7.2 or later + * Project repository: https://github.com/jquery-form/form + + * Copyright 2017 Kevin Morris + * Copyright 2006 M. Alsup + + * Dual licensed under the LGPL-2.1+ or MIT licenses + * https://github.com/jquery-form/form#license + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,r){return void 0===r&&(r="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(r),r}:e(jQuery)}(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).closest("form").ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=r.form;if(i.clk=r,"image"===r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n=/\r?\n/g,i={};i.fileapi=void 0!==e('').get(0).files,i.formdata=void 0!==window.FormData;var o=!!e.fn.prop;e.fn.attr2=function(){if(!o)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t,r,n,s){function u(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;a',k).val(f.extraData[c].value).appendTo(w)[0]):u.push(e('',k).val(f.extraData[c]).appendTo(w)[0]));f.iframeTarget||h.appendTo(D),v.attachEvent?v.attachEvent("onload",s):v.addEventListener("load",s,!1),setTimeout(t,15);try{w.submit()}catch(e){document.createElement("form").submit.apply(w)}}finally{w.setAttribute("action",i),w.setAttribute("enctype",o),r?w.setAttribute("target",r):p.removeAttr("target"),e(u).remove()}}function s(t){if(!x.aborted&&!X){if((O=n(v))||(a("cannot access response document"),t=L),t===A&&x)return x.abort("timeout"),void S.reject(x,"timeout");if(t===L&&x)return x.abort("server abort"),void S.reject(x,"error","server abort");if(O&&O.location.href!==f.iframeSrc||T){v.detachEvent?v.detachEvent("onload",s):v.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"===f.dataType||O.XMLDocument||e.isXMLDoc(O);if(a("isXml="+o),!o&&window.opera&&(null===O.body||!O.body.innerHTML)&&--C)return a("requeing onLoad callback, DOM not available"),void setTimeout(s,250);var u=O.body?O.body:O.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=O.XMLDocument?O.XMLDocument:O,o&&(f.dataType="xml"),x.getResponseHeader=function(e){return{"content-type":f.dataType}[e.toLowerCase()]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);var c=(f.dataType||"").toLowerCase(),l=/(json|script|text)/.test(c);if(l||f.textarea){var p=O.getElementsByTagName("textarea")[0];if(p)x.responseText=p.value,x.status=Number(p.getAttribute("status"))||x.status,x.statusText=p.getAttribute("statusText")||x.statusText;else if(l){var m=O.getElementsByTagName("pre")[0],g=O.getElementsByTagName("body")[0];m?x.responseText=m.textContent?m.textContent:m.innerText:g&&(x.responseText=g.textContent?g.textContent:g.innerText)}}else"xml"===c&&!x.responseXML&&x.responseText&&(x.responseXML=q(x.responseText));try{M=N(x,c,f)}catch(e){i="parsererror",x.error=r=e||i}}catch(e){a("error caught: ",e),i="error",x.error=r=e||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&x.status<300||304===x.status?"success":"error"),"success"===i?(f.success&&f.success.call(f.context,M,"success",x),S.resolve(x.responseText,"success",x),d&&e.event.trigger("ajaxSuccess",[x,f])):i&&(void 0===r&&(r=x.statusText),f.error&&f.error.call(f.context,x,i,r),S.reject(x,"error",r),d&&e.event.trigger("ajaxError",[x,f,r])),d&&e.event.trigger("ajaxComplete",[x,f]),d&&!--e.active&&e.event.trigger("ajaxStop"),f.complete&&f.complete.call(f.context,x,i),X=!0,f.timeout&&clearTimeout(j),setTimeout(function(){f.iframeTarget?h.attr("src",f.iframeSrc):h.remove(),x.responseXML=null},100)}}}var u,c,f,d,m,h,v,x,y,b,T,j,w=p[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(c=0;c',k)).css({position:"absolute",top:"-1000px",left:"-1000px"}),v=h[0],x={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";a("aborting upload... "+r),this.aborted=1;try{v.contentWindow.document.execCommand&&v.contentWindow.document.execCommand("Stop")}catch(e){}h.attr("src",f.iframeSrc),x.error=r,f.error&&f.error.call(f.context,x,r,t),d&&e.event.trigger("ajaxError",[x,f,r]),f.complete&&f.complete.call(f.context,x,r)}},(d=f.global)&&0==e.active++&&e.event.trigger("ajaxStart"),d&&e.event.trigger("ajaxSend",[x,f]),f.beforeSend&&!1===f.beforeSend.call(f.context,x,f))return f.global&&e.active--,S.reject(),S;if(x.aborted)return S.reject(),S;(y=w.clk)&&(b=y.name)&&!y.disabled&&(f.extraData=f.extraData||{},f.extraData[b]=y.value,"image"===y.type&&(f.extraData[b+".x"]=w.clk_x,f.extraData[b+".y"]=w.clk_y));var A=1,L=2,F=e("meta[name=csrf-token]").attr("content"),E=e("meta[name=csrf-param]").attr("content");E&&F&&(f.extraData=f.extraData||{},f.extraData[E]=F),f.forceSync?i():setTimeout(i,10);var M,O,X,C=50,q=e.parseXML||function(e,t){return window.ActiveXObject?((t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!==t.documentElement.nodeName?t:null},_=e.parseJSON||function(e){return window.eval("("+e+")")},N=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i=("xml"===r||!r)&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&(("json"===r||!r)&&n.indexOf("json")>=0?o=_(o):("script"===r||!r)&&n.indexOf("javascript")>=0&&e.globalEval(o)),o};return S}if(!this.length)return a("ajaxSubmit: skipping submit process - no element selected"),this;var l,f,d,p=this;"function"==typeof t?t={success:t}:"string"==typeof t||!1===t&&arguments.length>0?(t={url:t,data:r,dataType:n},"function"==typeof s&&(t.success=s)):void 0===t&&(t={}),l=t.method||t.type||this.attr2("method"),(d=(d="string"==typeof(f=t.url||this.attr2("action"))?e.trim(f):"")||window.location.href||"")&&(d=(d.match(/^([^#]+)/)||[])[1]),t=e.extend(!0,{url:d,success:e.ajaxSettings.success,type:l||e.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var m={};if(this.trigger("form-pre-serialize",[this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&!1===t.beforeSerialize(this,t))return a("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var h=t.traditional;void 0===h&&(h=e.ajaxSettings.traditional);var v,g=[],x=this.formToArray(t.semantic,g,t.filtering);if(t.data){var y=e.isFunction(t.data)?t.data(x):t.data;t.extraData=y,v=e.param(y,h)}if(t.beforeSubmit&&!1===t.beforeSubmit(x,this,t))return a("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[x,this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var b=e.param(x,h);v&&(b=b?b+"&"+v:v),"GET"===t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+b,t.data=null):t.data=b;var T=[];if(t.resetForm&&T.push(function(){p.resetForm()}),t.clearForm&&T.push(function(){p.clearForm(t.includeHidden)}),!t.dataType&&t.target){var j=t.success||function(){};T.push(function(r,a,n){var i=arguments,o=t.replaceTarget?"replaceWith":"html";e(t.target)[o](r).each(function(){j.apply(this,i)})})}else t.success&&(e.isArray(t.success)?e.merge(T,t.success):T.push(t.success));if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=T.length;i0,D="multipart/form-data",A=p.attr("enctype")===D||p.attr("encoding")===D,L=i.fileapi&&i.formdata;a("fileAPI :"+L);var F,E=(k||A)&&!L;!1!==t.iframe&&(t.iframe||E)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){F=c(x)}):F=c(x):F=(k||A)&&L?function(r){for(var a=new FormData,n=0;n0)&&(n={url:n,data:i,dataType:o},"function"==typeof s&&(n.success=s)),n=n||{},n.delegation=n.delegation&&e.isFunction(e.fn.on),!n.delegation&&0===this.length){var u={s:this.selector,c:this.context};return!e.isReady&&u.s?(a("DOM not ready, queuing ajaxForm"),e(function(){e(u.s,u.c).ajaxForm(n)}),this):(a("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return n.delegation?(e(document).off("submit.form-plugin",this.selector,t).off("click.form-plugin",this.selector,r).on("submit.form-plugin",this.selector,n,t).on("click.form-plugin",this.selector,n,r),this):this.ajaxFormUnbind().on("submit.form-plugin",n,t).on("click.form-plugin",n,r)},e.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,r,a){var n=[];if(0===this.length)return n;var o,s=this[0],u=this.attr("id"),c=t||void 0===s.elements?s.getElementsByTagName("*"):s.elements;if(c&&(c=e.makeArray(c)),u&&(t||/(Edge|Trident)\//.test(navigator.userAgent))&&(o=e(':input[form="'+u+'"]').get()).length&&(c=(c||[]).concat(o)),!c||!c.length)return n;e.isFunction(a)&&(c=e.map(c,a));var l,f,d,p,m,h,v;for(l=0,h=c.length;l?@\[\\\]^`{|}~])/g, "\\$1"); + } + + function getModelPrefix(fieldName) { + return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); + } + + function appendModelPrefix(value, prefix) { + if (value.indexOf("*.") === 0) { + value = value.replace("*.", prefix); + } + return value; + } + + function onError(error, inputElement) { // 'this' is the form element + var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), + replaceAttrValue = container.attr("data-valmsg-replace"), + replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; + + container.removeClass("field-validation-valid").addClass("field-validation-error"); + error.data("unobtrusiveContainer", container); + + if (replace) { + container.empty(); + error.removeClass("input-validation-error").appendTo(container); + } + else { + error.hide(); + } + } + + function onErrors(event, validator) { // 'this' is the form element + var container = $(this).find("[data-valmsg-summary=true]"), + list = container.find("ul"); + + if (list && list.length && validator.errorList.length) { + list.empty(); + container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); + + $.each(validator.errorList, function () { + $("
  • ").html(this.message).appendTo(list); + }); + } + } + + function onSuccess(error) { // 'this' is the form element + var container = error.data("unobtrusiveContainer"); + + if (container) { + var replaceAttrValue = container.attr("data-valmsg-replace"), + replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; + + container.addClass("field-validation-valid").removeClass("field-validation-error"); + error.removeData("unobtrusiveContainer"); + + if (replace) { + container.empty(); + } + } + } + + function onReset(event) { // 'this' is the form element + var $form = $(this), + key = '__jquery_unobtrusive_validation_form_reset'; + if ($form.data(key)) { + return; + } + // Set a flag that indicates we're currently resetting the form. + $form.data(key, true); + try { + $form.data("validator").resetForm(); + } finally { + $form.removeData(key); + } + + $form.find(".validation-summary-errors") + .addClass("validation-summary-valid") + .removeClass("validation-summary-errors"); + $form.find(".field-validation-error") + .addClass("field-validation-valid") + .removeClass("field-validation-error") + .removeData("unobtrusiveContainer") + .find(">*") // If we were using valmsg-replace, get the underlying error + .removeData("unobtrusiveContainer"); + } + + function validationInfo(form) { + var $form = $(form), + result = $form.data(data_validation), + onResetProxy = $.proxy(onReset, form), + defaultOptions = $jQval.unobtrusive.options || {}, + execInContext = function (name, args) { + var func = defaultOptions[name]; + func && $.isFunction(func) && func.apply(form, args); + }; + + if (!result) { + result = { + options: { // options structure passed to jQuery Validate's validate() method + errorClass: defaultOptions.errorClass || "input-validation-error", + errorElement: defaultOptions.errorElement || "span", + errorPlacement: function () { + onError.apply(form, arguments); + execInContext("errorPlacement", arguments); + }, + invalidHandler: function () { + onErrors.apply(form, arguments); + execInContext("invalidHandler", arguments); + }, + messages: {}, + rules: {}, + success: function () { + onSuccess.apply(form, arguments); + execInContext("success", arguments); + } + }, + attachValidation: function () { + $form + .off("reset." + data_validation, onResetProxy) + .on("reset." + data_validation, onResetProxy) + .validate(this.options); + }, + validate: function () { // a validation function that is called by unobtrusive Ajax + $form.validate(); + return $form.valid(); + } + }; + $form.data(data_validation, result); + } + + return result; + } + + $jQval.unobtrusive = { + adapters: [], + + parseElement: function (element, skipAttach) { + /// + /// Parses a single HTML element for unobtrusive validation attributes. + /// + /// The HTML element to be parsed. + /// [Optional] true to skip attaching the + /// validation to the form. If parsing just this single element, you should specify true. + /// If parsing several elements, you should specify false, and manually attach the validation + /// to the form when you are finished. The default is false. + var $element = $(element), + form = $element.parents("form")[0], + valInfo, rules, messages; + + if (!form) { // Cannot do client-side validation without a form + return; + } + + valInfo = validationInfo(form); + valInfo.options.rules[element.name] = rules = {}; + valInfo.options.messages[element.name] = messages = {}; + + $.each(this.adapters, function () { + var prefix = "data-val-" + this.name, + message = $element.attr(prefix), + paramValues = {}; + + if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) + prefix += "-"; + + $.each(this.params, function () { + paramValues[this] = $element.attr(prefix + this); + }); + + this.adapt({ + element: element, + form: form, + message: message, + params: paramValues, + rules: rules, + messages: messages + }); + } + }); + + $.extend(rules, { "__dummy__": true }); + + if (!skipAttach) { + valInfo.attachValidation(); + } + }, + + parse: function (selector) { + /// + /// Parses all the HTML elements in the specified selector. It looks for input elements decorated + /// with the [data-val=true] attribute value and enables validation according to the data-val-* + /// attribute values. + /// + /// Any valid jQuery selector. + + // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one + // element with data-val=true + var $selector = $(selector), + $forms = $selector.parents() + .addBack() + .filter("form") + .add($selector.find("form")) + .has("[data-val=true]"); + + $selector.find("[data-val=true]").each(function () { + $jQval.unobtrusive.parseElement(this, true); + }); + + $forms.each(function () { + var info = validationInfo(this); + if (info) { + info.attachValidation(); + } + }); + } + }; + + adapters = $jQval.unobtrusive.adapters; + + adapters.add = function (adapterName, params, fn) { + /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. + /// The name of the adapter to be added. This matches the name used + /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). + /// [Optional] An array of parameter names (strings) that will + /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and + /// mmmm is the parameter name). + /// The function to call, which adapts the values from the HTML + /// attributes into jQuery Validate rules and/or messages. + /// + if (!fn) { // Called with no params, just a function + fn = params; + params = []; + } + this.push({ name: adapterName, params: params, adapt: fn }); + return this; + }; + + adapters.addBool = function (adapterName, ruleName) { + /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where + /// the jQuery Validate validation rule has no parameter values. + /// The name of the adapter to be added. This matches the name used + /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). + /// [Optional] The name of the jQuery Validate rule. If not provided, the value + /// of adapterName will be used instead. + /// + return this.add(adapterName, function (options) { + setValidationValues(options, ruleName || adapterName, true); + }); + }; + + adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { + /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where + /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and + /// one for min-and-max). The HTML parameters are expected to be named -min and -max. + /// The name of the adapter to be added. This matches the name used + /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). + /// The name of the jQuery Validate rule to be used when you only + /// have a minimum value. + /// The name of the jQuery Validate rule to be used when you only + /// have a maximum value. + /// The name of the jQuery Validate rule to be used when you + /// have both a minimum and maximum value. + /// [Optional] The name of the HTML attribute that + /// contains the minimum value. The default is "min". + /// [Optional] The name of the HTML attribute that + /// contains the maximum value. The default is "max". + /// + return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { + var min = options.params.min, + max = options.params.max; + + if (min && max) { + setValidationValues(options, minMaxRuleName, [min, max]); + } + else if (min) { + setValidationValues(options, minRuleName, min); + } + else if (max) { + setValidationValues(options, maxRuleName, max); + } + }); + }; + + adapters.addSingleVal = function (adapterName, attribute, ruleName) { + /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where + /// the jQuery Validate validation rule has a single value. + /// The name of the adapter to be added. This matches the name used + /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). + /// [Optional] The name of the HTML attribute that contains the value. + /// The default is "val". + /// [Optional] The name of the jQuery Validate rule. If not provided, the value + /// of adapterName will be used instead. + /// + return this.add(adapterName, [attribute || "val"], function (options) { + setValidationValues(options, ruleName || adapterName, options.params[attribute]); + }); + }; + + $jQval.addMethod("__dummy__", function (value, element, params) { + return true; + }); + + $jQval.addMethod("regex", function (value, element, params) { + var match; + if (this.optional(element)) { + return true; + } + + match = new RegExp(params).exec(value); + return (match && (match.index === 0) && (match[0].length === value.length)); + }); + + $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { + var match; + if (nonalphamin) { + match = value.match(/\W/g); + match = match && match.length >= nonalphamin; + } + return match; + }); + + if ($jQval.methods.extension) { + adapters.addSingleVal("accept", "mimtype"); + adapters.addSingleVal("extension", "extension"); + } else { + // for backward compatibility, when the 'extension' validation method does not exist, such as with versions + // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for + // validating the extension, and ignore mime-type validations as they are not supported. + adapters.addSingleVal("extension", "extension", "accept"); + } + + adapters.addSingleVal("regex", "pattern"); + adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); + adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); + adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); + adapters.add("equalto", ["other"], function (options) { + var prefix = getModelPrefix(options.element.name), + other = options.params.other, + fullOtherName = appendModelPrefix(other, prefix), + element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; + + setValidationValues(options, "equalTo", element); + }); + adapters.add("required", function (options) { + // jQuery Validate equates "required" with "mandatory" for checkbox elements + if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { + setValidationValues(options, "required", true); + } + }); + adapters.add("remote", ["url", "type", "additionalfields"], function (options) { + var value = { + url: options.params.url, + type: options.params.type || "GET", + data: {} + }, + prefix = getModelPrefix(options.element.name); + + $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { + var paramName = appendModelPrefix(fieldName, prefix); + value.data[paramName] = function () { + var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); + // For checkboxes and radio buttons, only pick up values from checked fields. + if (field.is(":checkbox")) { + return field.filter(":checked").val() || field.filter(":hidden").val() || ''; + } + else if (field.is(":radio")) { + return field.filter(":checked").val() || ''; + } + return field.val(); + }; + }); + + setValidationValues(options, "remote", value); + }); + adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { + if (options.params.min) { + setValidationValues(options, "minlength", options.params.min); + } + if (options.params.nonalphamin) { + setValidationValues(options, "nonalphamin", options.params.nonalphamin); + } + if (options.params.regex) { + setValidationValues(options, "regex", options.params.regex); + } + }); + adapters.add("fileextensions", ["extensions"], function (options) { + setValidationValues(options, "extension", options.params.extensions); + }); + + $(function () { + $jQval.unobtrusive.parse(document); + }); + + return $jQval.unobtrusive; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/jquery.validate.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/jquery.validate.js new file mode 100644 index 0000000000..397885ef73 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/jquery.validate.js @@ -0,0 +1,1650 @@ +/*! + * jQuery Validation Plugin v1.19.0 + * + * https://jqueryvalidation.org/ + * + * Copyright (c) 2018 Jörn Zaefferer + * Released under the MIT license + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +$.extend( $.fn, { + + // https://jqueryvalidation.org/validate/ + validate: function( options ) { + + // If nothing is selected, return nothing; can't chain anyway + if ( !this.length ) { + if ( options && options.debug && window.console ) { + console.warn( "Nothing selected, can't validate, returning nothing." ); + } + return; + } + + // Check if a validator for this form was already created + var validator = $.data( this[ 0 ], "validator" ); + if ( validator ) { + return validator; + } + + // Add novalidate tag if HTML5. + this.attr( "novalidate", "novalidate" ); + + validator = new $.validator( options, this[ 0 ] ); + $.data( this[ 0 ], "validator", validator ); + + if ( validator.settings.onsubmit ) { + + this.on( "click.validate", ":submit", function( event ) { + + // Track the used submit button to properly handle scripted + // submits later. + validator.submitButton = event.currentTarget; + + // Allow suppressing validation by adding a cancel class to the submit button + if ( $( this ).hasClass( "cancel" ) ) { + validator.cancelSubmit = true; + } + + // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button + if ( $( this ).attr( "formnovalidate" ) !== undefined ) { + validator.cancelSubmit = true; + } + } ); + + // Validate the form on submit + this.on( "submit.validate", function( event ) { + if ( validator.settings.debug ) { + + // Prevent form submit to be able to see console output + event.preventDefault(); + } + + function handle() { + var hidden, result; + + // Insert a hidden input as a replacement for the missing submit button + // The hidden input is inserted in two cases: + // - A user defined a `submitHandler` + // - There was a pending request due to `remote` method and `stopRequest()` + // was called to submit the form in case it's valid + if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) { + hidden = $( "" ) + .attr( "name", validator.submitButton.name ) + .val( $( validator.submitButton ).val() ) + .appendTo( validator.currentForm ); + } + + if ( validator.settings.submitHandler && !validator.settings.debug ) { + result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); + if ( hidden ) { + + // And clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + if ( result !== undefined ) { + return result; + } + return false; + } + return true; + } + + // Prevent submit for invalid forms or custom submit handlers + if ( validator.cancelSubmit ) { + validator.cancelSubmit = false; + return handle(); + } + if ( validator.form() ) { + if ( validator.pendingRequest ) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + } ); + } + + return validator; + }, + + // https://jqueryvalidation.org/valid/ + valid: function() { + var valid, validator, errorList; + + if ( $( this[ 0 ] ).is( "form" ) ) { + valid = this.validate().form(); + } else { + errorList = []; + valid = true; + validator = $( this[ 0 ].form ).validate(); + this.each( function() { + valid = validator.element( this ) && valid; + if ( !valid ) { + errorList = errorList.concat( validator.errorList ); + } + } ); + validator.errorList = errorList; + } + return valid; + }, + + // https://jqueryvalidation.org/rules/ + rules: function( command, argument ) { + var element = this[ 0 ], + isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false", + settings, staticRules, existingRules, data, param, filtered; + + // If nothing is selected, return empty object; can't chain anyway + if ( element == null ) { + return; + } + + if ( !element.form && isContentEditable ) { + element.form = this.closest( "form" )[ 0 ]; + element.name = this.attr( "name" ); + } + + if ( element.form == null ) { + return; + } + + if ( command ) { + settings = $.data( element.form, "validator" ).settings; + staticRules = settings.rules; + existingRules = $.validator.staticRules( element ); + switch ( command ) { + case "add": + $.extend( existingRules, $.validator.normalizeRule( argument ) ); + + // Remove messages from rules, but allow them to be set separately + delete existingRules.messages; + staticRules[ element.name ] = existingRules; + if ( argument.messages ) { + settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); + } + break; + case "remove": + if ( !argument ) { + delete staticRules[ element.name ]; + return existingRules; + } + filtered = {}; + $.each( argument.split( /\s/ ), function( index, method ) { + filtered[ method ] = existingRules[ method ]; + delete existingRules[ method ]; + } ); + return filtered; + } + } + + data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.classRules( element ), + $.validator.attributeRules( element ), + $.validator.dataRules( element ), + $.validator.staticRules( element ) + ), element ); + + // Make sure required is at front + if ( data.required ) { + param = data.required; + delete data.required; + data = $.extend( { required: param }, data ); + } + + // Make sure remote is at back + if ( data.remote ) { + param = data.remote; + delete data.remote; + data = $.extend( data, { remote: param } ); + } + + return data; + } +} ); + +// Custom selectors +$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support + + // https://jqueryvalidation.org/blank-selector/ + blank: function( a ) { + return !$.trim( "" + $( a ).val() ); + }, + + // https://jqueryvalidation.org/filled-selector/ + filled: function( a ) { + var val = $( a ).val(); + return val !== null && !!$.trim( "" + val ); + }, + + // https://jqueryvalidation.org/unchecked-selector/ + unchecked: function( a ) { + return !$( a ).prop( "checked" ); + } +} ); + +// Constructor for validator +$.validator = function( options, form ) { + this.settings = $.extend( true, {}, $.validator.defaults, options ); + this.currentForm = form; + this.init(); +}; + +// https://jqueryvalidation.org/jQuery.validator.format/ +$.validator.format = function( source, params ) { + if ( arguments.length === 1 ) { + return function() { + var args = $.makeArray( arguments ); + args.unshift( source ); + return $.validator.format.apply( this, args ); + }; + } + if ( params === undefined ) { + return source; + } + if ( arguments.length > 2 && params.constructor !== Array ) { + params = $.makeArray( arguments ).slice( 1 ); + } + if ( params.constructor !== Array ) { + params = [ params ]; + } + $.each( params, function( i, n ) { + source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { + return n; + } ); + } ); + return source; +}; + +$.extend( $.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + pendingClass: "pending", + validClass: "valid", + errorElement: "label", + focusCleanup: false, + focusInvalid: true, + errorContainer: $( [] ), + errorLabelContainer: $( [] ), + onsubmit: true, + ignore: ":hidden", + ignoreTitle: false, + onfocusin: function( element ) { + this.lastActive = element; + + // Hide error label and remove error class on focus if enabled + if ( this.settings.focusCleanup ) { + if ( this.settings.unhighlight ) { + this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); + } + this.hideThese( this.errorsFor( element ) ); + } + }, + onfocusout: function( element ) { + if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { + this.element( element ); + } + }, + onkeyup: function( element, event ) { + + // Avoid revalidate the field when pressing one of the following keys + // Shift => 16 + // Ctrl => 17 + // Alt => 18 + // Caps lock => 20 + // End => 35 + // Home => 36 + // Left arrow => 37 + // Up arrow => 38 + // Right arrow => 39 + // Down arrow => 40 + // Insert => 45 + // Num lock => 144 + // AltGr key => 225 + var excludedKeys = [ + 16, 17, 18, 20, 35, 36, 37, + 38, 39, 40, 45, 144, 225 + ]; + + if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { + return; + } else if ( element.name in this.submitted || element.name in this.invalid ) { + this.element( element ); + } + }, + onclick: function( element ) { + + // Click on selects, radiobuttons and checkboxes + if ( element.name in this.submitted ) { + this.element( element ); + + // Or option elements, check parent select in that case + } else if ( element.parentNode.name in this.submitted ) { + this.element( element.parentNode ); + } + }, + highlight: function( element, errorClass, validClass ) { + if ( element.type === "radio" ) { + this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); + } else { + $( element ).addClass( errorClass ).removeClass( validClass ); + } + }, + unhighlight: function( element, errorClass, validClass ) { + if ( element.type === "radio" ) { + this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); + } else { + $( element ).removeClass( errorClass ).addClass( validClass ); + } + } + }, + + // https://jqueryvalidation.org/jQuery.validator.setDefaults/ + setDefaults: function( settings ) { + $.extend( $.validator.defaults, settings ); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + equalTo: "Please enter the same value again.", + maxlength: $.validator.format( "Please enter no more than {0} characters." ), + minlength: $.validator.format( "Please enter at least {0} characters." ), + rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), + range: $.validator.format( "Please enter a value between {0} and {1}." ), + max: $.validator.format( "Please enter a value less than or equal to {0}." ), + min: $.validator.format( "Please enter a value greater than or equal to {0}." ), + step: $.validator.format( "Please enter a multiple of {0}." ) + }, + + autoCreateRanges: false, + + prototype: { + + init: function() { + this.labelContainer = $( this.settings.errorLabelContainer ); + this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); + this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var currentForm = this.currentForm, + groups = ( this.groups = {} ), + rules; + $.each( this.settings.groups, function( key, value ) { + if ( typeof value === "string" ) { + value = value.split( /\s/ ); + } + $.each( value, function( index, name ) { + groups[ name ] = key; + } ); + } ); + rules = this.settings.rules; + $.each( rules, function( key, value ) { + rules[ key ] = $.validator.normalizeRule( value ); + } ); + + function delegate( event ) { + var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; + + // Set form expando on contenteditable + if ( !this.form && isContentEditable ) { + this.form = $( this ).closest( "form" )[ 0 ]; + this.name = $( this ).attr( "name" ); + } + + // Ignore the element if it belongs to another form. This will happen mainly + // when setting the `form` attribute of an input to the id of another form. + if ( currentForm !== this.form ) { + return; + } + + var validator = $.data( this.form, "validator" ), + eventType = "on" + event.type.replace( /^validate/, "" ), + settings = validator.settings; + if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) { + settings[ eventType ].call( validator, this, event ); + } + } + + $( this.currentForm ) + .on( "focusin.validate focusout.validate keyup.validate", + ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + + "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + + "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + + "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate ) + + // Support: Chrome, oldIE + // "select" is provided as event.target when clicking a option + .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate ); + + if ( this.settings.invalidHandler ) { + $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler ); + } + }, + + // https://jqueryvalidation.org/Validator.form/ + form: function() { + this.checkForm(); + $.extend( this.submitted, this.errorMap ); + this.invalid = $.extend( {}, this.errorMap ); + if ( !this.valid() ) { + $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); + } + this.showErrors(); + return this.valid(); + }, + + checkForm: function() { + this.prepareForm(); + for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { + this.check( elements[ i ] ); + } + return this.valid(); + }, + + // https://jqueryvalidation.org/Validator.element/ + element: function( element ) { + var cleanElement = this.clean( element ), + checkElement = this.validationTargetFor( cleanElement ), + v = this, + result = true, + rs, group; + + if ( checkElement === undefined ) { + delete this.invalid[ cleanElement.name ]; + } else { + this.prepareElement( checkElement ); + this.currentElements = $( checkElement ); + + // If this element is grouped, then validate all group elements already + // containing a value + group = this.groups[ checkElement.name ]; + if ( group ) { + $.each( this.groups, function( name, testgroup ) { + if ( testgroup === group && name !== checkElement.name ) { + cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) ); + if ( cleanElement && cleanElement.name in v.invalid ) { + v.currentElements.push( cleanElement ); + result = v.check( cleanElement ) && result; + } + } + } ); + } + + rs = this.check( checkElement ) !== false; + result = result && rs; + if ( rs ) { + this.invalid[ checkElement.name ] = false; + } else { + this.invalid[ checkElement.name ] = true; + } + + if ( !this.numberOfInvalids() ) { + + // Hide error containers on last error + this.toHide = this.toHide.add( this.containers ); + } + this.showErrors(); + + // Add aria-invalid status for screen readers + $( element ).attr( "aria-invalid", !rs ); + } + + return result; + }, + + // https://jqueryvalidation.org/Validator.showErrors/ + showErrors: function( errors ) { + if ( errors ) { + var validator = this; + + // Add items to error list and map + $.extend( this.errorMap, errors ); + this.errorList = $.map( this.errorMap, function( message, name ) { + return { + message: message, + element: validator.findByName( name )[ 0 ] + }; + } ); + + // Remove items from success list + this.successList = $.grep( this.successList, function( element ) { + return !( element.name in errors ); + } ); + } + if ( this.settings.showErrors ) { + this.settings.showErrors.call( this, this.errorMap, this.errorList ); + } else { + this.defaultShowErrors(); + } + }, + + // https://jqueryvalidation.org/Validator.resetForm/ + resetForm: function() { + if ( $.fn.resetForm ) { + $( this.currentForm ).resetForm(); + } + this.invalid = {}; + this.submitted = {}; + this.prepareForm(); + this.hideErrors(); + var elements = this.elements() + .removeData( "previousValue" ) + .removeAttr( "aria-invalid" ); + + this.resetElements( elements ); + }, + + resetElements: function( elements ) { + var i; + + if ( this.settings.unhighlight ) { + for ( i = 0; elements[ i ]; i++ ) { + this.settings.unhighlight.call( this, elements[ i ], + this.settings.errorClass, "" ); + this.findByName( elements[ i ].name ).removeClass( this.settings.validClass ); + } + } else { + elements + .removeClass( this.settings.errorClass ) + .removeClass( this.settings.validClass ); + } + }, + + numberOfInvalids: function() { + return this.objectLength( this.invalid ); + }, + + objectLength: function( obj ) { + /* jshint unused: false */ + var count = 0, + i; + for ( i in obj ) { + + // This check allows counting elements with empty error + // message as invalid elements + if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) { + count++; + } + } + return count; + }, + + hideErrors: function() { + this.hideThese( this.toHide ); + }, + + hideThese: function( errors ) { + errors.not( this.containers ).text( "" ); + this.addWrapper( errors ).hide(); + }, + + valid: function() { + return this.size() === 0; + }, + + size: function() { + return this.errorList.length; + }, + + focusInvalid: function() { + if ( this.settings.focusInvalid ) { + try { + $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] ) + .filter( ":visible" ) + .focus() + + // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger( "focusin" ); + } catch ( e ) { + + // Ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function() { + var lastActive = this.lastActive; + return lastActive && $.grep( this.errorList, function( n ) { + return n.element.name === lastActive.name; + } ).length === 1 && lastActive; + }, + + elements: function() { + var validator = this, + rulesCache = {}; + + // Select all valid inputs inside the form (no submit or reset buttons) + return $( this.currentForm ) + .find( "input, select, textarea, [contenteditable]" ) + .not( ":submit, :reset, :image, :disabled" ) + .not( this.settings.ignore ) + .filter( function() { + var name = this.name || $( this ).attr( "name" ); // For contenteditable + var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; + + if ( !name && validator.settings.debug && window.console ) { + console.error( "%o has no name assigned", this ); + } + + // Set form expando on contenteditable + if ( isContentEditable ) { + this.form = $( this ).closest( "form" )[ 0 ]; + this.name = name; + } + + // Ignore elements that belong to other/nested forms + if ( this.form !== validator.currentForm ) { + return false; + } + + // Select only the first element for each name, and only those with rules specified + if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { + return false; + } + + rulesCache[ name ] = true; + return true; + } ); + }, + + clean: function( selector ) { + return $( selector )[ 0 ]; + }, + + errors: function() { + var errorClass = this.settings.errorClass.split( " " ).join( "." ); + return $( this.settings.errorElement + "." + errorClass, this.errorContext ); + }, + + resetInternals: function() { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $( [] ); + this.toHide = $( [] ); + }, + + reset: function() { + this.resetInternals(); + this.currentElements = $( [] ); + }, + + prepareForm: function() { + this.reset(); + this.toHide = this.errors().add( this.containers ); + }, + + prepareElement: function( element ) { + this.reset(); + this.toHide = this.errorsFor( element ); + }, + + elementValue: function( element ) { + var $element = $( element ), + type = element.type, + isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false", + val, idx; + + if ( type === "radio" || type === "checkbox" ) { + return this.findByName( element.name ).filter( ":checked" ).val(); + } else if ( type === "number" && typeof element.validity !== "undefined" ) { + return element.validity.badInput ? "NaN" : $element.val(); + } + + if ( isContentEditable ) { + val = $element.text(); + } else { + val = $element.val(); + } + + if ( type === "file" ) { + + // Modern browser (chrome & safari) + if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) { + return val.substr( 12 ); + } + + // Legacy browsers + // Unix-based path + idx = val.lastIndexOf( "/" ); + if ( idx >= 0 ) { + return val.substr( idx + 1 ); + } + + // Windows-based path + idx = val.lastIndexOf( "\\" ); + if ( idx >= 0 ) { + return val.substr( idx + 1 ); + } + + // Just the file name + return val; + } + + if ( typeof val === "string" ) { + return val.replace( /\r/g, "" ); + } + return val; + }, + + check: function( element ) { + element = this.validationTargetFor( this.clean( element ) ); + + var rules = $( element ).rules(), + rulesCount = $.map( rules, function( n, i ) { + return i; + } ).length, + dependencyMismatch = false, + val = this.elementValue( element ), + result, method, rule, normalizer; + + // Prioritize the local normalizer defined for this element over the global one + // if the former exists, otherwise user the global one in case it exists. + if ( typeof rules.normalizer === "function" ) { + normalizer = rules.normalizer; + } else if ( typeof this.settings.normalizer === "function" ) { + normalizer = this.settings.normalizer; + } + + // If normalizer is defined, then call it to retreive the changed value instead + // of using the real one. + // Note that `this` in the normalizer is `element`. + if ( normalizer ) { + val = normalizer.call( element, val ); + + // Delete the normalizer from rules to avoid treating it as a pre-defined method. + delete rules.normalizer; + } + + for ( method in rules ) { + rule = { method: method, parameters: rules[ method ] }; + try { + result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); + + // If a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if ( result === "dependency-mismatch" && rulesCount === 1 ) { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if ( result === "pending" ) { + this.toHide = this.toHide.not( this.errorsFor( element ) ); + return; + } + + if ( !result ) { + this.formatAndAdd( element, rule ); + return false; + } + } catch ( e ) { + if ( this.settings.debug && window.console ) { + console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); + } + if ( e instanceof TypeError ) { + e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; + } + + throw e; + } + } + if ( dependencyMismatch ) { + return; + } + if ( this.objectLength( rules ) ) { + this.successList.push( element ); + } + return true; + }, + + // Return the custom message for the given element and validation method + // specified in the element's HTML5 data attribute + // return the generic message if present and no method specific message is present + customDataMessage: function( element, method ) { + return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + + method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); + }, + + // Return the custom message for the given element name and validation method + customMessage: function( name, method ) { + var m = this.settings.messages[ name ]; + return m && ( m.constructor === String ? m : m[ method ] ); + }, + + // Return the first defined argument, allowing empty strings + findDefined: function() { + for ( var i = 0; i < arguments.length; i++ ) { + if ( arguments[ i ] !== undefined ) { + return arguments[ i ]; + } + } + return undefined; + }, + + // The second parameter 'rule' used to be a string, and extended to an object literal + // of the following form: + // rule = { + // method: "method name", + // parameters: "the given method parameters" + // } + // + // The old behavior still supported, kept to maintain backward compatibility with + // old code, and will be removed in the next major release. + defaultMessage: function( element, rule ) { + if ( typeof rule === "string" ) { + rule = { method: rule }; + } + + var message = this.findDefined( + this.customMessage( element.name, rule.method ), + this.customDataMessage( element, rule.method ), + + // 'title' is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[ rule.method ], + "Warning: No message defined for " + element.name + "" + ), + theregex = /\$?\{(\d+)\}/g; + if ( typeof message === "function" ) { + message = message.call( this, rule.parameters, element ); + } else if ( theregex.test( message ) ) { + message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); + } + + return message; + }, + + formatAndAdd: function( element, rule ) { + var message = this.defaultMessage( element, rule ); + + this.errorList.push( { + message: message, + element: element, + method: rule.method + } ); + + this.errorMap[ element.name ] = message; + this.submitted[ element.name ] = message; + }, + + addWrapper: function( toToggle ) { + if ( this.settings.wrapper ) { + toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); + } + return toToggle; + }, + + defaultShowErrors: function() { + var i, elements, error; + for ( i = 0; this.errorList[ i ]; i++ ) { + error = this.errorList[ i ]; + if ( this.settings.highlight ) { + this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); + } + this.showLabel( error.element, error.message ); + } + if ( this.errorList.length ) { + this.toShow = this.toShow.add( this.containers ); + } + if ( this.settings.success ) { + for ( i = 0; this.successList[ i ]; i++ ) { + this.showLabel( this.successList[ i ] ); + } + } + if ( this.settings.unhighlight ) { + for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { + this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); + } + } + this.toHide = this.toHide.not( this.toShow ); + this.hideErrors(); + this.addWrapper( this.toShow ).show(); + }, + + validElements: function() { + return this.currentElements.not( this.invalidElements() ); + }, + + invalidElements: function() { + return $( this.errorList ).map( function() { + return this.element; + } ); + }, + + showLabel: function( element, message ) { + var place, group, errorID, v, + error = this.errorsFor( element ), + elementID = this.idOrName( element ), + describedBy = $( element ).attr( "aria-describedby" ); + + if ( error.length ) { + + // Refresh error/success class + error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); + + // Replace message on existing label + error.html( message ); + } else { + + // Create error element + error = $( "<" + this.settings.errorElement + ">" ) + .attr( "id", elementID + "-error" ) + .addClass( this.settings.errorClass ) + .html( message || "" ); + + // Maintain reference to the element to be placed into the DOM + place = error; + if ( this.settings.wrapper ) { + + // Make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); + } + if ( this.labelContainer.length ) { + this.labelContainer.append( place ); + } else if ( this.settings.errorPlacement ) { + this.settings.errorPlacement.call( this, place, $( element ) ); + } else { + place.insertAfter( element ); + } + + // Link error back to the element + if ( error.is( "label" ) ) { + + // If the error is a label, then associate using 'for' + error.attr( "for", elementID ); + + // If the element is not a child of an associated label, then it's necessary + // to explicitly apply aria-describedby + } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) { + errorID = error.attr( "id" ); + + // Respect existing non-error aria-describedby + if ( !describedBy ) { + describedBy = errorID; + } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) { + + // Add to end of list if not already present + describedBy += " " + errorID; + } + $( element ).attr( "aria-describedby", describedBy ); + + // If this element is grouped, then assign to all elements in the same group + group = this.groups[ element.name ]; + if ( group ) { + v = this; + $.each( v.groups, function( name, testgroup ) { + if ( testgroup === group ) { + $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm ) + .attr( "aria-describedby", error.attr( "id" ) ); + } + } ); + } + } + } + if ( !message && this.settings.success ) { + error.text( "" ); + if ( typeof this.settings.success === "string" ) { + error.addClass( this.settings.success ); + } else { + this.settings.success( error, element ); + } + } + this.toShow = this.toShow.add( error ); + }, + + errorsFor: function( element ) { + var name = this.escapeCssMeta( this.idOrName( element ) ), + describer = $( element ).attr( "aria-describedby" ), + selector = "label[for='" + name + "'], label[for='" + name + "'] *"; + + // 'aria-describedby' should directly reference the error element + if ( describer ) { + selector = selector + ", #" + this.escapeCssMeta( describer ) + .replace( /\s+/g, ", #" ); + } + + return this + .errors() + .filter( selector ); + }, + + // See https://api.jquery.com/category/selectors/, for CSS + // meta-characters that should be escaped in order to be used with JQuery + // as a literal part of a name/id or any selector. + escapeCssMeta: function( string ) { + return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" ); + }, + + idOrName: function( element ) { + return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name ); + }, + + validationTargetFor: function( element ) { + + // If radio/checkbox, validate first element in group instead + if ( this.checkable( element ) ) { + element = this.findByName( element.name ); + } + + // Always apply ignore filter + return $( element ).not( this.settings.ignore )[ 0 ]; + }, + + checkable: function( element ) { + return ( /radio|checkbox/i ).test( element.type ); + }, + + findByName: function( name ) { + return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" ); + }, + + getLength: function( value, element ) { + switch ( element.nodeName.toLowerCase() ) { + case "select": + return $( "option:selected", element ).length; + case "input": + if ( this.checkable( element ) ) { + return this.findByName( element.name ).filter( ":checked" ).length; + } + } + return value.length; + }, + + depend: function( param, element ) { + return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true; + }, + + dependTypes: { + "boolean": function( param ) { + return param; + }, + "string": function( param, element ) { + return !!$( param, element.form ).length; + }, + "function": function( param, element ) { + return param( element ); + } + }, + + optional: function( element ) { + var val = this.elementValue( element ); + return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; + }, + + startRequest: function( element ) { + if ( !this.pending[ element.name ] ) { + this.pendingRequest++; + $( element ).addClass( this.settings.pendingClass ); + this.pending[ element.name ] = true; + } + }, + + stopRequest: function( element, valid ) { + this.pendingRequest--; + + // Sometimes synchronization fails, make sure pendingRequest is never < 0 + if ( this.pendingRequest < 0 ) { + this.pendingRequest = 0; + } + delete this.pending[ element.name ]; + $( element ).removeClass( this.settings.pendingClass ); + if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { + $( this.currentForm ).submit(); + + // Remove the hidden input that was used as a replacement for the + // missing submit button. The hidden input is added by `handle()` + // to ensure that the value of the used submit button is passed on + // for scripted submits triggered by this method + if ( this.submitButton ) { + $( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove(); + } + + this.formSubmitted = false; + } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) { + $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); + this.formSubmitted = false; + } + }, + + previousValue: function( element, method ) { + method = typeof method === "string" && method || "remote"; + + return $.data( element, "previousValue" ) || $.data( element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage( element, { method: method } ) + } ); + }, + + // Cleans up all forms and elements, removes validator-specific events + destroy: function() { + this.resetForm(); + + $( this.currentForm ) + .off( ".validate" ) + .removeData( "validator" ) + .find( ".validate-equalTo-blur" ) + .off( ".validate-equalTo" ) + .removeClass( "validate-equalTo-blur" ) + .find( ".validate-lessThan-blur" ) + .off( ".validate-lessThan" ) + .removeClass( "validate-lessThan-blur" ) + .find( ".validate-lessThanEqual-blur" ) + .off( ".validate-lessThanEqual" ) + .removeClass( "validate-lessThanEqual-blur" ) + .find( ".validate-greaterThanEqual-blur" ) + .off( ".validate-greaterThanEqual" ) + .removeClass( "validate-greaterThanEqual-blur" ) + .find( ".validate-greaterThan-blur" ) + .off( ".validate-greaterThan" ) + .removeClass( "validate-greaterThan-blur" ); + } + + }, + + classRuleSettings: { + required: { required: true }, + email: { email: true }, + url: { url: true }, + date: { date: true }, + dateISO: { dateISO: true }, + number: { number: true }, + digits: { digits: true }, + creditcard: { creditcard: true } + }, + + addClassRules: function( className, rules ) { + if ( className.constructor === String ) { + this.classRuleSettings[ className ] = rules; + } else { + $.extend( this.classRuleSettings, className ); + } + }, + + classRules: function( element ) { + var rules = {}, + classes = $( element ).attr( "class" ); + + if ( classes ) { + $.each( classes.split( " " ), function() { + if ( this in $.validator.classRuleSettings ) { + $.extend( rules, $.validator.classRuleSettings[ this ] ); + } + } ); + } + return rules; + }, + + normalizeAttributeRule: function( rules, type, method, value ) { + + // Convert the value to a number for number inputs, and for text for backwards compability + // allows type="date" and others to be compared as strings + if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { + value = Number( value ); + + // Support Opera Mini, which returns NaN for undefined minlength + if ( isNaN( value ) ) { + value = undefined; + } + } + + if ( value || value === 0 ) { + rules[ method ] = value; + } else if ( type === method && type !== "range" ) { + + // Exception: the jquery validate 'range' method + // does not test for the html5 'range' type + rules[ method ] = true; + } + }, + + attributeRules: function( element ) { + var rules = {}, + $element = $( element ), + type = element.getAttribute( "type" ), + method, value; + + for ( method in $.validator.methods ) { + + // Support for in both html5 and older browsers + if ( method === "required" ) { + value = element.getAttribute( method ); + + // Some browsers return an empty string for the required attribute + // and non-HTML5 browsers might have required="" markup + if ( value === "" ) { + value = true; + } + + // Force non-HTML5 browsers to return bool + value = !!value; + } else { + value = $element.attr( method ); + } + + this.normalizeAttributeRule( rules, type, method, value ); + } + + // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs + if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { + delete rules.maxlength; + } + + return rules; + }, + + dataRules: function( element ) { + var rules = {}, + $element = $( element ), + type = element.getAttribute( "type" ), + method, value; + + for ( method in $.validator.methods ) { + value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); + + // Cast empty attributes like `data-rule-required` to `true` + if ( value === "" ) { + value = true; + } + + this.normalizeAttributeRule( rules, type, method, value ); + } + return rules; + }, + + staticRules: function( element ) { + var rules = {}, + validator = $.data( element.form, "validator" ); + + if ( validator.settings.rules ) { + rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; + } + return rules; + }, + + normalizeRules: function( rules, element ) { + + // Handle dependency check + $.each( rules, function( prop, val ) { + + // Ignore rule when param is explicitly false, eg. required:false + if ( val === false ) { + delete rules[ prop ]; + return; + } + if ( val.param || val.depends ) { + var keepRule = true; + switch ( typeof val.depends ) { + case "string": + keepRule = !!$( val.depends, element.form ).length; + break; + case "function": + keepRule = val.depends.call( element, element ); + break; + } + if ( keepRule ) { + rules[ prop ] = val.param !== undefined ? val.param : true; + } else { + $.data( element.form, "validator" ).resetElements( $( element ) ); + delete rules[ prop ]; + } + } + } ); + + // Evaluate parameters + $.each( rules, function( rule, parameter ) { + rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter; + } ); + + // Clean number parameters + $.each( [ "minlength", "maxlength" ], function() { + if ( rules[ this ] ) { + rules[ this ] = Number( rules[ this ] ); + } + } ); + $.each( [ "rangelength", "range" ], function() { + var parts; + if ( rules[ this ] ) { + if ( $.isArray( rules[ this ] ) ) { + rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ]; + } else if ( typeof rules[ this ] === "string" ) { + parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ ); + rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ]; + } + } + } ); + + if ( $.validator.autoCreateRanges ) { + + // Auto-create ranges + if ( rules.min != null && rules.max != null ) { + rules.range = [ rules.min, rules.max ]; + delete rules.min; + delete rules.max; + } + if ( rules.minlength != null && rules.maxlength != null ) { + rules.rangelength = [ rules.minlength, rules.maxlength ]; + delete rules.minlength; + delete rules.maxlength; + } + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function( data ) { + if ( typeof data === "string" ) { + var transformed = {}; + $.each( data.split( /\s/ ), function() { + transformed[ this ] = true; + } ); + data = transformed; + } + return data; + }, + + // https://jqueryvalidation.org/jQuery.validator.addMethod/ + addMethod: function( name, method, message ) { + $.validator.methods[ name ] = method; + $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; + if ( method.length < 3 ) { + $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); + } + }, + + // https://jqueryvalidation.org/jQuery.validator.methods/ + methods: { + + // https://jqueryvalidation.org/required-method/ + required: function( value, element, param ) { + + // Check if dependency is met + if ( !this.depend( param, element ) ) { + return "dependency-mismatch"; + } + if ( element.nodeName.toLowerCase() === "select" ) { + + // Could be an array for select-multiple or a string, both are fine this way + var val = $( element ).val(); + return val && val.length > 0; + } + if ( this.checkable( element ) ) { + return this.getLength( value, element ) > 0; + } + return value !== undefined && value !== null && value.length > 0; + }, + + // https://jqueryvalidation.org/email-method/ + email: function( value, element ) { + + // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + // Retrieved 2014-01-14 + // If you have a problem with this implementation, report a bug against the above spec + // Or use custom methods to implement your own email validation + return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); + }, + + // https://jqueryvalidation.org/url-method/ + url: function( value, element ) { + + // Copyright (c) 2010-2013 Diego Perini, MIT licensed + // https://gist.github.com/dperini/729294 + // see also https://mathiasbynens.be/demo/url-regex + // modified to allow protocol-relative URLs + return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); + }, + + // https://jqueryvalidation.org/date-method/ + date: ( function() { + var called = false; + + return function( value, element ) { + if ( !called ) { + called = true; + if ( this.settings.debug && window.console ) { + console.warn( + "The `date` method is deprecated and will be removed in version '2.0.0'.\n" + + "Please don't use it, since it relies on the Date constructor, which\n" + + "behaves very differently across browsers and locales. Use `dateISO`\n" + + "instead or one of the locale specific methods in `localizations/`\n" + + "and `additional-methods.js`." + ); + } + } + + return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); + }; + }() ), + + // https://jqueryvalidation.org/dateISO-method/ + dateISO: function( value, element ) { + return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); + }, + + // https://jqueryvalidation.org/number-method/ + number: function( value, element ) { + return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); + }, + + // https://jqueryvalidation.org/digits-method/ + digits: function( value, element ) { + return this.optional( element ) || /^\d+$/.test( value ); + }, + + // https://jqueryvalidation.org/minlength-method/ + minlength: function( value, element, param ) { + var length = $.isArray( value ) ? value.length : this.getLength( value, element ); + return this.optional( element ) || length >= param; + }, + + // https://jqueryvalidation.org/maxlength-method/ + maxlength: function( value, element, param ) { + var length = $.isArray( value ) ? value.length : this.getLength( value, element ); + return this.optional( element ) || length <= param; + }, + + // https://jqueryvalidation.org/rangelength-method/ + rangelength: function( value, element, param ) { + var length = $.isArray( value ) ? value.length : this.getLength( value, element ); + return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); + }, + + // https://jqueryvalidation.org/min-method/ + min: function( value, element, param ) { + return this.optional( element ) || value >= param; + }, + + // https://jqueryvalidation.org/max-method/ + max: function( value, element, param ) { + return this.optional( element ) || value <= param; + }, + + // https://jqueryvalidation.org/range-method/ + range: function( value, element, param ) { + return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); + }, + + // https://jqueryvalidation.org/step-method/ + step: function( value, element, param ) { + var type = $( element ).attr( "type" ), + errorMessage = "Step attribute on input type " + type + " is not supported.", + supportedTypes = [ "text", "number", "range" ], + re = new RegExp( "\\b" + type + "\\b" ), + notSupported = type && !re.test( supportedTypes.join() ), + decimalPlaces = function( num ) { + var match = ( "" + num ).match( /(?:\.(\d+))?$/ ); + if ( !match ) { + return 0; + } + + // Number of digits right of decimal point. + return match[ 1 ] ? match[ 1 ].length : 0; + }, + toInt = function( num ) { + return Math.round( num * Math.pow( 10, decimals ) ); + }, + valid = true, + decimals; + + // Works only for text, number and range input types + // TODO find a way to support input types date, datetime, datetime-local, month, time and week + if ( notSupported ) { + throw new Error( errorMessage ); + } + + decimals = decimalPlaces( param ); + + // Value can't have too many decimals + if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) { + valid = false; + } + + return this.optional( element ) || valid; + }, + + // https://jqueryvalidation.org/equalTo-method/ + equalTo: function( value, element, param ) { + + // Bind to the blur event of the target in order to revalidate whenever the target field is updated + var target = $( param ); + if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) { + target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() { + $( element ).valid(); + } ); + } + return value === target.val(); + }, + + // https://jqueryvalidation.org/remote-method/ + remote: function( value, element, param, method ) { + if ( this.optional( element ) ) { + return "dependency-mismatch"; + } + + method = typeof method === "string" && method || "remote"; + + var previous = this.previousValue( element, method ), + validator, data, optionDataString; + + if ( !this.settings.messages[ element.name ] ) { + this.settings.messages[ element.name ] = {}; + } + previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ]; + this.settings.messages[ element.name ][ method ] = previous.message; + + param = typeof param === "string" && { url: param } || param; + optionDataString = $.param( $.extend( { data: value }, param.data ) ); + if ( previous.old === optionDataString ) { + return previous.valid; + } + + previous.old = optionDataString; + validator = this; + this.startRequest( element ); + data = {}; + data[ element.name ] = value; + $.ajax( $.extend( true, { + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + context: validator.currentForm, + success: function( response ) { + var valid = response === true || response === "true", + errors, message, submitted; + + validator.settings.messages[ element.name ][ method ] = previous.originalMessage; + if ( valid ) { + submitted = validator.formSubmitted; + validator.resetInternals(); + validator.toHide = validator.errorsFor( element ); + validator.formSubmitted = submitted; + validator.successList.push( element ); + validator.invalid[ element.name ] = false; + validator.showErrors(); + } else { + errors = {}; + message = response || validator.defaultMessage( element, { method: method, parameters: value } ); + errors[ element.name ] = previous.message = message; + validator.invalid[ element.name ] = true; + validator.showErrors( errors ); + } + previous.valid = valid; + validator.stopRequest( element, valid ); + } + }, param ) ); + return "pending"; + } + } + +} ); + +// Ajax mode: abort +// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); +// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() + +var pendingRequests = {}, + ajax; + +// Use a prefilter if available (1.5+) +if ( $.ajaxPrefilter ) { + $.ajaxPrefilter( function( settings, _, xhr ) { + var port = settings.port; + if ( settings.mode === "abort" ) { + if ( pendingRequests[ port ] ) { + pendingRequests[ port ].abort(); + } + pendingRequests[ port ] = xhr; + } + } ); +} else { + + // Proxy ajax + ajax = $.ajax; + $.ajax = function( settings ) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if ( mode === "abort" ) { + if ( pendingRequests[ port ] ) { + pendingRequests[ port ].abort(); + } + pendingRequests[ port ] = ajax.apply( this, arguments ); + return pendingRequests[ port ]; + } + return ajax.apply( this, arguments ); + }; +} +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.js new file mode 100644 index 0000000000..c58f8bf6c7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: AR (Arabic; العربية) + */ +$.extend( $.validator.messages, { + required: "هذا الحقل إلزامي", + remote: "يرجى تصحيح هذا الحقل للمتابعة", + email: "رجاء إدخال عنوان بريد إلكتروني صحيح", + url: "رجاء إدخال عنوان موقع إلكتروني صحيح", + date: "رجاء إدخال تاريخ صحيح", + dateISO: "رجاء إدخال تاريخ صحيح (ISO)", + number: "رجاء إدخال عدد بطريقة صحيحة", + digits: "رجاء إدخال أرقام فقط", + creditcard: "رجاء إدخال رقم بطاقة ائتمان صحيح", + equalTo: "رجاء إدخال نفس القيمة", + extension: "رجاء إدخال ملف بامتداد موافق عليه", + maxlength: $.validator.format( "الحد الأقصى لعدد الحروف هو {0}" ), + minlength: $.validator.format( "الحد الأدنى لعدد الحروف هو {0}" ), + rangelength: $.validator.format( "عدد الحروف يجب أن يكون بين {0} و {1}" ), + range: $.validator.format( "رجاء إدخال عدد قيمته بين {0} و {1}" ), + max: $.validator.format( "رجاء إدخال عدد أقل من أو يساوي {0}" ), + min: $.validator.format( "رجاء إدخال عدد أكبر من أو يساوي {0}" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.min.js new file mode 100644 index 0000000000..146d7edb78 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ar.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هذا الحقل إلزامي",remote:"يرجى تصحيح هذا الحقل للمتابعة",email:"رجاء إدخال عنوان بريد إلكتروني صحيح",url:"رجاء إدخال عنوان موقع إلكتروني صحيح",date:"رجاء إدخال تاريخ صحيح",dateISO:"رجاء إدخال تاريخ صحيح (ISO)",number:"رجاء إدخال عدد بطريقة صحيحة",digits:"رجاء إدخال أرقام فقط",creditcard:"رجاء إدخال رقم بطاقة ائتمان صحيح",equalTo:"رجاء إدخال نفس القيمة",extension:"رجاء إدخال ملف بامتداد موافق عليه",maxlength:a.validator.format("الحد الأقصى لعدد الحروف هو {0}"),minlength:a.validator.format("الحد الأدنى لعدد الحروف هو {0}"),rangelength:a.validator.format("عدد الحروف يجب أن يكون بين {0} و {1}"),range:a.validator.format("رجاء إدخال عدد قيمته بين {0} و {1}"),max:a.validator.format("رجاء إدخال عدد أقل من أو يساوي {0}"),min:a.validator.format("رجاء إدخال عدد أكبر من أو يساوي {0}")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.js new file mode 100644 index 0000000000..3cd9723a5c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: Az (Azeri; azərbaycan dili) + */ +$.extend( $.validator.messages, { + required: "Bu xana mütləq doldurulmalıdır.", + remote: "Zəhmət olmasa, düzgün məna daxil edin.", + email: "Zəhmət olmasa, düzgün elektron poçt daxil edin.", + url: "Zəhmət olmasa, düzgün URL daxil edin.", + date: "Zəhmət olmasa, düzgün tarix daxil edin.", + dateISO: "Zəhmət olmasa, düzgün ISO formatlı tarix daxil edin.", + number: "Zəhmət olmasa, düzgün rəqəm daxil edin.", + digits: "Zəhmət olmasa, yalnız rəqəm daxil edin.", + creditcard: "Zəhmət olmasa, düzgün kredit kart nömrəsini daxil edin.", + equalTo: "Zəhmət olmasa, eyni mənanı bir daha daxil edin.", + extension: "Zəhmət olmasa, düzgün genişlənməyə malik faylı seçin.", + maxlength: $.validator.format( "Zəhmət olmasa, {0} simvoldan çox olmayaraq daxil edin." ), + minlength: $.validator.format( "Zəhmət olmasa, {0} simvoldan az olmayaraq daxil edin." ), + rangelength: $.validator.format( "Zəhmət olmasa, {0} - {1} aralığında uzunluğa malik simvol daxil edin." ), + range: $.validator.format( "Zəhmət olmasa, {0} - {1} aralığında rəqəm daxil edin." ), + max: $.validator.format( "Zəhmət olmasa, {0} və ondan kiçik rəqəm daxil edin." ), + min: $.validator.format( "Zəhmət olmasa, {0} və ondan böyük rəqəm daxil edin" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.min.js new file mode 100644 index 0000000000..e31d25455e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_az.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu xana mütləq doldurulmalıdır.",remote:"Zəhmət olmasa, düzgün məna daxil edin.",email:"Zəhmət olmasa, düzgün elektron poçt daxil edin.",url:"Zəhmət olmasa, düzgün URL daxil edin.",date:"Zəhmət olmasa, düzgün tarix daxil edin.",dateISO:"Zəhmət olmasa, düzgün ISO formatlı tarix daxil edin.",number:"Zəhmət olmasa, düzgün rəqəm daxil edin.",digits:"Zəhmət olmasa, yalnız rəqəm daxil edin.",creditcard:"Zəhmət olmasa, düzgün kredit kart nömrəsini daxil edin.",equalTo:"Zəhmət olmasa, eyni mənanı bir daha daxil edin.",extension:"Zəhmət olmasa, düzgün genişlənməyə malik faylı seçin.",maxlength:a.validator.format("Zəhmət olmasa, {0} simvoldan çox olmayaraq daxil edin."),minlength:a.validator.format("Zəhmət olmasa, {0} simvoldan az olmayaraq daxil edin."),rangelength:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında uzunluğa malik simvol daxil edin."),range:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında rəqəm daxil edin."),max:a.validator.format("Zəhmət olmasa, {0} və ondan kiçik rəqəm daxil edin."),min:a.validator.format("Zəhmət olmasa, {0} və ondan böyük rəqəm daxil edin")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.js new file mode 100644 index 0000000000..c725eeadb5 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: BG (Bulgarian; български език) + */ +$.extend( $.validator.messages, { + required: "Полето е задължително.", + remote: "Моля, въведете правилната стойност.", + email: "Моля, въведете валиден email.", + url: "Моля, въведете валидно URL.", + date: "Моля, въведете валидна дата.", + dateISO: "Моля, въведете валидна дата (ISO).", + number: "Моля, въведете валиден номер.", + digits: "Моля, въведете само цифри.", + creditcard: "Моля, въведете валиден номер на кредитна карта.", + equalTo: "Моля, въведете същата стойност отново.", + extension: "Моля, въведете стойност с валидно разширение.", + maxlength: $.validator.format( "Моля, въведете не повече от {0} символа." ), + minlength: $.validator.format( "Моля, въведете поне {0} символа." ), + rangelength: $.validator.format( "Моля, въведете стойност с дължина между {0} и {1} символа." ), + range: $.validator.format( "Моля, въведете стойност между {0} и {1}." ), + max: $.validator.format( "Моля, въведете стойност по-малка или равна на {0}." ), + min: $.validator.format( "Моля, въведете стойност по-голяма или равна на {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.min.js new file mode 100644 index 0000000000..1ea5fe095d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bg.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задължително.",remote:"Моля, въведете правилната стойност.",email:"Моля, въведете валиден email.",url:"Моля, въведете валидно URL.",date:"Моля, въведете валидна дата.",dateISO:"Моля, въведете валидна дата (ISO).",number:"Моля, въведете валиден номер.",digits:"Моля, въведете само цифри.",creditcard:"Моля, въведете валиден номер на кредитна карта.",equalTo:"Моля, въведете същата стойност отново.",extension:"Моля, въведете стойност с валидно разширение.",maxlength:a.validator.format("Моля, въведете не повече от {0} символа."),minlength:a.validator.format("Моля, въведете поне {0} символа."),rangelength:a.validator.format("Моля, въведете стойност с дължина между {0} и {1} символа."),range:a.validator.format("Моля, въведете стойност между {0} и {1}."),max:a.validator.format("Моля, въведете стойност по-малка или равна на {0}."),min:a.validator.format("Моля, въведете стойност по-голяма или равна на {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.js new file mode 100644 index 0000000000..44c7b6777d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: bn_BD (Bengali, Bangladesh) + */ +$.extend( $.validator.messages, { + required: "এই তথ্যটি আবশ্যক।", + remote: "এই তথ্যটি ঠিক করুন।", + email: "অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।", + url: "অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।", + date: "তারিখ সঠিক নয়।", + dateISO: "অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।", + number: "অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।", + digits: "এখানে শুধু সংখ্যা ব্যবহার করা যাবে।", + creditcard: "অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।", + equalTo: "একই মান আবার লিখুন।", + extension: "সঠিক ধরনের ফাইল আপলোড করুন।", + maxlength: $.validator.format( "{0}টির বেশি অক্ষর লেখা যাবে না।" ), + minlength: $.validator.format( "{0}টির কম অক্ষর লেখা যাবে না।" ), + rangelength: $.validator.format( "{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।" ), + range: $.validator.format( "{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।" ), + max: $.validator.format( "অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।" ), + min: $.validator.format( "অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.min.js new file mode 100644 index 0000000000..c6d336d704 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_bn_BD.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"এই তথ্যটি আবশ্যক।",remote:"এই তথ্যটি ঠিক করুন।",email:"অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।",url:"অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।",date:"তারিখ সঠিক নয়।",dateISO:"অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।",number:"অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।",digits:"এখানে শুধু সংখ্যা ব্যবহার করা যাবে।",creditcard:"অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।",equalTo:"একই মান আবার লিখুন।",extension:"সঠিক ধরনের ফাইল আপলোড করুন।",maxlength:a.validator.format("{0}টির বেশি অক্ষর লেখা যাবে না।"),minlength:a.validator.format("{0}টির কম অক্ষর লেখা যাবে না।"),rangelength:a.validator.format("{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।"),range:a.validator.format("{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।"),max:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।"),min:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.js new file mode 100644 index 0000000000..cd6c59663f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: CA (Catalan; català) + */ +$.extend( $.validator.messages, { + required: "Aquest camp és obligatori.", + remote: "Si us plau, omple aquest camp.", + email: "Si us plau, escriu una adreça de correu-e vàlida", + url: "Si us plau, escriu una URL vàlida.", + date: "Si us plau, escriu una data vàlida.", + dateISO: "Si us plau, escriu una data (ISO) vàlida.", + number: "Si us plau, escriu un número enter vàlid.", + digits: "Si us plau, escriu només dígits.", + creditcard: "Si us plau, escriu un número de tarjeta vàlid.", + equalTo: "Si us plau, escriu el mateix valor de nou.", + extension: "Si us plau, escriu un valor amb una extensió acceptada.", + maxlength: $.validator.format( "Si us plau, no escriguis més de {0} caracters." ), + minlength: $.validator.format( "Si us plau, no escriguis menys de {0} caracters." ), + rangelength: $.validator.format( "Si us plau, escriu un valor entre {0} i {1} caracters." ), + range: $.validator.format( "Si us plau, escriu un valor entre {0} i {1}." ), + max: $.validator.format( "Si us plau, escriu un valor menor o igual a {0}." ), + min: $.validator.format( "Si us plau, escriu un valor major o igual a {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.min.js new file mode 100644 index 0000000000..affe49c71e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ca.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Aquest camp és obligatori.",remote:"Si us plau, omple aquest camp.",email:"Si us plau, escriu una adreça de correu-e vàlida",url:"Si us plau, escriu una URL vàlida.",date:"Si us plau, escriu una data vàlida.",dateISO:"Si us plau, escriu una data (ISO) vàlida.",number:"Si us plau, escriu un número enter vàlid.",digits:"Si us plau, escriu només dígits.",creditcard:"Si us plau, escriu un número de tarjeta vàlid.",equalTo:"Si us plau, escriu el mateix valor de nou.",extension:"Si us plau, escriu un valor amb una extensió acceptada.",maxlength:a.validator.format("Si us plau, no escriguis més de {0} caracters."),minlength:a.validator.format("Si us plau, no escriguis menys de {0} caracters."),rangelength:a.validator.format("Si us plau, escriu un valor entre {0} i {1} caracters."),range:a.validator.format("Si us plau, escriu un valor entre {0} i {1}."),max:a.validator.format("Si us plau, escriu un valor menor o igual a {0}."),min:a.validator.format("Si us plau, escriu un valor major o igual a {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.js new file mode 100644 index 0000000000..2ab4b51668 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.js @@ -0,0 +1,36 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: CS (Czech; čeština, český jazyk) + */ +$.extend( $.validator.messages, { + required: "Tento údaj je povinný.", + remote: "Prosím, opravte tento údaj.", + email: "Prosím, zadejte platný e-mail.", + url: "Prosím, zadejte platné URL.", + date: "Prosím, zadejte platné datum.", + dateISO: "Prosím, zadejte platné datum (ISO).", + number: "Prosím, zadejte číslo.", + digits: "Prosím, zadávejte pouze číslice.", + creditcard: "Prosím, zadejte číslo kreditní karty.", + equalTo: "Prosím, zadejte znovu stejnou hodnotu.", + extension: "Prosím, zadejte soubor se správnou příponou.", + maxlength: $.validator.format( "Prosím, zadejte nejvíce {0} znaků." ), + minlength: $.validator.format( "Prosím, zadejte nejméně {0} znaků." ), + rangelength: $.validator.format( "Prosím, zadejte od {0} do {1} znaků." ), + range: $.validator.format( "Prosím, zadejte hodnotu od {0} do {1}." ), + max: $.validator.format( "Prosím, zadejte hodnotu menší nebo rovnu {0}." ), + min: $.validator.format( "Prosím, zadejte hodnotu větší nebo rovnu {0}." ), + step: $.validator.format( "Musí být násobkem čísla {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.min.js new file mode 100644 index 0000000000..9415db241b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_cs.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Tento údaj je povinný.",remote:"Prosím, opravte tento údaj.",email:"Prosím, zadejte platný e-mail.",url:"Prosím, zadejte platné URL.",date:"Prosím, zadejte platné datum.",dateISO:"Prosím, zadejte platné datum (ISO).",number:"Prosím, zadejte číslo.",digits:"Prosím, zadávejte pouze číslice.",creditcard:"Prosím, zadejte číslo kreditní karty.",equalTo:"Prosím, zadejte znovu stejnou hodnotu.",extension:"Prosím, zadejte soubor se správnou příponou.",maxlength:a.validator.format("Prosím, zadejte nejvíce {0} znaků."),minlength:a.validator.format("Prosím, zadejte nejméně {0} znaků."),rangelength:a.validator.format("Prosím, zadejte od {0} do {1} znaků."),range:a.validator.format("Prosím, zadejte hodnotu od {0} do {1}."),max:a.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."),min:a.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}."),step:a.validator.format("Musí být násobkem čísla {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.js new file mode 100644 index 0000000000..302775c0fb --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.js @@ -0,0 +1,46 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: DA (Danish; dansk) + */ +$.extend( $.validator.messages, { + required: "Dette felt er påkrævet.", + remote: "Ret venligst dette felt", + email: "Indtast en gyldig email-adresse.", + url: "Indtast en gyldig URL.", + date: "Indtast en gyldig dato.", + number: "Indtast et tal.", + digits: "Indtast kun cifre.", + creditcard: "Indtast et gyldigt kreditkortnummer.", + equalTo: "Indtast den samme værdi igen.", + time: "Angiv en gyldig tid mellem kl. 00:00 og 23:59.", + ipv4: "Angiv venligst en gyldig IPv4-adresse.", + ipv6: "Angiv venligst en gyldig IPv6-adresse.", + require_from_group: $.validator.format( "Angiv mindst {0} af disse felter." ), + extension: "Indtast venligst en værdi med en gyldig endelse", + pattern: "Ugyldigt format", + lettersonly: "Angiv venligst kun bogstaver.", + nowhitespace: "Må ikke indholde mellemrum", + maxlength: $.validator.format( "Indtast højst {0} tegn." ), + minlength: $.validator.format( "Indtast mindst {0} tegn." ), + rangelength: $.validator.format( "Indtast mindst {0} og højst {1} tegn." ), + range: $.validator.format( "Angiv en værdi mellem {0} og {1}." ), + max: $.validator.format( "Angiv en værdi der højst er {0}." ), + min: $.validator.format( "Angiv en værdi der mindst er {0}." ), + minWords: $.validator.format( "Indtast venligst mindst {0} ord" ), + maxWords: $.validator.format( "Indtast venligst højst {0} ord" ), + step: $.validator.format( "Angiv en værdi gange {0}." ), + notEqualTo: "Angiv en anden værdi, værdierne må ikke være det samme.", + integer: "Angiv et ikke-decimaltal, der er positivt eller negativt." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.min.js new file mode 100644 index 0000000000..6ddcd487f6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_da.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dette felt er påkrævet.",remote:"Ret venligst dette felt",email:"Indtast en gyldig email-adresse.",url:"Indtast en gyldig URL.",date:"Indtast en gyldig dato.",number:"Indtast et tal.",digits:"Indtast kun cifre.",creditcard:"Indtast et gyldigt kreditkortnummer.",equalTo:"Indtast den samme værdi igen.",time:"Angiv en gyldig tid mellem kl. 00:00 og 23:59.",ipv4:"Angiv venligst en gyldig IPv4-adresse.",ipv6:"Angiv venligst en gyldig IPv6-adresse.",require_from_group:a.validator.format("Angiv mindst {0} af disse felter."),extension:"Indtast venligst en værdi med en gyldig endelse",pattern:"Ugyldigt format",lettersonly:"Angiv venligst kun bogstaver.",nowhitespace:"Må ikke indholde mellemrum",maxlength:a.validator.format("Indtast højst {0} tegn."),minlength:a.validator.format("Indtast mindst {0} tegn."),rangelength:a.validator.format("Indtast mindst {0} og højst {1} tegn."),range:a.validator.format("Angiv en værdi mellem {0} og {1}."),max:a.validator.format("Angiv en værdi der højst er {0}."),min:a.validator.format("Angiv en værdi der mindst er {0}."),minWords:a.validator.format("Indtast venligst mindst {0} ord"),maxWords:a.validator.format("Indtast venligst højst {0} ord"),step:a.validator.format("Angiv en værdi gange {0}."),notEqualTo:"Angiv en anden værdi, værdierne må ikke være det samme.",integer:"Angiv et ikke-decimaltal, der er positivt eller negativt."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.js new file mode 100644 index 0000000000..611c16f71f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.js @@ -0,0 +1,82 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: DE (German, Deutsch) + */ +$.extend( $.validator.messages, { + required: "Dieses Feld ist ein Pflichtfeld.", + maxlength: $.validator.format( "Geben Sie bitte maximal {0} Zeichen ein." ), + minlength: $.validator.format( "Geben Sie bitte mindestens {0} Zeichen ein." ), + rangelength: $.validator.format( "Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein." ), + email: "Geben Sie bitte eine gültige E-Mail-Adresse ein.", + url: "Geben Sie bitte eine gültige URL ein.", + date: "Geben Sie bitte ein gültiges Datum ein.", + number: "Geben Sie bitte eine Nummer ein.", + digits: "Geben Sie bitte nur Ziffern ein.", + equalTo: "Wiederholen Sie bitte denselben Wert.", + range: $.validator.format( "Geben Sie bitte einen Wert zwischen {0} und {1} ein." ), + max: $.validator.format( "Geben Sie bitte einen Wert kleiner oder gleich {0} ein." ), + min: $.validator.format( "Geben Sie bitte einen Wert größer oder gleich {0} ein." ), + creditcard: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein.", + remote: "Korrigieren Sie bitte dieses Feld.", + dateISO: "Geben Sie bitte ein gültiges Datum ein (ISO-Format).", + step: $.validator.format( "Geben Sie bitte ein Vielfaches von {0} ein." ), + maxWords: $.validator.format( "Geben Sie bitte {0} Wörter oder weniger ein." ), + minWords: $.validator.format( "Geben Sie bitte mindestens {0} Wörter ein." ), + rangeWords: $.validator.format( "Geben Sie bitte zwischen {0} und {1} Wörtern ein." ), + accept: "Geben Sie bitte einen Wert mit einem gültigen MIME-Typ ein.", + alphanumeric: "Geben Sie bitte nur Buchstaben (keine Umlaute), Zahlen oder Unterstriche ein.", + bankaccountNL: "Geben Sie bitte eine gültige Kontonummer ein.", + bankorgiroaccountNL: "Geben Sie bitte eine gültige Bank- oder Girokontonummer ein.", + bic: "Geben Sie bitte einen gültigen BIC-Code ein.", + cifES: "Geben Sie bitte eine gültige CIF-Nummer ein.", + cpfBR: "Geben Sie bitte eine gültige CPF-Nummer ein.", + creditcardtypes: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein.", + currency: "Geben Sie bitte eine gültige Währung ein.", + extension: "Geben Sie bitte einen Wert mit einer gültigen Erweiterung ein.", + giroaccountNL: "Geben Sie bitte eine gültige Girokontonummer ein.", + iban: "Geben Sie bitte eine gültige IBAN ein.", + integer: "Geben Sie bitte eine positive oder negative Nicht-Dezimalzahl ein.", + ipv4: "Geben Sie bitte eine gültige IPv4-Adresse ein.", + ipv6: "Geben Sie bitte eine gültige IPv6-Adresse ein.", + lettersonly: "Geben Sie bitte nur Buchstaben ein.", + letterswithbasicpunc: "Geben Sie bitte nur Buchstaben oder Interpunktion ein.", + mobileNL: "Geben Sie bitte eine gültige Handynummer ein.", + mobileUK: "Geben Sie bitte eine gültige Handynummer ein.", + netmask: "Geben Sie bitte eine gültige Netzmaske ein.", + nieES: "Geben Sie bitte eine gültige NIE-Nummer ein.", + nifES: "Geben Sie bitte eine gültige NIF-Nummer ein.", + nipPL: "Geben Sie bitte eine gültige NIP-Nummer ein.", + notEqualTo: "Geben Sie bitte einen anderen Wert ein. Die Werte dürfen nicht gleich sein.", + nowhitespace: "Kein Leerzeichen bitte.", + pattern: "Ungültiges Format.", + phoneNL: "Geben Sie bitte eine gültige Telefonnummer ein.", + phonesUK: "Geben Sie bitte eine gültige britische Telefonnummer ein.", + phoneUK: "Geben Sie bitte eine gültige Telefonnummer ein.", + phoneUS: "Geben Sie bitte eine gültige Telefonnummer ein.", + postalcodeBR: "Geben Sie bitte eine gültige brasilianische Postleitzahl ein.", + postalCodeCA: "Geben Sie bitte eine gültige kanadische Postleitzahl ein.", + postalcodeIT: "Geben Sie bitte eine gültige italienische Postleitzahl ein.", + postalcodeNL: "Geben Sie bitte eine gültige niederländische Postleitzahl ein.", + postcodeUK: "Geben Sie bitte eine gültige britische Postleitzahl ein.", + require_from_group: $.validator.format( "Füllen Sie bitte mindestens {0} dieser Felder aus." ), + skip_or_fill_minimum: $.validator.format( "Überspringen Sie bitte diese Felder oder füllen Sie mindestens {0} von ihnen aus." ), + stateUS: "Geben Sie bitte einen gültigen US-Bundesstaat ein.", + strippedminlength: $.validator.format( "Geben Sie bitte mindestens {0} Zeichen ein." ), + time: "Geben Sie bitte eine gültige Uhrzeit zwischen 00:00 und 23:59 ein.", + time12h: "Geben Sie bitte eine gültige Uhrzeit im 12-Stunden-Format ein.", + vinUS: "Die angegebene Fahrzeugidentifikationsnummer (VIN) ist ungültig.", + zipcodeUS: "Die angegebene US-Postleitzahl ist ungültig.", + ziprange: "Ihre Postleitzahl muss im Bereich 902xx-xxxx bis 905xx-xxxx liegen." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.min.js new file mode 100644 index 0000000000..4e03c22a49 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_de.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dieses Feld ist ein Pflichtfeld.",maxlength:a.validator.format("Geben Sie bitte maximal {0} Zeichen ein."),minlength:a.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),rangelength:a.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."),email:"Geben Sie bitte eine gültige E-Mail-Adresse ein.",url:"Geben Sie bitte eine gültige URL ein.",date:"Geben Sie bitte ein gültiges Datum ein.",number:"Geben Sie bitte eine Nummer ein.",digits:"Geben Sie bitte nur Ziffern ein.",equalTo:"Wiederholen Sie bitte denselben Wert.",range:a.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."),max:a.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."),min:a.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."),creditcard:"Geben Sie bitte eine gültige Kreditkarten-Nummer ein.",remote:"Korrigieren Sie bitte dieses Feld.",dateISO:"Geben Sie bitte ein gültiges Datum ein (ISO-Format).",step:a.validator.format("Geben Sie bitte ein Vielfaches von {0} ein."),maxWords:a.validator.format("Geben Sie bitte {0} Wörter oder weniger ein."),minWords:a.validator.format("Geben Sie bitte mindestens {0} Wörter ein."),rangeWords:a.validator.format("Geben Sie bitte zwischen {0} und {1} Wörtern ein."),accept:"Geben Sie bitte einen Wert mit einem gültigen MIME-Typ ein.",alphanumeric:"Geben Sie bitte nur Buchstaben (keine Umlaute), Zahlen oder Unterstriche ein.",bankaccountNL:"Geben Sie bitte eine gültige Kontonummer ein.",bankorgiroaccountNL:"Geben Sie bitte eine gültige Bank- oder Girokontonummer ein.",bic:"Geben Sie bitte einen gültigen BIC-Code ein.",cifES:"Geben Sie bitte eine gültige CIF-Nummer ein.",cpfBR:"Geben Sie bitte eine gültige CPF-Nummer ein.",creditcardtypes:"Geben Sie bitte eine gültige Kreditkarten-Nummer ein.",currency:"Geben Sie bitte eine gültige Währung ein.",extension:"Geben Sie bitte einen Wert mit einer gültigen Erweiterung ein.",giroaccountNL:"Geben Sie bitte eine gültige Girokontonummer ein.",iban:"Geben Sie bitte eine gültige IBAN ein.",integer:"Geben Sie bitte eine positive oder negative Nicht-Dezimalzahl ein.",ipv4:"Geben Sie bitte eine gültige IPv4-Adresse ein.",ipv6:"Geben Sie bitte eine gültige IPv6-Adresse ein.",lettersonly:"Geben Sie bitte nur Buchstaben ein.",letterswithbasicpunc:"Geben Sie bitte nur Buchstaben oder Interpunktion ein.",mobileNL:"Geben Sie bitte eine gültige Handynummer ein.",mobileUK:"Geben Sie bitte eine gültige Handynummer ein.",netmask:"Geben Sie bitte eine gültige Netzmaske ein.",nieES:"Geben Sie bitte eine gültige NIE-Nummer ein.",nifES:"Geben Sie bitte eine gültige NIF-Nummer ein.",nipPL:"Geben Sie bitte eine gültige NIP-Nummer ein.",notEqualTo:"Geben Sie bitte einen anderen Wert ein. Die Werte dürfen nicht gleich sein.",nowhitespace:"Kein Leerzeichen bitte.",pattern:"Ungültiges Format.",phoneNL:"Geben Sie bitte eine gültige Telefonnummer ein.",phonesUK:"Geben Sie bitte eine gültige britische Telefonnummer ein.",phoneUK:"Geben Sie bitte eine gültige Telefonnummer ein.",phoneUS:"Geben Sie bitte eine gültige Telefonnummer ein.",postalcodeBR:"Geben Sie bitte eine gültige brasilianische Postleitzahl ein.",postalCodeCA:"Geben Sie bitte eine gültige kanadische Postleitzahl ein.",postalcodeIT:"Geben Sie bitte eine gültige italienische Postleitzahl ein.",postalcodeNL:"Geben Sie bitte eine gültige niederländische Postleitzahl ein.",postcodeUK:"Geben Sie bitte eine gültige britische Postleitzahl ein.",require_from_group:a.validator.format("Füllen Sie bitte mindestens {0} dieser Felder aus."),skip_or_fill_minimum:a.validator.format("Überspringen Sie bitte diese Felder oder füllen Sie mindestens {0} von ihnen aus."),stateUS:"Geben Sie bitte einen gültigen US-Bundesstaat ein.",strippedminlength:a.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),time:"Geben Sie bitte eine gültige Uhrzeit zwischen 00:00 und 23:59 ein.",time12h:"Geben Sie bitte eine gültige Uhrzeit im 12-Stunden-Format ein.",vinUS:"Die angegebene Fahrzeugidentifikationsnummer (VIN) ist ungültig.",zipcodeUS:"Die angegebene US-Postleitzahl ist ungültig.",ziprange:"Ihre Postleitzahl muss im Bereich 902xx-xxxx bis 905xx-xxxx liegen."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.js new file mode 100644 index 0000000000..f2dc9e9dcc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: EL (Greek; ελληνικά) + */ +$.extend( $.validator.messages, { + required: "Αυτό το πεδίο είναι υποχρεωτικό.", + remote: "Παρακαλώ διορθώστε αυτό το πεδίο.", + email: "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.", + url: "Παρακαλώ εισάγετε ένα έγκυρο URL.", + date: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.", + dateISO: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).", + number: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό.", + digits: "Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.", + creditcard: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.", + equalTo: "Παρακαλώ εισάγετε την ίδια τιμή ξανά.", + extension: "Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.", + maxlength: $.validator.format( "Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες." ), + minlength: $.validator.format( "Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες." ), + rangelength: $.validator.format( "Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων." ), + range: $.validator.format( "Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}." ), + max: $.validator.format( "Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}." ), + min: $.validator.format( "Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.min.js new file mode 100644 index 0000000000..d3c1b4d7f0 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_el.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Αυτό το πεδίο είναι υποχρεωτικό.",remote:"Παρακαλώ διορθώστε αυτό το πεδίο.",email:"Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.",url:"Παρακαλώ εισάγετε ένα έγκυρο URL.",date:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.",dateISO:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).",number:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό.",digits:"Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.",creditcard:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.",equalTo:"Παρακαλώ εισάγετε την ίδια τιμή ξανά.",extension:"Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.",maxlength:a.validator.format("Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες."),minlength:a.validator.format("Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες."),rangelength:a.validator.format("Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων."),range:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}."),max:a.validator.format("Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}."),min:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.js new file mode 100644 index 0000000000..4829dc23a7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.js @@ -0,0 +1,38 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ES (Spanish; Español) + */ +$.extend( $.validator.messages, { + required: "Este campo es obligatorio.", + remote: "Por favor, rellena este campo.", + email: "Por favor, escribe una dirección de correo válida.", + url: "Por favor, escribe una URL válida.", + date: "Por favor, escribe una fecha válida.", + dateISO: "Por favor, escribe una fecha (ISO) válida.", + number: "Por favor, escribe un número válido.", + digits: "Por favor, escribe sólo dígitos.", + creditcard: "Por favor, escribe un número de tarjeta válido.", + equalTo: "Por favor, escribe el mismo valor de nuevo.", + extension: "Por favor, escribe un valor con una extensión aceptada.", + maxlength: $.validator.format( "Por favor, no escribas más de {0} caracteres." ), + minlength: $.validator.format( "Por favor, no escribas menos de {0} caracteres." ), + rangelength: $.validator.format( "Por favor, escribe un valor entre {0} y {1} caracteres." ), + range: $.validator.format( "Por favor, escribe un valor entre {0} y {1}." ), + max: $.validator.format( "Por favor, escribe un valor menor o igual a {0}." ), + min: $.validator.format( "Por favor, escribe un valor mayor o igual a {0}." ), + nifES: "Por favor, escribe un NIF válido.", + nieES: "Por favor, escribe un NIE válido.", + cifES: "Por favor, escribe un CIF válido." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.min.js new file mode 100644 index 0000000000..ab0bb43dc2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, rellena este campo.",email:"Por favor, escribe una dirección de correo válida.",url:"Por favor, escribe una URL válida.",date:"Por favor, escribe una fecha válida.",dateISO:"Por favor, escribe una fecha (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe sólo dígitos.",creditcard:"Por favor, escribe un número de tarjeta válido.",equalTo:"Por favor, escribe el mismo valor de nuevo.",extension:"Por favor, escribe un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribe un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribe un valor mayor o igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.js new file mode 100644 index 0000000000..aa15bf494e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.js @@ -0,0 +1,39 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ES (Spanish; Español) + * Region: AR (Argentina) + */ +$.extend( $.validator.messages, { + required: "Este campo es obligatorio.", + remote: "Por favor, completá este campo.", + email: "Por favor, escribí una dirección de correo válida.", + url: "Por favor, escribí una URL válida.", + date: "Por favor, escribí una fecha válida.", + dateISO: "Por favor, escribí una fecha (ISO) válida.", + number: "Por favor, escribí un número entero válido.", + digits: "Por favor, escribí sólo dígitos.", + creditcard: "Por favor, escribí un número de tarjeta válido.", + equalTo: "Por favor, escribí el mismo valor de nuevo.", + extension: "Por favor, escribí un valor con una extensión aceptada.", + maxlength: $.validator.format( "Por favor, no escribas más de {0} caracteres." ), + minlength: $.validator.format( "Por favor, no escribas menos de {0} caracteres." ), + rangelength: $.validator.format( "Por favor, escribí un valor entre {0} y {1} caracteres." ), + range: $.validator.format( "Por favor, escribí un valor entre {0} y {1}." ), + max: $.validator.format( "Por favor, escribí un valor menor o igual a {0}." ), + min: $.validator.format( "Por favor, escribí un valor mayor o igual a {0}." ), + nifES: "Por favor, escribí un NIF válido.", + nieES: "Por favor, escribí un NIE válido.", + cifES: "Por favor, escribí un CIF válido." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.min.js new file mode 100644 index 0000000000..12996ac5c7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_AR.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, completá este campo.",email:"Por favor, escribí una dirección de correo válida.",url:"Por favor, escribí una URL válida.",date:"Por favor, escribí una fecha válida.",dateISO:"Por favor, escribí una fecha (ISO) válida.",number:"Por favor, escribí un número entero válido.",digits:"Por favor, escribí sólo dígitos.",creditcard:"Por favor, escribí un número de tarjeta válido.",equalTo:"Por favor, escribí el mismo valor de nuevo.",extension:"Por favor, escribí un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribí un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribí un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribí un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribí un valor mayor o igual a {0}."),nifES:"Por favor, escribí un NIF válido.",nieES:"Por favor, escribí un NIE válido.",cifES:"Por favor, escribí un CIF válido."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.js new file mode 100644 index 0000000000..1d9e388273 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.js @@ -0,0 +1,39 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ES (Spanish; Español) + * Region: PE (Perú) + */ +$.extend( $.validator.messages, { + required: "Este campo es obligatorio.", + remote: "Por favor, llene este campo.", + email: "Por favor, escriba un correo electrónico válido.", + url: "Por favor, escriba una URL válida.", + date: "Por favor, escriba una fecha válida.", + dateISO: "Por favor, escriba una fecha (ISO) válida.", + number: "Por favor, escriba un número válido.", + digits: "Por favor, escriba sólo dígitos.", + creditcard: "Por favor, escriba un número de tarjeta válido.", + equalTo: "Por favor, escriba el mismo valor de nuevo.", + extension: "Por favor, escriba un valor con una extensión permitida.", + maxlength: $.validator.format( "Por favor, no escriba más de {0} caracteres." ), + minlength: $.validator.format( "Por favor, no escriba menos de {0} caracteres." ), + rangelength: $.validator.format( "Por favor, escriba un valor entre {0} y {1} caracteres." ), + range: $.validator.format( "Por favor, escriba un valor entre {0} y {1}." ), + max: $.validator.format( "Por favor, escriba un valor menor o igual a {0}." ), + min: $.validator.format( "Por favor, escriba un valor mayor o igual a {0}." ), + nifES: "Por favor, escriba un NIF válido.", + nieES: "Por favor, escriba un NIE válido.", + cifES: "Por favor, escriba un CIF válido." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.min.js new file mode 100644 index 0000000000..5cfe40db72 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_es_PE.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, llene este campo.",email:"Por favor, escriba un correo electrónico válido.",url:"Por favor, escriba una URL válida.",date:"Por favor, escriba una fecha válida.",dateISO:"Por favor, escriba una fecha (ISO) válida.",number:"Por favor, escriba un número válido.",digits:"Por favor, escriba sólo dígitos.",creditcard:"Por favor, escriba un número de tarjeta válido.",equalTo:"Por favor, escriba el mismo valor de nuevo.",extension:"Por favor, escriba un valor con una extensión permitida.",maxlength:a.validator.format("Por favor, no escriba más de {0} caracteres."),minlength:a.validator.format("Por favor, no escriba menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escriba un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escriba un valor entre {0} y {1}."),max:a.validator.format("Por favor, escriba un valor menor o igual a {0}."),min:a.validator.format("Por favor, escriba un valor mayor o igual a {0}."),nifES:"Por favor, escriba un NIF válido.",nieES:"Por favor, escriba un NIE válido.",cifES:"Por favor, escriba un CIF válido."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.js new file mode 100644 index 0000000000..3fc27885d2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.js @@ -0,0 +1,33 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ET (Estonian; eesti, eesti keel) + */ +$.extend( $.validator.messages, { + required: "See väli peab olema täidetud.", + maxlength: $.validator.format( "Palun sisestage vähem kui {0} tähemärki." ), + minlength: $.validator.format( "Palun sisestage vähemalt {0} tähemärki." ), + rangelength: $.validator.format( "Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki." ), + email: "Palun sisestage korrektne e-maili aadress.", + url: "Palun sisestage korrektne URL.", + date: "Palun sisestage korrektne kuupäev.", + dateISO: "Palun sisestage korrektne kuupäev (YYYY-MM-DD).", + number: "Palun sisestage korrektne number.", + digits: "Palun sisestage ainult numbreid.", + equalTo: "Palun sisestage sama väärtus uuesti.", + range: $.validator.format( "Palun sisestage väärtus vahemikus {0} kuni {1}." ), + max: $.validator.format( "Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}." ), + min: $.validator.format( "Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}." ), + creditcard: "Palun sisestage korrektne krediitkaardi number." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.min.js new file mode 100644 index 0000000000..f5e7fe9905 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_et.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"See väli peab olema täidetud.",maxlength:a.validator.format("Palun sisestage vähem kui {0} tähemärki."),minlength:a.validator.format("Palun sisestage vähemalt {0} tähemärki."),rangelength:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki."),email:"Palun sisestage korrektne e-maili aadress.",url:"Palun sisestage korrektne URL.",date:"Palun sisestage korrektne kuupäev.",dateISO:"Palun sisestage korrektne kuupäev (YYYY-MM-DD).",number:"Palun sisestage korrektne number.",digits:"Palun sisestage ainult numbreid.",equalTo:"Palun sisestage sama väärtus uuesti.",range:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1}."),max:a.validator.format("Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}."),min:a.validator.format("Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}."),creditcard:"Palun sisestage korrektne krediitkaardi number."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.js new file mode 100644 index 0000000000..6a36df851f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: EU (Basque; euskara, euskera) + */ +$.extend( $.validator.messages, { + required: "Eremu hau beharrezkoa da.", + remote: "Mesedez, bete eremu hau.", + email: "Mesedez, idatzi baliozko posta helbide bat.", + url: "Mesedez, idatzi baliozko URL bat.", + date: "Mesedez, idatzi baliozko data bat.", + dateISO: "Mesedez, idatzi baliozko (ISO) data bat.", + number: "Mesedez, idatzi baliozko zenbaki oso bat.", + digits: "Mesedez, idatzi digituak soilik.", + creditcard: "Mesedez, idatzi baliozko txartel zenbaki bat.", + equalTo: "Mesedez, idatzi berdina berriro ere.", + extension: "Mesedez, idatzi onartutako luzapena duen balio bat.", + maxlength: $.validator.format( "Mesedez, ez idatzi {0} karaktere baino gehiago." ), + minlength: $.validator.format( "Mesedez, ez idatzi {0} karaktere baino gutxiago." ), + rangelength: $.validator.format( "Mesedez, idatzi {0} eta {1} karaktere arteko balio bat." ), + range: $.validator.format( "Mesedez, idatzi {0} eta {1} arteko balio bat." ), + max: $.validator.format( "Mesedez, idatzi {0} edo txikiagoa den balio bat." ), + min: $.validator.format( "Mesedez, idatzi {0} edo handiagoa den balio bat." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.min.js new file mode 100644 index 0000000000..a172876dcd --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_eu.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Eremu hau beharrezkoa da.",remote:"Mesedez, bete eremu hau.",email:"Mesedez, idatzi baliozko posta helbide bat.",url:"Mesedez, idatzi baliozko URL bat.",date:"Mesedez, idatzi baliozko data bat.",dateISO:"Mesedez, idatzi baliozko (ISO) data bat.",number:"Mesedez, idatzi baliozko zenbaki oso bat.",digits:"Mesedez, idatzi digituak soilik.",creditcard:"Mesedez, idatzi baliozko txartel zenbaki bat.",equalTo:"Mesedez, idatzi berdina berriro ere.",extension:"Mesedez, idatzi onartutako luzapena duen balio bat.",maxlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gehiago."),minlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gutxiago."),rangelength:a.validator.format("Mesedez, idatzi {0} eta {1} karaktere arteko balio bat."),range:a.validator.format("Mesedez, idatzi {0} eta {1} arteko balio bat."),max:a.validator.format("Mesedez, idatzi {0} edo txikiagoa den balio bat."),min:a.validator.format("Mesedez, idatzi {0} edo handiagoa den balio bat.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.js new file mode 100644 index 0000000000..0f5283b34a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.js @@ -0,0 +1,39 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: FA (Persian; فارسی) + */ +$.extend( $.validator.messages, { + required: "تکمیل این فیلد اجباری است.", + remote: "لطفا این فیلد را تصحیح کنید.", + email: "لطفا یک ایمیل صحیح وارد کنید.", + url: "لطفا آدرس صحیح وارد کنید.", + date: "لطفا تاریخ صحیح وارد کنید.", + dateFA: "لطفا یک تاریخ صحیح وارد کنید.", + dateISO: "لطفا تاریخ صحیح وارد کنید (ISO).", + number: "لطفا عدد صحیح وارد کنید.", + digits: "لطفا تنها رقم وارد کنید.", + creditcard: "لطفا کریدیت کارت صحیح وارد کنید.", + equalTo: "لطفا مقدار برابری وارد کنید.", + extension: "لطفا مقداری وارد کنید که", + alphanumeric: "لطفا مقدار را عدد (انگلیسی) وارد کنید.", + maxlength: $.validator.format( "لطفا بیشتر از {0} حرف وارد نکنید." ), + minlength: $.validator.format( "لطفا کمتر از {0} حرف وارد نکنید." ), + rangelength: $.validator.format( "لطفا مقداری بین {0} تا {1} حرف وارد کنید." ), + range: $.validator.format( "لطفا مقداری بین {0} تا {1} حرف وارد کنید." ), + max: $.validator.format( "لطفا مقداری کمتر از {0} وارد کنید." ), + min: $.validator.format( "لطفا مقداری بیشتر از {0} وارد کنید." ), + minWords: $.validator.format( "لطفا حداقل {0} کلمه وارد کنید." ), + maxWords: $.validator.format( "لطفا حداکثر {0} کلمه وارد کنید." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.min.js new file mode 100644 index 0000000000..eb1549a27a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fa.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"تکمیل این فیلد اجباری است.",remote:"لطفا این فیلد را تصحیح کنید.",email:"لطفا یک ایمیل صحیح وارد کنید.",url:"لطفا آدرس صحیح وارد کنید.",date:"لطفا تاریخ صحیح وارد کنید.",dateFA:"لطفا یک تاریخ صحیح وارد کنید.",dateISO:"لطفا تاریخ صحیح وارد کنید (ISO).",number:"لطفا عدد صحیح وارد کنید.",digits:"لطفا تنها رقم وارد کنید.",creditcard:"لطفا کریدیت کارت صحیح وارد کنید.",equalTo:"لطفا مقدار برابری وارد کنید.",extension:"لطفا مقداری وارد کنید که",alphanumeric:"لطفا مقدار را عدد (انگلیسی) وارد کنید.",maxlength:a.validator.format("لطفا بیشتر از {0} حرف وارد نکنید."),minlength:a.validator.format("لطفا کمتر از {0} حرف وارد نکنید."),rangelength:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),range:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),max:a.validator.format("لطفا مقداری کمتر از {0} وارد کنید."),min:a.validator.format("لطفا مقداری بیشتر از {0} وارد کنید."),minWords:a.validator.format("لطفا حداقل {0} کلمه وارد کنید."),maxWords:a.validator.format("لطفا حداکثر {0} کلمه وارد کنید.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.js new file mode 100644 index 0000000000..ab5887b072 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.js @@ -0,0 +1,33 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: FI (Finnish; suomi, suomen kieli) + */ +$.extend( $.validator.messages, { + required: "Tämä kenttä on pakollinen.", + email: "Syötä oikea sähköpostiosoite.", + url: "Syötä oikea URL-osoite.", + date: "Syötä oikea päivämäärä.", + dateISO: "Syötä oikea päivämäärä muodossa VVVV-KK-PP.", + number: "Syötä luku.", + creditcard: "Syötä voimassa oleva luottokorttinumero.", + digits: "Syötä pelkästään numeroita.", + equalTo: "Syötä sama arvo uudestaan.", + maxlength: $.validator.format( "Voit syöttää enintään {0} merkkiä." ), + minlength: $.validator.format( "Vähintään {0} merkkiä." ), + rangelength: $.validator.format( "Syötä vähintään {0} ja enintään {1} merkkiä." ), + range: $.validator.format( "Syötä arvo väliltä {0}–{1}." ), + max: $.validator.format( "Syötä arvo, joka on enintään {0}." ), + min: $.validator.format( "Syötä arvo, joka on vähintään {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.min.js new file mode 100644 index 0000000000..fb2a331816 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fi.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Tämä kenttä on pakollinen.",email:"Syötä oikea sähköpostiosoite.",url:"Syötä oikea URL-osoite.",date:"Syötä oikea päivämäärä.",dateISO:"Syötä oikea päivämäärä muodossa VVVV-KK-PP.",number:"Syötä luku.",creditcard:"Syötä voimassa oleva luottokorttinumero.",digits:"Syötä pelkästään numeroita.",equalTo:"Syötä sama arvo uudestaan.",maxlength:a.validator.format("Voit syöttää enintään {0} merkkiä."),minlength:a.validator.format("Vähintään {0} merkkiä."),rangelength:a.validator.format("Syötä vähintään {0} ja enintään {1} merkkiä."),range:a.validator.format("Syötä arvo väliltä {0}–{1}."),max:a.validator.format("Syötä arvo, joka on enintään {0}."),min:a.validator.format("Syötä arvo, joka on vähintään {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.js new file mode 100644 index 0000000000..e9f18364fe --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.js @@ -0,0 +1,63 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: FR (French; français) + */ +$.extend( $.validator.messages, { + required: "Ce champ est obligatoire.", + remote: "Veuillez corriger ce champ.", + email: "Veuillez fournir une adresse électronique valide.", + url: "Veuillez fournir une adresse URL valide.", + date: "Veuillez fournir une date valide.", + dateISO: "Veuillez fournir une date valide (ISO).", + number: "Veuillez fournir un numéro valide.", + digits: "Veuillez fournir seulement des chiffres.", + creditcard: "Veuillez fournir un numéro de carte de crédit valide.", + equalTo: "Veuillez fournir encore la même valeur.", + notEqualTo: "Veuillez fournir une valeur différente, les valeurs ne doivent pas être identiques.", + extension: "Veuillez fournir une valeur avec une extension valide.", + maxlength: $.validator.format( "Veuillez fournir au plus {0} caractères." ), + minlength: $.validator.format( "Veuillez fournir au moins {0} caractères." ), + rangelength: $.validator.format( "Veuillez fournir une valeur qui contient entre {0} et {1} caractères." ), + range: $.validator.format( "Veuillez fournir une valeur entre {0} et {1}." ), + max: $.validator.format( "Veuillez fournir une valeur inférieure ou égale à {0}." ), + min: $.validator.format( "Veuillez fournir une valeur supérieure ou égale à {0}." ), + step: $.validator.format( "Veuillez fournir une valeur multiple de {0}." ), + maxWords: $.validator.format( "Veuillez fournir au plus {0} mots." ), + minWords: $.validator.format( "Veuillez fournir au moins {0} mots." ), + rangeWords: $.validator.format( "Veuillez fournir entre {0} et {1} mots." ), + letterswithbasicpunc: "Veuillez fournir seulement des lettres et des signes de ponctuation.", + alphanumeric: "Veuillez fournir seulement des lettres, nombres, espaces et soulignages.", + lettersonly: "Veuillez fournir seulement des lettres.", + nowhitespace: "Veuillez ne pas inscrire d'espaces blancs.", + ziprange: "Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.", + integer: "Veuillez fournir un nombre non décimal qui est positif ou négatif.", + vinUS: "Veuillez fournir un numéro d'identification du véhicule (VIN).", + dateITA: "Veuillez fournir une date valide.", + time: "Veuillez fournir une heure valide entre 00:00 et 23:59.", + phoneUS: "Veuillez fournir un numéro de téléphone valide.", + phoneUK: "Veuillez fournir un numéro de téléphone valide.", + mobileUK: "Veuillez fournir un numéro de téléphone mobile valide.", + strippedminlength: $.validator.format( "Veuillez fournir au moins {0} caractères." ), + email2: "Veuillez fournir une adresse électronique valide.", + url2: "Veuillez fournir une adresse URL valide.", + creditcardtypes: "Veuillez fournir un numéro de carte de crédit valide.", + ipv4: "Veuillez fournir une adresse IP v4 valide.", + ipv6: "Veuillez fournir une adresse IP v6 valide.", + require_from_group: $.validator.format( "Veuillez fournir au moins {0} de ces champs." ), + nifES: "Veuillez fournir un numéro NIF valide.", + nieES: "Veuillez fournir un numéro NIE valide.", + cifES: "Veuillez fournir un numéro CIF valide.", + postalCodeCA: "Veuillez fournir un code postal valide." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.min.js new file mode 100644 index 0000000000..99d3a53f20 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_fr.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ce champ est obligatoire.",remote:"Veuillez corriger ce champ.",email:"Veuillez fournir une adresse électronique valide.",url:"Veuillez fournir une adresse URL valide.",date:"Veuillez fournir une date valide.",dateISO:"Veuillez fournir une date valide (ISO).",number:"Veuillez fournir un numéro valide.",digits:"Veuillez fournir seulement des chiffres.",creditcard:"Veuillez fournir un numéro de carte de crédit valide.",equalTo:"Veuillez fournir encore la même valeur.",notEqualTo:"Veuillez fournir une valeur différente, les valeurs ne doivent pas être identiques.",extension:"Veuillez fournir une valeur avec une extension valide.",maxlength:a.validator.format("Veuillez fournir au plus {0} caractères."),minlength:a.validator.format("Veuillez fournir au moins {0} caractères."),rangelength:a.validator.format("Veuillez fournir une valeur qui contient entre {0} et {1} caractères."),range:a.validator.format("Veuillez fournir une valeur entre {0} et {1}."),max:a.validator.format("Veuillez fournir une valeur inférieure ou égale à {0}."),min:a.validator.format("Veuillez fournir une valeur supérieure ou égale à {0}."),step:a.validator.format("Veuillez fournir une valeur multiple de {0}."),maxWords:a.validator.format("Veuillez fournir au plus {0} mots."),minWords:a.validator.format("Veuillez fournir au moins {0} mots."),rangeWords:a.validator.format("Veuillez fournir entre {0} et {1} mots."),letterswithbasicpunc:"Veuillez fournir seulement des lettres et des signes de ponctuation.",alphanumeric:"Veuillez fournir seulement des lettres, nombres, espaces et soulignages.",lettersonly:"Veuillez fournir seulement des lettres.",nowhitespace:"Veuillez ne pas inscrire d'espaces blancs.",ziprange:"Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.",integer:"Veuillez fournir un nombre non décimal qui est positif ou négatif.",vinUS:"Veuillez fournir un numéro d'identification du véhicule (VIN).",dateITA:"Veuillez fournir une date valide.",time:"Veuillez fournir une heure valide entre 00:00 et 23:59.",phoneUS:"Veuillez fournir un numéro de téléphone valide.",phoneUK:"Veuillez fournir un numéro de téléphone valide.",mobileUK:"Veuillez fournir un numéro de téléphone mobile valide.",strippedminlength:a.validator.format("Veuillez fournir au moins {0} caractères."),email2:"Veuillez fournir une adresse électronique valide.",url2:"Veuillez fournir une adresse URL valide.",creditcardtypes:"Veuillez fournir un numéro de carte de crédit valide.",ipv4:"Veuillez fournir une adresse IP v4 valide.",ipv6:"Veuillez fournir une adresse IP v6 valide.",require_from_group:a.validator.format("Veuillez fournir au moins {0} de ces champs."),nifES:"Veuillez fournir un numéro NIF valide.",nieES:"Veuillez fournir un numéro NIE valide.",cifES:"Veuillez fournir un numéro CIF valide.",postalCodeCA:"Veuillez fournir un code postal valide."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.js new file mode 100644 index 0000000000..61b6e241e6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/** + * @author @tatocaster + * Translated default messages for the jQuery validation plugin. + * Locale: GE (Georgian; ქართული) + */ +$.extend( $.validator.messages, { + required: "ეს ველი სავალდებულოა", + remote: "გთხოვთ შეასწოროთ.", + email: "გთხოვთ შეიყვანოთ სწორი ფორმატით.", + url: "გთხოვთ შეიყვანოთ სწორი ფორმატით.", + date: "გთხოვთ შეიყვანოთ სწორი თარიღი.", + dateISO: "გთხოვთ შეიყვანოთ სწორი ფორმატით (ISO).", + number: "გთხოვთ შეიყვანოთ რიცხვი.", + digits: "დაშვებულია მხოლოდ ციფრები.", + creditcard: "გთხოვთ შეიყვანოთ სწორი ფორმატის ბარათის კოდი.", + equalTo: "გთხოვთ შეიყვანოთ იგივე მნიშვნელობა.", + maxlength: $.validator.format( "გთხოვთ შეიყვანოთ არა უმეტეს {0} სიმბოლოსი." ), + minlength: $.validator.format( "შეიყვანეთ მინიმუმ {0} სიმბოლო." ), + rangelength: $.validator.format( "გთხოვთ შეიყვანოთ {0} -დან {1} -მდე რაოდენობის სიმბოლოები." ), + range: $.validator.format( "შეიყვანეთ {0} -სა {1} -ს შორის." ), + max: $.validator.format( "გთხოვთ შეიყვანოთ მნიშვნელობა ნაკლები ან ტოლი {0} -ს." ), + min: $.validator.format( "გთხოვთ შეიყვანოთ მნიშვნელობა მეტი ან ტოლი {0} -ს." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.min.js new file mode 100644 index 0000000000..456c6da8f1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ge.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ეს ველი სავალდებულოა",remote:"გთხოვთ შეასწოროთ.",email:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",url:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",date:"გთხოვთ შეიყვანოთ სწორი თარიღი.",dateISO:"გთხოვთ შეიყვანოთ სწორი ფორმატით (ISO).",number:"გთხოვთ შეიყვანოთ რიცხვი.",digits:"დაშვებულია მხოლოდ ციფრები.",creditcard:"გთხოვთ შეიყვანოთ სწორი ფორმატის ბარათის კოდი.",equalTo:"გთხოვთ შეიყვანოთ იგივე მნიშვნელობა.",maxlength:a.validator.format("გთხოვთ შეიყვანოთ არა უმეტეს {0} სიმბოლოსი."),minlength:a.validator.format("შეიყვანეთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("გთხოვთ შეიყვანოთ {0} -დან {1} -მდე რაოდენობის სიმბოლოები."),range:a.validator.format("შეიყვანეთ {0} -სა {1} -ს შორის."),max:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა ნაკლები ან ტოლი {0} -ს."),min:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა მეტი ან ტოლი {0} -ს.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.js new file mode 100644 index 0000000000..0503617139 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.js @@ -0,0 +1,40 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: GL (Galician; Galego) + */ +( function( $ ) { + $.extend( $.validator.messages, { + required: "Este campo é obrigatorio.", + remote: "Por favor, cubre este campo.", + email: "Por favor, escribe unha dirección de correo válida.", + url: "Por favor, escribe unha URL válida.", + date: "Por favor, escribe unha data válida.", + dateISO: "Por favor, escribe unha data (ISO) válida.", + number: "Por favor, escribe un número válido.", + digits: "Por favor, escribe só díxitos.", + creditcard: "Por favor, escribe un número de tarxeta válido.", + equalTo: "Por favor, escribe o mesmo valor de novo.", + extension: "Por favor, escribe un valor cunha extensión aceptada.", + maxlength: $.validator.format( "Por favor, non escribas máis de {0} caracteres." ), + minlength: $.validator.format( "Por favor, non escribas menos de {0} caracteres." ), + rangelength: $.validator.format( "Por favor, escribe un valor entre {0} e {1} caracteres." ), + range: $.validator.format( "Por favor, escribe un valor entre {0} e {1}." ), + max: $.validator.format( "Por favor, escribe un valor menor ou igual a {0}." ), + min: $.validator.format( "Por favor, escribe un valor maior ou igual a {0}." ), + nifES: "Por favor, escribe un NIF válido.", + nieES: "Por favor, escribe un NIE válido.", + cifES: "Por favor, escribe un CIF válido." + } ); +}( jQuery ) ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.min.js new file mode 100644 index 0000000000..77eac5ffdf --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_gl.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(a){a.extend(a.validator.messages,{required:"Este campo é obrigatorio.",remote:"Por favor, cubre este campo.",email:"Por favor, escribe unha dirección de correo válida.",url:"Por favor, escribe unha URL válida.",date:"Por favor, escribe unha data válida.",dateISO:"Por favor, escribe unha data (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe só díxitos.",creditcard:"Por favor, escribe un número de tarxeta válido.",equalTo:"Por favor, escribe o mesmo valor de novo.",extension:"Por favor, escribe un valor cunha extensión aceptada.",maxlength:a.validator.format("Por favor, non escribas máis de {0} caracteres."),minlength:a.validator.format("Por favor, non escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} e {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} e {1}."),max:a.validator.format("Por favor, escribe un valor menor ou igual a {0}."),min:a.validator.format("Por favor, escribe un valor maior ou igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."})}(jQuery),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.js new file mode 100644 index 0000000000..cb84b56a26 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: HE (Hebrew; עברית) + */ +$.extend( $.validator.messages, { + required: "השדה הזה הינו שדה חובה", + remote: "נא לתקן שדה זה", + email: "נא למלא כתובת דוא\"ל חוקית", + url: "נא למלא כתובת אינטרנט חוקית", + date: "נא למלא תאריך חוקי", + dateISO: "נא למלא תאריך חוקי (ISO)", + number: "נא למלא מספר", + digits: "נא למלא רק מספרים", + creditcard: "נא למלא מספר כרטיס אשראי חוקי", + equalTo: "נא למלא את אותו ערך שוב", + extension: "נא למלא ערך עם סיומת חוקית", + maxlength: $.validator.format( ".נא לא למלא יותר מ- {0} תווים" ), + minlength: $.validator.format( "נא למלא לפחות {0} תווים" ), + rangelength: $.validator.format( "נא למלא ערך בין {0} ל- {1} תווים" ), + range: $.validator.format( "נא למלא ערך בין {0} ל- {1}" ), + max: $.validator.format( "נא למלא ערך קטן או שווה ל- {0}" ), + min: $.validator.format( "נא למלא ערך גדול או שווה ל- {0}" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.min.js new file mode 100644 index 0000000000..381e1079eb --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_he.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"השדה הזה הינו שדה חובה",remote:"נא לתקן שדה זה",email:'נא למלא כתובת דוא"ל חוקית',url:"נא למלא כתובת אינטרנט חוקית",date:"נא למלא תאריך חוקי",dateISO:"נא למלא תאריך חוקי (ISO)",number:"נא למלא מספר",digits:"נא למלא רק מספרים",creditcard:"נא למלא מספר כרטיס אשראי חוקי",equalTo:"נא למלא את אותו ערך שוב",extension:"נא למלא ערך עם סיומת חוקית",maxlength:a.validator.format(".נא לא למלא יותר מ- {0} תווים"),minlength:a.validator.format("נא למלא לפחות {0} תווים"),rangelength:a.validator.format("נא למלא ערך בין {0} ל- {1} תווים"),range:a.validator.format("נא למלא ערך בין {0} ל- {1}"),max:a.validator.format("נא למלא ערך קטן או שווה ל- {0}"),min:a.validator.format("נא למלא ערך גדול או שווה ל- {0}")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.js new file mode 100644 index 0000000000..092506dbef --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: HR (Croatia; hrvatski jezik) + */ +$.extend( $.validator.messages, { + required: "Ovo polje je obavezno.", + remote: "Ovo polje treba popraviti.", + email: "Unesite ispravnu e-mail adresu.", + url: "Unesite ispravan URL.", + date: "Unesite ispravan datum.", + dateISO: "Unesite ispravan datum (ISO).", + number: "Unesite ispravan broj.", + digits: "Unesite samo brojeve.", + creditcard: "Unesite ispravan broj kreditne kartice.", + equalTo: "Unesite ponovo istu vrijednost.", + extension: "Unesite vrijednost sa ispravnom ekstenzijom.", + maxlength: $.validator.format( "Maksimalni broj znakova je {0} ." ), + minlength: $.validator.format( "Minimalni broj znakova je {0} ." ), + rangelength: $.validator.format( "Unesite vrijednost između {0} i {1} znakova." ), + range: $.validator.format( "Unesite vrijednost između {0} i {1}." ), + max: $.validator.format( "Unesite vrijednost manju ili jednaku {0}." ), + min: $.validator.format( "Unesite vrijednost veću ili jednaku {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.min.js new file mode 100644 index 0000000000..ee2b757297 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hr.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ovo polje je obavezno.",remote:"Ovo polje treba popraviti.",email:"Unesite ispravnu e-mail adresu.",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo brojeve.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite ponovo istu vrijednost.",extension:"Unesite vrijednost sa ispravnom ekstenzijom.",maxlength:a.validator.format("Maksimalni broj znakova je {0} ."),minlength:a.validator.format("Minimalni broj znakova je {0} ."),rangelength:a.validator.format("Unesite vrijednost između {0} i {1} znakova."),range:a.validator.format("Unesite vrijednost između {0} i {1}."),max:a.validator.format("Unesite vrijednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrijednost veću ili jednaku {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.js new file mode 100644 index 0000000000..616ae251c9 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: HU (Hungarian; Magyar) + */ +$.extend( $.validator.messages, { + required: "Kötelező megadni.", + maxlength: $.validator.format( "Legfeljebb {0} karakter hosszú legyen." ), + minlength: $.validator.format( "Legalább {0} karakter hosszú legyen." ), + rangelength: $.validator.format( "Legalább {0} és legfeljebb {1} karakter hosszú legyen." ), + email: "Érvényes e-mail címnek kell lennie.", + url: "Érvényes URL-nek kell lennie.", + date: "Dátumnak kell lennie.", + number: "Számnak kell lennie.", + digits: "Csak számjegyek lehetnek.", + equalTo: "Meg kell egyeznie a két értéknek.", + range: $.validator.format( "{0} és {1} közé kell esnie." ), + max: $.validator.format( "Nem lehet nagyobb, mint {0}." ), + min: $.validator.format( "Nem lehet kisebb, mint {0}." ), + creditcard: "Érvényes hitelkártyaszámnak kell lennie.", + remote: "Kérem javítsa ki ezt a mezőt.", + dateISO: "Kérem írjon be egy érvényes dátumot (ISO).", + step: $.validator.format( "A {0} egyik többszörösét adja meg." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.min.js new file mode 100644 index 0000000000..ea2cbcd67f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hu.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kötelező megadni.",maxlength:a.validator.format("Legfeljebb {0} karakter hosszú legyen."),minlength:a.validator.format("Legalább {0} karakter hosszú legyen."),rangelength:a.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."),email:"Érvényes e-mail címnek kell lennie.",url:"Érvényes URL-nek kell lennie.",date:"Dátumnak kell lennie.",number:"Számnak kell lennie.",digits:"Csak számjegyek lehetnek.",equalTo:"Meg kell egyeznie a két értéknek.",range:a.validator.format("{0} és {1} közé kell esnie."),max:a.validator.format("Nem lehet nagyobb, mint {0}."),min:a.validator.format("Nem lehet kisebb, mint {0}."),creditcard:"Érvényes hitelkártyaszámnak kell lennie.",remote:"Kérem javítsa ki ezt a mezőt.",dateISO:"Kérem írjon be egy érvényes dátumot (ISO).",step:a.validator.format("A {0} egyik többszörösét adja meg.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.js new file mode 100644 index 0000000000..c6aec5c331 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: HY_AM (Armenian; հայերեն լեզու) + */ +$.extend( $.validator.messages, { + required: "Պարտադիր լրացման դաշտ", + remote: "Ներմուծեք ճիշտ արժեքը", + email: "Ներմուծեք վավեր էլեկտրոնային փոստի հասցե", + url: "Ներմուծեք վավեր URL", + date: "Ներմուծեք վավեր ամսաթիվ", + dateISO: "Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։", + number: "Ներմուծեք թիվ", + digits: "Ներմուծեք միայն թվեր", + creditcard: "Ներմուծեք ճիշտ բանկային քարտի համար", + equalTo: "Ներմուծեք միևնուն արժեքը ևս մեկ անգամ", + extension: "Ընտրեք ճիշտ ընդլանումով ֆայլ", + maxlength: $.validator.format( "Ներմուծեք ոչ ավել քան {0} նիշ" ), + minlength: $.validator.format( "Ներմուծեք ոչ պակաս քան {0} նիշ" ), + rangelength: $.validator.format( "Ներմուծեք {0}֊ից {1} երկարությամբ արժեք" ), + range: $.validator.format( "Ներմուծեք թիվ {0}֊ից {1} միջակայքում" ), + max: $.validator.format( "Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին" ), + min: $.validator.format( "Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.min.js new file mode 100644 index 0000000000..01d6e02454 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_hy_AM.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Պարտադիր լրացման դաշտ",remote:"Ներմուծեք ճիշտ արժեքը",email:"Ներմուծեք վավեր էլեկտրոնային փոստի հասցե",url:"Ներմուծեք վավեր URL",date:"Ներմուծեք վավեր ամսաթիվ",dateISO:"Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։",number:"Ներմուծեք թիվ",digits:"Ներմուծեք միայն թվեր",creditcard:"Ներմուծեք ճիշտ բանկային քարտի համար",equalTo:"Ներմուծեք միևնուն արժեքը ևս մեկ անգամ",extension:"Ընտրեք ճիշտ ընդլանումով ֆայլ",maxlength:a.validator.format("Ներմուծեք ոչ ավել քան {0} նիշ"),minlength:a.validator.format("Ներմուծեք ոչ պակաս քան {0} նիշ"),rangelength:a.validator.format("Ներմուծեք {0}֊ից {1} երկարությամբ արժեք"),range:a.validator.format("Ներմուծեք թիվ {0}֊ից {1} միջակայքում"),max:a.validator.format("Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին"),min:a.validator.format("Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.js new file mode 100644 index 0000000000..052a988165 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.js @@ -0,0 +1,34 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ID (Indonesia; Indonesian) + */ +$.extend( $.validator.messages, { + required: "Kolom ini diperlukan.", + remote: "Harap benarkan kolom ini.", + email: "Silakan masukkan format email yang benar.", + url: "Silakan masukkan format URL yang benar.", + date: "Silakan masukkan format tanggal yang benar.", + dateISO: "Silakan masukkan format tanggal(ISO) yang benar.", + number: "Silakan masukkan angka yang benar.", + digits: "Harap masukan angka saja.", + creditcard: "Harap masukkan format kartu kredit yang benar.", + equalTo: "Harap masukkan nilai yg sama dengan sebelumnya.", + maxlength: $.validator.format( "Input dibatasi hanya {0} karakter." ), + minlength: $.validator.format( "Input tidak kurang dari {0} karakter." ), + rangelength: $.validator.format( "Panjang karakter yg diizinkan antara {0} dan {1} karakter." ), + range: $.validator.format( "Harap masukkan nilai antara {0} dan {1}." ), + max: $.validator.format( "Harap masukkan nilai lebih kecil atau sama dengan {0}." ), + min: $.validator.format( "Harap masukkan nilai lebih besar atau sama dengan {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.min.js new file mode 100644 index 0000000000..5686069cb2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_id.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kolom ini diperlukan.",remote:"Harap benarkan kolom ini.",email:"Silakan masukkan format email yang benar.",url:"Silakan masukkan format URL yang benar.",date:"Silakan masukkan format tanggal yang benar.",dateISO:"Silakan masukkan format tanggal(ISO) yang benar.",number:"Silakan masukkan angka yang benar.",digits:"Harap masukan angka saja.",creditcard:"Harap masukkan format kartu kredit yang benar.",equalTo:"Harap masukkan nilai yg sama dengan sebelumnya.",maxlength:a.validator.format("Input dibatasi hanya {0} karakter."),minlength:a.validator.format("Input tidak kurang dari {0} karakter."),rangelength:a.validator.format("Panjang karakter yg diizinkan antara {0} dan {1} karakter."),range:a.validator.format("Harap masukkan nilai antara {0} dan {1}."),max:a.validator.format("Harap masukkan nilai lebih kecil atau sama dengan {0}."),min:a.validator.format("Harap masukkan nilai lebih besar atau sama dengan {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.js new file mode 100644 index 0000000000..e3f75d0141 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.js @@ -0,0 +1,33 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: IS (Icelandic; íslenska) + */ +$.extend( $.validator.messages, { + required: "Þessi reitur er nauðsynlegur.", + remote: "Lagaðu þennan reit.", + maxlength: $.validator.format( "Sláðu inn mest {0} stafi." ), + minlength: $.validator.format( "Sláðu inn minnst {0} stafi." ), + rangelength: $.validator.format( "Sláðu inn minnst {0} og mest {1} stafi." ), + email: "Sláðu inn gilt netfang.", + url: "Sláðu inn gilda vefslóð.", + date: "Sláðu inn gilda dagsetningu.", + number: "Sláðu inn tölu.", + digits: "Sláðu inn tölustafi eingöngu.", + equalTo: "Sláðu sama gildi inn aftur.", + range: $.validator.format( "Sláðu inn gildi milli {0} og {1}." ), + max: $.validator.format( "Sláðu inn gildi sem er minna en eða jafnt og {0}." ), + min: $.validator.format( "Sláðu inn gildi sem er stærra en eða jafnt og {0}." ), + creditcard: "Sláðu inn gilt greiðslukortanúmer." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.min.js new file mode 100644 index 0000000000..3a6c01751c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_is.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Þessi reitur er nauðsynlegur.",remote:"Lagaðu þennan reit.",maxlength:a.validator.format("Sláðu inn mest {0} stafi."),minlength:a.validator.format("Sláðu inn minnst {0} stafi."),rangelength:a.validator.format("Sláðu inn minnst {0} og mest {1} stafi."),email:"Sláðu inn gilt netfang.",url:"Sláðu inn gilda vefslóð.",date:"Sláðu inn gilda dagsetningu.",number:"Sláðu inn tölu.",digits:"Sláðu inn tölustafi eingöngu.",equalTo:"Sláðu sama gildi inn aftur.",range:a.validator.format("Sláðu inn gildi milli {0} og {1}."),max:a.validator.format("Sláðu inn gildi sem er minna en eða jafnt og {0}."),min:a.validator.format("Sláðu inn gildi sem er stærra en eða jafnt og {0}."),creditcard:"Sláðu inn gilt greiðslukortanúmer."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.js new file mode 100644 index 0000000000..88ce6f0ea7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.js @@ -0,0 +1,39 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: IT (Italian; Italiano) + */ +$.extend( $.validator.messages, { + required: "Campo obbligatorio", + remote: "Controlla questo campo", + email: "Inserisci un indirizzo email valido", + url: "Inserisci un indirizzo web valido", + date: "Inserisci una data valida", + dateISO: "Inserisci una data valida (ISO)", + number: "Inserisci un numero valido", + digits: "Inserisci solo numeri", + creditcard: "Inserisci un numero di carta di credito valido", + equalTo: "Il valore non corrisponde", + extension: "Inserisci un valore con un'estensione valida", + maxlength: $.validator.format( "Non inserire più di {0} caratteri" ), + minlength: $.validator.format( "Inserisci almeno {0} caratteri" ), + rangelength: $.validator.format( "Inserisci un valore compreso tra {0} e {1} caratteri" ), + range: $.validator.format( "Inserisci un valore compreso tra {0} e {1}" ), + max: $.validator.format( "Inserisci un valore minore o uguale a {0}" ), + min: $.validator.format( "Inserisci un valore maggiore o uguale a {0}" ), + nifES: "Inserisci un NIF valido", + nieES: "Inserisci un NIE valido", + cifES: "Inserisci un CIF valido", + currency: "Inserisci una valuta valida" +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.min.js new file mode 100644 index 0000000000..f37ee14730 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_it.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo obbligatorio",remote:"Controlla questo campo",email:"Inserisci un indirizzo email valido",url:"Inserisci un indirizzo web valido",date:"Inserisci una data valida",dateISO:"Inserisci una data valida (ISO)",number:"Inserisci un numero valido",digits:"Inserisci solo numeri",creditcard:"Inserisci un numero di carta di credito valido",equalTo:"Il valore non corrisponde",extension:"Inserisci un valore con un'estensione valida",maxlength:a.validator.format("Non inserire più di {0} caratteri"),minlength:a.validator.format("Inserisci almeno {0} caratteri"),rangelength:a.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri"),range:a.validator.format("Inserisci un valore compreso tra {0} e {1}"),max:a.validator.format("Inserisci un valore minore o uguale a {0}"),min:a.validator.format("Inserisci un valore maggiore o uguale a {0}"),nifES:"Inserisci un NIF valido",nieES:"Inserisci un NIE valido",cifES:"Inserisci un CIF valido",currency:"Inserisci una valuta valida"}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.js new file mode 100644 index 0000000000..f72c53dc45 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.js @@ -0,0 +1,36 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: JA (Japanese; 日本語) + */ +$.extend( $.validator.messages, { + required: "このフィールドは必須です。", + remote: "このフィールドを修正してください。", + email: "有効なEメールアドレスを入力してください。", + url: "有効なURLを入力してください。", + date: "有効な日付を入力してください。", + dateISO: "有効な日付(ISO)を入力してください。", + number: "有効な数字を入力してください。", + digits: "数字のみを入力してください。", + creditcard: "有効なクレジットカード番号を入力してください。", + equalTo: "同じ値をもう一度入力してください。", + extension: "有効な拡張子を含む値を入力してください。", + maxlength: $.validator.format( "{0} 文字以内で入力してください。" ), + minlength: $.validator.format( "{0} 文字以上で入力してください。" ), + rangelength: $.validator.format( "{0} 文字から {1} 文字までの値を入力してください。" ), + range: $.validator.format( "{0} から {1} までの値を入力してください。" ), + step: $.validator.format( "{0} の倍数を入力してください。" ), + max: $.validator.format( "{0} 以下の値を入力してください。" ), + min: $.validator.format( "{0} 以上の値を入力してください。" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.min.js new file mode 100644 index 0000000000..a8f684ad79 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ja.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"このフィールドは必須です。",remote:"このフィールドを修正してください。",email:"有効なEメールアドレスを入力してください。",url:"有効なURLを入力してください。",date:"有効な日付を入力してください。",dateISO:"有効な日付(ISO)を入力してください。",number:"有効な数字を入力してください。",digits:"数字のみを入力してください。",creditcard:"有効なクレジットカード番号を入力してください。",equalTo:"同じ値をもう一度入力してください。",extension:"有効な拡張子を含む値を入力してください。",maxlength:a.validator.format("{0} 文字以内で入力してください。"),minlength:a.validator.format("{0} 文字以上で入力してください。"),rangelength:a.validator.format("{0} 文字から {1} 文字までの値を入力してください。"),range:a.validator.format("{0} から {1} までの値を入力してください。"),step:a.validator.format("{0} の倍数を入力してください。"),max:a.validator.format("{0} 以下の値を入力してください。"),min:a.validator.format("{0} 以上の値を入力してください。")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.js new file mode 100644 index 0000000000..a4d79ff974 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: KA (Georgian; ქართული) + */ +$.extend( $.validator.messages, { + required: "ამ ველის შევსება აუცილებელია.", + remote: "გთხოვთ მიუთითოთ სწორი მნიშვნელობა.", + email: "გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.", + url: "გთხოვთ მიუთითოთ კორექტული URL.", + date: "გთხოვთ მიუთითოთ კორექტული თარიღი.", + dateISO: "გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.", + number: "გთხოვთ მიუთითოთ ციფრი.", + digits: "გთხოვთ მიუთითოთ მხოლოდ ციფრები.", + creditcard: "გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.", + equalTo: "გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.", + extension: "გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.", + maxlength: $.validator.format( "დასაშვებია არაუმეტეს {0} სიმბოლო." ), + minlength: $.validator.format( "აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო." ), + rangelength: $.validator.format( "ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე." ), + range: $.validator.format( "გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე." ), + max: $.validator.format( "გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს." ), + min: $.validator.format( "გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.min.js new file mode 100644 index 0000000000..6273e8b7a3 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ka.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ამ ველის შევსება აუცილებელია.",remote:"გთხოვთ მიუთითოთ სწორი მნიშვნელობა.",email:"გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.",url:"გთხოვთ მიუთითოთ კორექტული URL.",date:"გთხოვთ მიუთითოთ კორექტული თარიღი.",dateISO:"გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.",number:"გთხოვთ მიუთითოთ ციფრი.",digits:"გთხოვთ მიუთითოთ მხოლოდ ციფრები.",creditcard:"გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.",equalTo:"გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.",extension:"გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.",maxlength:a.validator.format("დასაშვებია არაუმეტეს {0} სიმბოლო."),minlength:a.validator.format("აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე."),range:a.validator.format("გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე."),max:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს."),min:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.js new file mode 100644 index 0000000000..79e3ea828e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: KK (Kazakh; қазақ тілі) + */ +$.extend( $.validator.messages, { + required: "Бұл өрісті міндетті түрде толтырыңыз.", + remote: "Дұрыс мағына енгізуіңізді сұраймыз.", + email: "Нақты электронды поштаңызды енгізуіңізді сұраймыз.", + url: "Нақты URL-ды енгізуіңізді сұраймыз.", + date: "Нақты URL-ды енгізуіңізді сұраймыз.", + dateISO: "Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.", + number: "Күнді енгізуіңізді сұраймыз.", + digits: "Тек қана сандарды енгізуіңізді сұраймыз.", + creditcard: "Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.", + equalTo: "Осы мәнді қайта енгізуіңізді сұраймыз.", + extension: "Файлдың кеңейтуін дұрыс таңдаңыз.", + maxlength: $.validator.format( "Ұзындығы {0} символдан көр болмасын." ), + minlength: $.validator.format( "Ұзындығы {0} символдан аз болмасын." ), + rangelength: $.validator.format( "Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз." ), + range: $.validator.format( "Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз." ), + max: $.validator.format( "{0} аз немесе тең санын енгізуіңіді сұраймыз." ), + min: $.validator.format( "{0} көп немесе тең санын енгізуіңізді сұраймыз." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.min.js new file mode 100644 index 0000000000..7f450ec8f6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_kk.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Бұл өрісті міндетті түрде толтырыңыз.",remote:"Дұрыс мағына енгізуіңізді сұраймыз.",email:"Нақты электронды поштаңызды енгізуіңізді сұраймыз.",url:"Нақты URL-ды енгізуіңізді сұраймыз.",date:"Нақты URL-ды енгізуіңізді сұраймыз.",dateISO:"Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.",number:"Күнді енгізуіңізді сұраймыз.",digits:"Тек қана сандарды енгізуіңізді сұраймыз.",creditcard:"Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.",equalTo:"Осы мәнді қайта енгізуіңізді сұраймыз.",extension:"Файлдың кеңейтуін дұрыс таңдаңыз.",maxlength:a.validator.format("Ұзындығы {0} символдан көр болмасын."),minlength:a.validator.format("Ұзындығы {0} символдан аз болмасын."),rangelength:a.validator.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."),max:a.validator.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."),min:a.validator.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.js new file mode 100644 index 0000000000..f94612cb7a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: KO (Korean; 한국어) + */ +$.extend( $.validator.messages, { + required: "필수 항목입니다.", + remote: "항목을 수정하세요.", + email: "유효하지 않은 E-Mail주소입니다.", + url: "유효하지 않은 URL입니다.", + date: "올바른 날짜를 입력하세요.", + dateISO: "올바른 날짜(ISO)를 입력하세요.", + number: "유효한 숫자가 아닙니다.", + digits: "숫자만 입력 가능합니다.", + creditcard: "신용카드 번호가 바르지 않습니다.", + equalTo: "같은 값을 다시 입력하세요.", + extension: "올바른 확장자가 아닙니다.", + maxlength: $.validator.format( "{0}자를 넘을 수 없습니다. " ), + minlength: $.validator.format( "{0}자 이상 입력하세요." ), + rangelength: $.validator.format( "문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요." ), + range: $.validator.format( "{0} 에서 {1} 사이의 값을 입력하세요." ), + max: $.validator.format( "{0} 이하의 값을 입력하세요." ), + min: $.validator.format( "{0} 이상의 값을 입력하세요." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.min.js new file mode 100644 index 0000000000..4634eca42c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ko.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"필수 항목입니다.",remote:"항목을 수정하세요.",email:"유효하지 않은 E-Mail주소입니다.",url:"유효하지 않은 URL입니다.",date:"올바른 날짜를 입력하세요.",dateISO:"올바른 날짜(ISO)를 입력하세요.",number:"유효한 숫자가 아닙니다.",digits:"숫자만 입력 가능합니다.",creditcard:"신용카드 번호가 바르지 않습니다.",equalTo:"같은 값을 다시 입력하세요.",extension:"올바른 확장자가 아닙니다.",maxlength:a.validator.format("{0}자를 넘을 수 없습니다. "),minlength:a.validator.format("{0}자 이상 입력하세요."),rangelength:a.validator.format("문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요."),range:a.validator.format("{0} 에서 {1} 사이의 값을 입력하세요."),max:a.validator.format("{0} 이하의 값을 입력하세요."),min:a.validator.format("{0} 이상의 값을 입력하세요.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.js new file mode 100644 index 0000000000..4dea0b1101 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: LT (Lithuanian; lietuvių kalba) + */ +$.extend( $.validator.messages, { + required: "Šis laukas yra privalomas.", + remote: "Prašau pataisyti šį lauką.", + email: "Prašau įvesti teisingą elektroninio pašto adresą.", + url: "Prašau įvesti teisingą URL.", + date: "Prašau įvesti teisingą datą.", + dateISO: "Prašau įvesti teisingą datą (ISO).", + number: "Prašau įvesti teisingą skaičių.", + digits: "Prašau naudoti tik skaitmenis.", + creditcard: "Prašau įvesti teisingą kreditinės kortelės numerį.", + equalTo: "Prašau įvestį tą pačią reikšmę dar kartą.", + extension: "Prašau įvesti reikšmę su teisingu plėtiniu.", + maxlength: $.validator.format( "Prašau įvesti ne daugiau kaip {0} simbolių." ), + minlength: $.validator.format( "Prašau įvesti bent {0} simbolius." ), + rangelength: $.validator.format( "Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių." ), + range: $.validator.format( "Prašau įvesti reikšmę intervale nuo {0} iki {1}." ), + max: $.validator.format( "Prašau įvesti reikšmę mažesnę arba lygią {0}." ), + min: $.validator.format( "Prašau įvesti reikšmę didesnę arba lygią {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.min.js new file mode 100644 index 0000000000..67ad519db3 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lt.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis laukas yra privalomas.",remote:"Prašau pataisyti šį lauką.",email:"Prašau įvesti teisingą elektroninio pašto adresą.",url:"Prašau įvesti teisingą URL.",date:"Prašau įvesti teisingą datą.",dateISO:"Prašau įvesti teisingą datą (ISO).",number:"Prašau įvesti teisingą skaičių.",digits:"Prašau naudoti tik skaitmenis.",creditcard:"Prašau įvesti teisingą kreditinės kortelės numerį.",equalTo:"Prašau įvestį tą pačią reikšmę dar kartą.",extension:"Prašau įvesti reikšmę su teisingu plėtiniu.",maxlength:a.validator.format("Prašau įvesti ne daugiau kaip {0} simbolių."),minlength:a.validator.format("Prašau įvesti bent {0} simbolius."),rangelength:a.validator.format("Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių."),range:a.validator.format("Prašau įvesti reikšmę intervale nuo {0} iki {1}."),max:a.validator.format("Prašau įvesti reikšmę mažesnę arba lygią {0}."),min:a.validator.format("Prašau įvesti reikšmę didesnę arba lygią {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.js new file mode 100644 index 0000000000..692e3cbcb7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: LV (Latvian; latviešu valoda) + */ +$.extend( $.validator.messages, { + required: "Šis lauks ir obligāts.", + remote: "Lūdzu, pārbaudiet šo lauku.", + email: "Lūdzu, ievadiet derīgu e-pasta adresi.", + url: "Lūdzu, ievadiet derīgu URL adresi.", + date: "Lūdzu, ievadiet derīgu datumu.", + dateISO: "Lūdzu, ievadiet derīgu datumu (ISO).", + number: "Lūdzu, ievadiet derīgu numuru.", + digits: "Lūdzu, ievadiet tikai ciparus.", + creditcard: "Lūdzu, ievadiet derīgu kredītkartes numuru.", + equalTo: "Lūdzu, ievadiet to pašu vēlreiz.", + extension: "Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.", + maxlength: $.validator.format( "Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes." ), + minlength: $.validator.format( "Lūdzu, ievadiet vismaz {0} rakstzīmes." ), + rangelength: $.validator.format( "Lūdzu ievadiet {0} līdz {1} rakstzīmes." ), + range: $.validator.format( "Lūdzu, ievadiet skaitli no {0} līdz {1}." ), + max: $.validator.format( "Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}." ), + min: $.validator.format( "Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.min.js new file mode 100644 index 0000000000..67e4efa448 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_lv.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis lauks ir obligāts.",remote:"Lūdzu, pārbaudiet šo lauku.",email:"Lūdzu, ievadiet derīgu e-pasta adresi.",url:"Lūdzu, ievadiet derīgu URL adresi.",date:"Lūdzu, ievadiet derīgu datumu.",dateISO:"Lūdzu, ievadiet derīgu datumu (ISO).",number:"Lūdzu, ievadiet derīgu numuru.",digits:"Lūdzu, ievadiet tikai ciparus.",creditcard:"Lūdzu, ievadiet derīgu kredītkartes numuru.",equalTo:"Lūdzu, ievadiet to pašu vēlreiz.",extension:"Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.",maxlength:a.validator.format("Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes."),minlength:a.validator.format("Lūdzu, ievadiet vismaz {0} rakstzīmes."),rangelength:a.validator.format("Lūdzu ievadiet {0} līdz {1} rakstzīmes."),range:a.validator.format("Lūdzu, ievadiet skaitli no {0} līdz {1}."),max:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}."),min:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.js new file mode 100644 index 0000000000..242783536e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: MK (Macedonian; македонски јазик) + */ +$.extend( $.validator.messages, { + required: "Полето е задолжително.", + remote: "Поправете го ова поле", + email: "Внесете правилна e-mail адреса", + url: "Внесете правилен URL.", + date: "Внесете правилен датум", + dateISO: "Внесете правилен датум (ISO).", + number: "Внесете правилен број.", + digits: "Внесете само бројки.", + creditcard: "Внесете правилен број на кредитната картичка.", + equalTo: "Внесете ја истата вредност повторно.", + extension: "Внесете вредност со соодветна екстензија.", + maxlength: $.validator.format( "Внесете максимално {0} знаци." ), + minlength: $.validator.format( "Внесете барем {0} знаци." ), + rangelength: $.validator.format( "Внесете вредност со должина помеѓу {0} и {1} знаци." ), + range: $.validator.format( "Внесете вредност помеѓу {0} и {1}." ), + max: $.validator.format( "Внесете вредност помала или еднаква на {0}." ), + min: $.validator.format( "Внесете вредност поголема или еднаква на {0}" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.min.js new file mode 100644 index 0000000000..93a33adf20 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_mk.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задолжително.",remote:"Поправете го ова поле",email:"Внесете правилна e-mail адреса",url:"Внесете правилен URL.",date:"Внесете правилен датум",dateISO:"Внесете правилен датум (ISO).",number:"Внесете правилен број.",digits:"Внесете само бројки.",creditcard:"Внесете правилен број на кредитната картичка.",equalTo:"Внесете ја истата вредност повторно.",extension:"Внесете вредност со соодветна екстензија.",maxlength:a.validator.format("Внесете максимално {0} знаци."),minlength:a.validator.format("Внесете барем {0} знаци."),rangelength:a.validator.format("Внесете вредност со должина помеѓу {0} и {1} знаци."),range:a.validator.format("Внесете вредност помеѓу {0} и {1}."),max:a.validator.format("Внесете вредност помала или еднаква на {0}."),min:a.validator.format("Внесете вредност поголема или еднаква на {0}")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.js new file mode 100644 index 0000000000..9b8313b6f4 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: MY (Malay; Melayu) + */ +$.extend( $.validator.messages, { + required: "Medan ini diperlukan.", + remote: "Sila betulkan medan ini.", + email: "Sila masukkan alamat emel yang betul.", + url: "Sila masukkan URL yang betul.", + date: "Sila masukkan tarikh yang betul.", + dateISO: "Sila masukkan tarikh(ISO) yang betul.", + number: "Sila masukkan nombor yang betul.", + digits: "Sila masukkan nilai digit sahaja.", + creditcard: "Sila masukkan nombor kredit kad yang betul.", + equalTo: "Sila masukkan nilai yang sama semula.", + extension: "Sila masukkan nilai yang telah diterima.", + maxlength: $.validator.format( "Sila masukkan tidak lebih dari {0} aksara." ), + minlength: $.validator.format( "Sila masukkan sekurang-kurangnya {0} aksara." ), + rangelength: $.validator.format( "Sila masukkan antara {0} dan {1} panjang aksara." ), + range: $.validator.format( "Sila masukkan nilai antara {0} dan {1} aksara." ), + max: $.validator.format( "Sila masukkan nilai yang kurang atau sama dengan {0}." ), + min: $.validator.format( "Sila masukkan nilai yang lebih atau sama dengan {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.min.js new file mode 100644 index 0000000000..721a1be35d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_my.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Medan ini diperlukan.",remote:"Sila betulkan medan ini.",email:"Sila masukkan alamat emel yang betul.",url:"Sila masukkan URL yang betul.",date:"Sila masukkan tarikh yang betul.",dateISO:"Sila masukkan tarikh(ISO) yang betul.",number:"Sila masukkan nombor yang betul.",digits:"Sila masukkan nilai digit sahaja.",creditcard:"Sila masukkan nombor kredit kad yang betul.",equalTo:"Sila masukkan nilai yang sama semula.",extension:"Sila masukkan nilai yang telah diterima.",maxlength:a.validator.format("Sila masukkan tidak lebih dari {0} aksara."),minlength:a.validator.format("Sila masukkan sekurang-kurangnya {0} aksara."),rangelength:a.validator.format("Sila masukkan antara {0} dan {1} panjang aksara."),range:a.validator.format("Sila masukkan nilai antara {0} dan {1} aksara."),max:a.validator.format("Sila masukkan nilai yang kurang atau sama dengan {0}."),min:a.validator.format("Sila masukkan nilai yang lebih atau sama dengan {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.js new file mode 100644 index 0000000000..c688ea2493 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.js @@ -0,0 +1,46 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: NL (Dutch; Nederlands, Vlaams) + */ +$.extend( $.validator.messages, { + required: "Dit is een verplicht veld.", + remote: "Controleer dit veld.", + email: "Vul hier een geldig e-mailadres in.", + url: "Vul hier een geldige URL in.", + date: "Vul hier een geldige datum in.", + dateISO: "Vul hier een geldige datum in (ISO-formaat).", + number: "Vul hier een geldig getal in.", + digits: "Vul hier alleen getallen in.", + creditcard: "Vul hier een geldig creditcardnummer in.", + equalTo: "Vul hier dezelfde waarde in.", + extension: "Vul hier een waarde in met een geldige extensie.", + maxlength: $.validator.format( "Vul hier maximaal {0} tekens in." ), + minlength: $.validator.format( "Vul hier minimaal {0} tekens in." ), + rangelength: $.validator.format( "Vul hier een waarde in van minimaal {0} en maximaal {1} tekens." ), + range: $.validator.format( "Vul hier een waarde in van minimaal {0} en maximaal {1}." ), + max: $.validator.format( "Vul hier een waarde in kleiner dan of gelijk aan {0}." ), + min: $.validator.format( "Vul hier een waarde in groter dan of gelijk aan {0}." ), + step: $.validator.format( "Vul hier een veelvoud van {0} in." ), + + // For validations in additional-methods.js + iban: "Vul hier een geldig IBAN in.", + dateNL: "Vul hier een geldige datum in.", + phoneNL: "Vul hier een geldig Nederlands telefoonnummer in.", + mobileNL: "Vul hier een geldig Nederlands mobiel telefoonnummer in.", + postalcodeNL: "Vul hier een geldige postcode in.", + bankaccountNL: "Vul hier een geldig bankrekeningnummer in.", + giroaccountNL: "Vul hier een geldig gironummer in.", + bankorgiroaccountNL: "Vul hier een geldig bank- of gironummer in." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.min.js new file mode 100644 index 0000000000..f69c3d5186 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_nl.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dit is een verplicht veld.",remote:"Controleer dit veld.",email:"Vul hier een geldig e-mailadres in.",url:"Vul hier een geldige URL in.",date:"Vul hier een geldige datum in.",dateISO:"Vul hier een geldige datum in (ISO-formaat).",number:"Vul hier een geldig getal in.",digits:"Vul hier alleen getallen in.",creditcard:"Vul hier een geldig creditcardnummer in.",equalTo:"Vul hier dezelfde waarde in.",extension:"Vul hier een waarde in met een geldige extensie.",maxlength:a.validator.format("Vul hier maximaal {0} tekens in."),minlength:a.validator.format("Vul hier minimaal {0} tekens in."),rangelength:a.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1} tekens."),range:a.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1}."),max:a.validator.format("Vul hier een waarde in kleiner dan of gelijk aan {0}."),min:a.validator.format("Vul hier een waarde in groter dan of gelijk aan {0}."),step:a.validator.format("Vul hier een veelvoud van {0} in."),iban:"Vul hier een geldig IBAN in.",dateNL:"Vul hier een geldige datum in.",phoneNL:"Vul hier een geldig Nederlands telefoonnummer in.",mobileNL:"Vul hier een geldig Nederlands mobiel telefoonnummer in.",postalcodeNL:"Vul hier een geldige postcode in.",bankaccountNL:"Vul hier een geldig bankrekeningnummer in.",giroaccountNL:"Vul hier een geldig gironummer in.",bankorgiroaccountNL:"Vul hier een geldig bank- of gironummer in."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.js new file mode 100644 index 0000000000..d6d7be0893 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: NO (Norwegian; Norsk) + */ +$.extend( $.validator.messages, { + required: "Angi en verdi.", + remote: "Ugyldig verdi.", + email: "Angi en gyldig epostadresse.", + url: "Angi en gyldig URL.", + date: "Angi en gyldig dato.", + dateISO: "Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).", + number: "Angi et gyldig tall.", + digits: "Skriv kun tall.", + equalTo: "Skriv samme verdi igjen.", + maxlength: $.validator.format( "Maksimalt {0} tegn." ), + minlength: $.validator.format( "Minimum {0} tegn." ), + rangelength: $.validator.format( "Angi minimum {0} og maksimum {1} tegn." ), + range: $.validator.format( "Angi en verdi mellom {0} og {1}." ), + max: $.validator.format( "Angi en verdi som er mindre eller lik {0}." ), + min: $.validator.format( "Angi en verdi som er større eller lik {0}." ), + step: $.validator.format( "Angi en verdi ganger {0}." ), + creditcard: "Angi et gyldig kredittkortnummer." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.min.js new file mode 100644 index 0000000000..6feaa2df65 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_no.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Angi en verdi.",remote:"Ugyldig verdi.",email:"Angi en gyldig epostadresse.",url:"Angi en gyldig URL.",date:"Angi en gyldig dato.",dateISO:"Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).",number:"Angi et gyldig tall.",digits:"Skriv kun tall.",equalTo:"Skriv samme verdi igjen.",maxlength:a.validator.format("Maksimalt {0} tegn."),minlength:a.validator.format("Minimum {0} tegn."),rangelength:a.validator.format("Angi minimum {0} og maksimum {1} tegn."),range:a.validator.format("Angi en verdi mellom {0} og {1}."),max:a.validator.format("Angi en verdi som er mindre eller lik {0}."),min:a.validator.format("Angi en verdi som er større eller lik {0}."),step:a.validator.format("Angi en verdi ganger {0}."),creditcard:"Angi et gyldig kredittkortnummer."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.js new file mode 100644 index 0000000000..fc07b85200 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.js @@ -0,0 +1,38 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: PL (Polish; język polski, polszczyzna) + */ +$.extend( $.validator.messages, { + required: "To pole jest wymagane.", + remote: "Proszę o wypełnienie tego pola.", + email: "Proszę o podanie prawidłowego adresu email.", + url: "Proszę o podanie prawidłowego URL.", + date: "Proszę o podanie prawidłowej daty.", + dateISO: "Proszę o podanie prawidłowej daty (ISO).", + number: "Proszę o podanie prawidłowej liczby.", + digits: "Proszę o podanie samych cyfr.", + creditcard: "Proszę o podanie prawidłowej karty kredytowej.", + equalTo: "Proszę o podanie tej samej wartości ponownie.", + extension: "Proszę o podanie wartości z prawidłowym rozszerzeniem.", + nipPL: "Proszę o podanie prawidłowego numeru NIP.", + phonePL: "Proszę o podanie prawidłowego numeru telefonu", + maxlength: $.validator.format( "Proszę o podanie nie więcej niż {0} znaków." ), + minlength: $.validator.format( "Proszę o podanie przynajmniej {0} znaków." ), + rangelength: $.validator.format( "Proszę o podanie wartości o długości od {0} do {1} znaków." ), + range: $.validator.format( "Proszę o podanie wartości z przedziału od {0} do {1}." ), + max: $.validator.format( "Proszę o podanie wartości mniejszej bądź równej {0}." ), + min: $.validator.format( "Proszę o podanie wartości większej bądź równej {0}." ), + pattern: $.validator.format( "Pole zawiera niedozwolone znaki." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.min.js new file mode 100644 index 0000000000..fdca59ea7b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pl.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To pole jest wymagane.",remote:"Proszę o wypełnienie tego pola.",email:"Proszę o podanie prawidłowego adresu email.",url:"Proszę o podanie prawidłowego URL.",date:"Proszę o podanie prawidłowej daty.",dateISO:"Proszę o podanie prawidłowej daty (ISO).",number:"Proszę o podanie prawidłowej liczby.",digits:"Proszę o podanie samych cyfr.",creditcard:"Proszę o podanie prawidłowej karty kredytowej.",equalTo:"Proszę o podanie tej samej wartości ponownie.",extension:"Proszę o podanie wartości z prawidłowym rozszerzeniem.",nipPL:"Proszę o podanie prawidłowego numeru NIP.",phonePL:"Proszę o podanie prawidłowego numeru telefonu",maxlength:a.validator.format("Proszę o podanie nie więcej niż {0} znaków."),minlength:a.validator.format("Proszę o podanie przynajmniej {0} znaków."),rangelength:a.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."),range:a.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."),max:a.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."),min:a.validator.format("Proszę o podanie wartości większej bądź równej {0}."),pattern:a.validator.format("Pole zawiera niedozwolone znaki.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.js new file mode 100644 index 0000000000..92d9604c33 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.js @@ -0,0 +1,91 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: PT (Portuguese; português) + * Region: BR (Brazil) + */ +$.extend( $.validator.messages, { + + // Core + required: "Este campo é requerido.", + remote: "Por favor, corrija este campo.", + email: "Por favor, forneça um endereço de email válido.", + url: "Por favor, forneça uma URL válida.", + date: "Por favor, forneça uma data válida.", + dateISO: "Por favor, forneça uma data válida (ISO).", + number: "Por favor, forneça um número válido.", + digits: "Por favor, forneça somente dígitos.", + creditcard: "Por favor, forneça um cartão de crédito válido.", + equalTo: "Por favor, forneça o mesmo valor novamente.", + maxlength: $.validator.format( "Por favor, forneça não mais que {0} caracteres." ), + minlength: $.validator.format( "Por favor, forneça ao menos {0} caracteres." ), + rangelength: $.validator.format( "Por favor, forneça um valor entre {0} e {1} caracteres de comprimento." ), + range: $.validator.format( "Por favor, forneça um valor entre {0} e {1}." ), + max: $.validator.format( "Por favor, forneça um valor menor ou igual a {0}." ), + min: $.validator.format( "Por favor, forneça um valor maior ou igual a {0}." ), + step: $.validator.format( "Por favor, forneça um valor múltiplo de {0}." ), + + // Metodos Adicionais + maxWords: $.validator.format( "Por favor, forneça com {0} palavras ou menos." ), + minWords: $.validator.format( "Por favor, forneça pelo menos {0} palavras." ), + rangeWords: $.validator.format( "Por favor, forneça entre {0} e {1} palavras." ), + accept: "Por favor, forneça um tipo válido.", + alphanumeric: "Por favor, forneça somente com letras, números e sublinhados.", + bankaccountNL: "Por favor, forneça com um número de conta bancária válida.", + bankorgiroaccountNL: "Por favor, forneça um banco válido ou número de conta.", + bic: "Por favor, forneça um código BIC válido.", + cifES: "Por favor, forneça um código CIF válido.", + creditcardtypes: "Por favor, forneça um número de cartão de crédito válido.", + currency: "Por favor, forneça uma moeda válida.", + dateFA: "Por favor, forneça uma data correta.", + dateITA: "Por favor, forneça uma data correta.", + dateNL: "Por favor, forneça uma data correta.", + extension: "Por favor, forneça um valor com uma extensão válida.", + giroaccountNL: "Por favor, forneça um número de conta corrente válido.", + iban: "Por favor, forneça um código IBAN válido.", + integer: "Por favor, forneça um número não decimal.", + ipv4: "Por favor, forneça um IPv4 válido.", + ipv6: "Por favor, forneça um IPv6 válido.", + lettersonly: "Por favor, forneça apenas com letras.", + letterswithbasicpunc: "Por favor, forneça apenas letras ou pontuações.", + mobileNL: "Por favor, forneceça um número válido de telefone.", + mobileUK: "Por favor, forneceça um número válido de telefone.", + nieES: "Por favor, forneça um NIE válido.", + nifES: "Por favor, forneça um NIF válido.", + nowhitespace: "Por favor, não utilize espaços em branco.", + pattern: "O formato fornecido é inválido.", + phoneNL: "Por favor, forneça um número de telefone válido.", + phoneUK: "Por favor, forneça um número de telefone válido.", + phoneUS: "Por favor, forneça um número de telefone válido.", + phonesUK: "Por favor, forneça um número de telefone válido.", + postalCodeCA: "Por favor, forneça um número de código postal válido.", + postalcodeIT: "Por favor, forneça um número de código postal válido.", + postalcodeNL: "Por favor, forneça um número de código postal válido.", + postcodeUK: "Por favor, forneça um número de código postal válido.", + postalcodeBR: "Por favor, forneça um CEP válido.", + require_from_group: $.validator.format( "Por favor, forneça pelo menos {0} destes campos." ), + skip_or_fill_minimum: $.validator.format( "Por favor, optar entre ignorar esses campos ou preencher pelo menos {0} deles." ), + stateUS: "Por favor, forneça um estado válido.", + strippedminlength: $.validator.format( "Por favor, forneça pelo menos {0} caracteres." ), + time: "Por favor, forneça um horário válido, no intervado de 00:00 a 23:59.", + time12h: "Por favor, forneça um horário válido, no intervado de 01:00 a 12:59 am/pm.", + url2: "Por favor, forneça uma URL válida.", + vinUS: "O número de identificação de veículo informado (VIN) é inválido.", + zipcodeUS: "Por favor, forneça um código postal americano válido.", + ziprange: "O código postal deve estar entre 902xx-xxxx e 905xx-xxxx", + cpfBR: "Por favor, forneça um CPF válido.", + nisBR: "Por favor, forneça um NIS/PIS válido", + cnhBR: "Por favor, forneça um CNH válido.", + cnpjBR: "Por favor, forneça um CNPJ válido." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.min.js new file mode 100644 index 0000000000..bac1ae897d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_BR.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo é requerido.",remote:"Por favor, corrija este campo.",email:"Por favor, forneça um endereço de email válido.",url:"Por favor, forneça uma URL válida.",date:"Por favor, forneça uma data válida.",dateISO:"Por favor, forneça uma data válida (ISO).",number:"Por favor, forneça um número válido.",digits:"Por favor, forneça somente dígitos.",creditcard:"Por favor, forneça um cartão de crédito válido.",equalTo:"Por favor, forneça o mesmo valor novamente.",maxlength:a.validator.format("Por favor, forneça não mais que {0} caracteres."),minlength:a.validator.format("Por favor, forneça ao menos {0} caracteres."),rangelength:a.validator.format("Por favor, forneça um valor entre {0} e {1} caracteres de comprimento."),range:a.validator.format("Por favor, forneça um valor entre {0} e {1}."),max:a.validator.format("Por favor, forneça um valor menor ou igual a {0}."),min:a.validator.format("Por favor, forneça um valor maior ou igual a {0}."),step:a.validator.format("Por favor, forneça um valor múltiplo de {0}."),maxWords:a.validator.format("Por favor, forneça com {0} palavras ou menos."),minWords:a.validator.format("Por favor, forneça pelo menos {0} palavras."),rangeWords:a.validator.format("Por favor, forneça entre {0} e {1} palavras."),accept:"Por favor, forneça um tipo válido.",alphanumeric:"Por favor, forneça somente com letras, números e sublinhados.",bankaccountNL:"Por favor, forneça com um número de conta bancária válida.",bankorgiroaccountNL:"Por favor, forneça um banco válido ou número de conta.",bic:"Por favor, forneça um código BIC válido.",cifES:"Por favor, forneça um código CIF válido.",creditcardtypes:"Por favor, forneça um número de cartão de crédito válido.",currency:"Por favor, forneça uma moeda válida.",dateFA:"Por favor, forneça uma data correta.",dateITA:"Por favor, forneça uma data correta.",dateNL:"Por favor, forneça uma data correta.",extension:"Por favor, forneça um valor com uma extensão válida.",giroaccountNL:"Por favor, forneça um número de conta corrente válido.",iban:"Por favor, forneça um código IBAN válido.",integer:"Por favor, forneça um número não decimal.",ipv4:"Por favor, forneça um IPv4 válido.",ipv6:"Por favor, forneça um IPv6 válido.",lettersonly:"Por favor, forneça apenas com letras.",letterswithbasicpunc:"Por favor, forneça apenas letras ou pontuações.",mobileNL:"Por favor, forneceça um número válido de telefone.",mobileUK:"Por favor, forneceça um número válido de telefone.",nieES:"Por favor, forneça um NIE válido.",nifES:"Por favor, forneça um NIF válido.",nowhitespace:"Por favor, não utilize espaços em branco.",pattern:"O formato fornecido é inválido.",phoneNL:"Por favor, forneça um número de telefone válido.",phoneUK:"Por favor, forneça um número de telefone válido.",phoneUS:"Por favor, forneça um número de telefone válido.",phonesUK:"Por favor, forneça um número de telefone válido.",postalCodeCA:"Por favor, forneça um número de código postal válido.",postalcodeIT:"Por favor, forneça um número de código postal válido.",postalcodeNL:"Por favor, forneça um número de código postal válido.",postcodeUK:"Por favor, forneça um número de código postal válido.",postalcodeBR:"Por favor, forneça um CEP válido.",require_from_group:a.validator.format("Por favor, forneça pelo menos {0} destes campos."),skip_or_fill_minimum:a.validator.format("Por favor, optar entre ignorar esses campos ou preencher pelo menos {0} deles."),stateUS:"Por favor, forneça um estado válido.",strippedminlength:a.validator.format("Por favor, forneça pelo menos {0} caracteres."),time:"Por favor, forneça um horário válido, no intervado de 00:00 a 23:59.",time12h:"Por favor, forneça um horário válido, no intervado de 01:00 a 12:59 am/pm.",url2:"Por favor, forneça uma URL válida.",vinUS:"O número de identificação de veículo informado (VIN) é inválido.",zipcodeUS:"Por favor, forneça um código postal americano válido.",ziprange:"O código postal deve estar entre 902xx-xxxx e 905xx-xxxx",cpfBR:"Por favor, forneça um CPF válido.",nisBR:"Por favor, forneça um NIS/PIS válido",cnhBR:"Por favor, forneça um CNH válido.",cnpjBR:"Por favor, forneça um CNPJ válido."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.js new file mode 100644 index 0000000000..d3b3ae5794 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.js @@ -0,0 +1,39 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: PT (Portuguese; português) + * Region: PT (Portugal) + */ +$.extend( $.validator.messages, { + required: "Campo de preenchimento obrigatório.", + remote: "Por favor, corrija este campo.", + email: "Por favor, introduza um endereço eletrónico válido.", + url: "Por favor, introduza um URL válido.", + date: "Por favor, introduza uma data válida.", + dateISO: "Por favor, introduza uma data válida (ISO).", + number: "Por favor, introduza um número válido.", + digits: "Por favor, introduza apenas dígitos.", + creditcard: "Por favor, introduza um número de cartão de crédito válido.", + equalTo: "Por favor, introduza de novo o mesmo valor.", + extension: "Por favor, introduza um ficheiro com uma extensão válida.", + maxlength: $.validator.format( "Por favor, não introduza mais do que {0} caracteres." ), + minlength: $.validator.format( "Por favor, introduza pelo menos {0} caracteres." ), + rangelength: $.validator.format( "Por favor, introduza entre {0} e {1} caracteres." ), + range: $.validator.format( "Por favor, introduza um valor entre {0} e {1}." ), + max: $.validator.format( "Por favor, introduza um valor menor ou igual a {0}." ), + min: $.validator.format( "Por favor, introduza um valor maior ou igual a {0}." ), + nifES: "Por favor, introduza um NIF válido.", + nieES: "Por favor, introduza um NIE válido.", + cifES: "Por favor, introduza um CIF válido." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.min.js new file mode 100644 index 0000000000..3b9ef3629e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_pt_PT.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo de preenchimento obrigatório.",remote:"Por favor, corrija este campo.",email:"Por favor, introduza um endereço eletrónico válido.",url:"Por favor, introduza um URL válido.",date:"Por favor, introduza uma data válida.",dateISO:"Por favor, introduza uma data válida (ISO).",number:"Por favor, introduza um número válido.",digits:"Por favor, introduza apenas dígitos.",creditcard:"Por favor, introduza um número de cartão de crédito válido.",equalTo:"Por favor, introduza de novo o mesmo valor.",extension:"Por favor, introduza um ficheiro com uma extensão válida.",maxlength:a.validator.format("Por favor, não introduza mais do que {0} caracteres."),minlength:a.validator.format("Por favor, introduza pelo menos {0} caracteres."),rangelength:a.validator.format("Por favor, introduza entre {0} e {1} caracteres."),range:a.validator.format("Por favor, introduza um valor entre {0} e {1}."),max:a.validator.format("Por favor, introduza um valor menor ou igual a {0}."),min:a.validator.format("Por favor, introduza um valor maior ou igual a {0}."),nifES:"Por favor, introduza um NIF válido.",nieES:"Por favor, introduza um NIE válido.",cifES:"Por favor, introduza um CIF válido."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.js new file mode 100644 index 0000000000..45ce0c6115 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: RO (Romanian, limba română) + */ +$.extend( $.validator.messages, { + required: "Acest câmp este obligatoriu.", + remote: "Te rugăm să completezi acest câmp.", + email: "Te rugăm să introduci o adresă de email validă", + url: "Te rugăm sa introduci o adresă URL validă.", + date: "Te rugăm să introduci o dată corectă.", + dateISO: "Te rugăm să introduci o dată (ISO) corectă.", + number: "Te rugăm să introduci un număr întreg valid.", + digits: "Te rugăm să introduci doar cifre.", + creditcard: "Te rugăm să introduci un numar de carte de credit valid.", + equalTo: "Te rugăm să reintroduci valoarea.", + extension: "Te rugăm să introduci o valoare cu o extensie validă.", + maxlength: $.validator.format( "Te rugăm să nu introduci mai mult de {0} caractere." ), + minlength: $.validator.format( "Te rugăm să introduci cel puțin {0} caractere." ), + rangelength: $.validator.format( "Te rugăm să introduci o valoare între {0} și {1} caractere." ), + range: $.validator.format( "Te rugăm să introduci o valoare între {0} și {1}." ), + max: $.validator.format( "Te rugăm să introduci o valoare egal sau mai mică decât {0}." ), + min: $.validator.format( "Te rugăm să introduci o valoare egal sau mai mare decât {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.min.js new file mode 100644 index 0000000000..e1ba18507e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ro.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Acest câmp este obligatoriu.",remote:"Te rugăm să completezi acest câmp.",email:"Te rugăm să introduci o adresă de email validă",url:"Te rugăm sa introduci o adresă URL validă.",date:"Te rugăm să introduci o dată corectă.",dateISO:"Te rugăm să introduci o dată (ISO) corectă.",number:"Te rugăm să introduci un număr întreg valid.",digits:"Te rugăm să introduci doar cifre.",creditcard:"Te rugăm să introduci un numar de carte de credit valid.",equalTo:"Te rugăm să reintroduci valoarea.",extension:"Te rugăm să introduci o valoare cu o extensie validă.",maxlength:a.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."),minlength:a.validator.format("Te rugăm să introduci cel puțin {0} caractere."),rangelength:a.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."),range:a.validator.format("Te rugăm să introduci o valoare între {0} și {1}."),max:a.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."),min:a.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.js new file mode 100644 index 0000000000..9f600510d1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: RU (Russian; русский язык) + */ +$.extend( $.validator.messages, { + required: "Это поле необходимо заполнить.", + remote: "Пожалуйста, введите правильное значение.", + email: "Пожалуйста, введите корректный адрес электронной почты.", + url: "Пожалуйста, введите корректный URL.", + date: "Пожалуйста, введите корректную дату.", + dateISO: "Пожалуйста, введите корректную дату в формате ISO.", + number: "Пожалуйста, введите число.", + digits: "Пожалуйста, вводите только цифры.", + creditcard: "Пожалуйста, введите правильный номер кредитной карты.", + equalTo: "Пожалуйста, введите такое же значение ещё раз.", + extension: "Пожалуйста, выберите файл с правильным расширением.", + maxlength: $.validator.format( "Пожалуйста, введите не больше {0} символов." ), + minlength: $.validator.format( "Пожалуйста, введите не меньше {0} символов." ), + rangelength: $.validator.format( "Пожалуйста, введите значение длиной от {0} до {1} символов." ), + range: $.validator.format( "Пожалуйста, введите число от {0} до {1}." ), + max: $.validator.format( "Пожалуйста, введите число, меньшее или равное {0}." ), + min: $.validator.format( "Пожалуйста, введите число, большее или равное {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.min.js new file mode 100644 index 0000000000..4934d77181 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ru.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Это поле необходимо заполнить.",remote:"Пожалуйста, введите правильное значение.",email:"Пожалуйста, введите корректный адрес электронной почты.",url:"Пожалуйста, введите корректный URL.",date:"Пожалуйста, введите корректную дату.",dateISO:"Пожалуйста, введите корректную дату в формате ISO.",number:"Пожалуйста, введите число.",digits:"Пожалуйста, вводите только цифры.",creditcard:"Пожалуйста, введите правильный номер кредитной карты.",equalTo:"Пожалуйста, введите такое же значение ещё раз.",extension:"Пожалуйста, выберите файл с правильным расширением.",maxlength:a.validator.format("Пожалуйста, введите не больше {0} символов."),minlength:a.validator.format("Пожалуйста, введите не меньше {0} символов."),rangelength:a.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}."),max:a.validator.format("Пожалуйста, введите число, меньшее или равное {0}."),min:a.validator.format("Пожалуйста, введите число, большее или равное {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.js new file mode 100644 index 0000000000..25741679fb --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SD (Sindhi; سنڌي) + */ +$.extend( $.validator.messages, { + required: "هنن جاين جي ضرورت آهي", + remote: "هنن جاين جي ضرورت آهي", + email: "لکيل اي ميل غلط آهي", + url: "لکيل ايڊريس غلط آهي", + date: "لکيل تاريخ غلط آهي", + dateISO: "جي معيار جي مطابق نه آهي (ISO) لکيل تاريخ", + number: "لکيل انگ صحيح ناهي", + digits: "رڳو انگ داخل ڪري سگهجي ٿو", + creditcard: "لکيل ڪارڊ نمبر صحيح نه آهي", + equalTo: "داخل ٿيل ڀيٽ صحيح نه آهي", + extension: "لکيل غلط آهي", + maxlength: $.validator.format( "وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي" ), + minlength: $.validator.format( "گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي" ), + rangelength: $.validator.format( "داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي" ), + range: $.validator.format( "داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي" ), + max: $.validator.format( "وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي" ), + min: $.validator.format( "گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.min.js new file mode 100644 index 0000000000..d41d835da8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sd.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هنن جاين جي ضرورت آهي",remote:"هنن جاين جي ضرورت آهي",email:"لکيل اي ميل غلط آهي",url:"لکيل ايڊريس غلط آهي",date:"لکيل تاريخ غلط آهي",dateISO:"جي معيار جي مطابق نه آهي (ISO) لکيل تاريخ",number:"لکيل انگ صحيح ناهي",digits:"رڳو انگ داخل ڪري سگهجي ٿو",creditcard:"لکيل ڪارڊ نمبر صحيح نه آهي",equalTo:"داخل ٿيل ڀيٽ صحيح نه آهي",extension:"لکيل غلط آهي",maxlength:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),minlength:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي"),rangelength:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),range:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),max:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),min:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.js new file mode 100644 index 0000000000..8d45b74adf --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SI (Slovenian) + */ +$.extend( $.validator.messages, { + required: "To polje je obvezno.", + remote: "Vpis v tem polju ni v pravi obliki.", + email: "Prosimo, vnesite pravi email naslov.", + url: "Prosimo, vnesite pravi URL.", + date: "Prosimo, vnesite pravi datum.", + dateISO: "Prosimo, vnesite pravi datum (ISO).", + number: "Prosimo, vnesite pravo številko.", + digits: "Prosimo, vnesite samo številke.", + creditcard: "Prosimo, vnesite pravo številko kreditne kartice.", + equalTo: "Prosimo, ponovno vnesite enako vsebino.", + extension: "Prosimo, vnesite vsebino z pravo končnico.", + maxlength: $.validator.format( "Prosimo, da ne vnašate več kot {0} znakov." ), + minlength: $.validator.format( "Prosimo, vnesite vsaj {0} znakov." ), + rangelength: $.validator.format( "Prosimo, vnesite od {0} do {1} znakov." ), + range: $.validator.format( "Prosimo, vnesite vrednost med {0} in {1}." ), + max: $.validator.format( "Prosimo, vnesite vrednost manjšo ali enako {0}." ), + min: $.validator.format( "Prosimo, vnesite vrednost večjo ali enako {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.min.js new file mode 100644 index 0000000000..a64185ff95 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_si.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Vpis v tem polju ni v pravi obliki.",email:"Prosimo, vnesite pravi email naslov.",url:"Prosimo, vnesite pravi URL.",date:"Prosimo, vnesite pravi datum.",dateISO:"Prosimo, vnesite pravi datum (ISO).",number:"Prosimo, vnesite pravo številko.",digits:"Prosimo, vnesite samo številke.",creditcard:"Prosimo, vnesite pravo številko kreditne kartice.",equalTo:"Prosimo, ponovno vnesite enako vsebino.",extension:"Prosimo, vnesite vsebino z pravo končnico.",maxlength:a.validator.format("Prosimo, da ne vnašate več kot {0} znakov."),minlength:a.validator.format("Prosimo, vnesite vsaj {0} znakov."),rangelength:a.validator.format("Prosimo, vnesite od {0} do {1} znakov."),range:a.validator.format("Prosimo, vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo, vnesite vrednost manjšo ali enako {0}."),min:a.validator.format("Prosimo, vnesite vrednost večjo ali enako {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.js new file mode 100644 index 0000000000..0f9becf59f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.js @@ -0,0 +1,33 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SK (Slovak; slovenčina, slovenský jazyk) + */ +$.extend( $.validator.messages, { + required: "Povinné zadať.", + maxlength: $.validator.format( "Maximálne {0} znakov." ), + minlength: $.validator.format( "Minimálne {0} znakov." ), + rangelength: $.validator.format( "Minimálne {0} a maximálne {1} znakov." ), + email: "E-mailová adresa musí byť platná.", + url: "URL musí byť platná.", + date: "Musí byť dátum.", + number: "Musí byť číslo.", + digits: "Môže obsahovať iba číslice.", + equalTo: "Dve hodnoty sa musia rovnať.", + range: $.validator.format( "Musí byť medzi {0} a {1}." ), + max: $.validator.format( "Nemôže byť viac ako {0}." ), + min: $.validator.format( "Nemôže byť menej ako {0}." ), + creditcard: "Číslo platobnej karty musí byť platné.", + step: $.validator.format( "Musí byť násobkom čísla {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.min.js new file mode 100644 index 0000000000..d22ec47f57 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sk.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Povinné zadať.",maxlength:a.validator.format("Maximálne {0} znakov."),minlength:a.validator.format("Minimálne {0} znakov."),rangelength:a.validator.format("Minimálne {0} a maximálne {1} znakov."),email:"E-mailová adresa musí byť platná.",url:"URL musí byť platná.",date:"Musí byť dátum.",number:"Musí byť číslo.",digits:"Môže obsahovať iba číslice.",equalTo:"Dve hodnoty sa musia rovnať.",range:a.validator.format("Musí byť medzi {0} a {1}."),max:a.validator.format("Nemôže byť viac ako {0}."),min:a.validator.format("Nemôže byť menej ako {0}."),creditcard:"Číslo platobnej karty musí byť platné.",step:a.validator.format("Musí byť násobkom čísla {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.js new file mode 100644 index 0000000000..9902b44828 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Language: SL (Slovenian; slovenski jezik) + */ +$.extend( $.validator.messages, { + required: "To polje je obvezno.", + remote: "Prosimo popravite to polje.", + email: "Prosimo vnesite veljaven email naslov.", + url: "Prosimo vnesite veljaven URL naslov.", + date: "Prosimo vnesite veljaven datum.", + dateISO: "Prosimo vnesite veljaven ISO datum.", + number: "Prosimo vnesite veljavno število.", + digits: "Prosimo vnesite samo števila.", + creditcard: "Prosimo vnesite veljavno številko kreditne kartice.", + equalTo: "Prosimo ponovno vnesite vrednost.", + extension: "Prosimo vnesite vrednost z veljavno končnico.", + maxlength: $.validator.format( "Prosimo vnesite največ {0} znakov." ), + minlength: $.validator.format( "Prosimo vnesite najmanj {0} znakov." ), + rangelength: $.validator.format( "Prosimo vnesite najmanj {0} in največ {1} znakov." ), + range: $.validator.format( "Prosimo vnesite vrednost med {0} in {1}." ), + max: $.validator.format( "Prosimo vnesite vrednost manjše ali enako {0}." ), + min: $.validator.format( "Prosimo vnesite vrednost večje ali enako {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.min.js new file mode 100644 index 0000000000..b1dccbb6fc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sl.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Prosimo popravite to polje.",email:"Prosimo vnesite veljaven email naslov.",url:"Prosimo vnesite veljaven URL naslov.",date:"Prosimo vnesite veljaven datum.",dateISO:"Prosimo vnesite veljaven ISO datum.",number:"Prosimo vnesite veljavno število.",digits:"Prosimo vnesite samo števila.",creditcard:"Prosimo vnesite veljavno številko kreditne kartice.",equalTo:"Prosimo ponovno vnesite vrednost.",extension:"Prosimo vnesite vrednost z veljavno končnico.",maxlength:a.validator.format("Prosimo vnesite največ {0} znakov."),minlength:a.validator.format("Prosimo vnesite najmanj {0} znakov."),rangelength:a.validator.format("Prosimo vnesite najmanj {0} in največ {1} znakov."),range:a.validator.format("Prosimo vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo vnesite vrednost manjše ali enako {0}."),min:a.validator.format("Prosimo vnesite vrednost večje ali enako {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.js new file mode 100644 index 0000000000..d3136a9086 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SR (Serbian; српски језик) + */ +$.extend( $.validator.messages, { + required: "Поље је обавезно.", + remote: "Средите ово поље.", + email: "Унесите исправну и-мејл адресу.", + url: "Унесите исправан URL.", + date: "Унесите исправан датум.", + dateISO: "Унесите исправан датум (ISO).", + number: "Унесите исправан број.", + digits: "Унесите само цифе.", + creditcard: "Унесите исправан број кредитне картице.", + equalTo: "Унесите исту вредност поново.", + extension: "Унесите вредност са одговарајућом екстензијом.", + maxlength: $.validator.format( "Унесите мање од {0} карактера." ), + minlength: $.validator.format( "Унесите барем {0} карактера." ), + rangelength: $.validator.format( "Унесите вредност дугачку између {0} и {1} карактера." ), + range: $.validator.format( "Унесите вредност између {0} и {1}." ), + max: $.validator.format( "Унесите вредност мању или једнаку {0}." ), + min: $.validator.format( "Унесите вредност већу или једнаку {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.min.js new file mode 100644 index 0000000000..8151b963f1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Поље је обавезно.",remote:"Средите ово поље.",email:"Унесите исправну и-мејл адресу.",url:"Унесите исправан URL.",date:"Унесите исправан датум.",dateISO:"Унесите исправан датум (ISO).",number:"Унесите исправан број.",digits:"Унесите само цифе.",creditcard:"Унесите исправан број кредитне картице.",equalTo:"Унесите исту вредност поново.",extension:"Унесите вредност са одговарајућом екстензијом.",maxlength:a.validator.format("Унесите мање од {0} карактера."),minlength:a.validator.format("Унесите барем {0} карактера."),rangelength:a.validator.format("Унесите вредност дугачку између {0} и {1} карактера."),range:a.validator.format("Унесите вредност између {0} и {1}."),max:a.validator.format("Унесите вредност мању или једнаку {0}."),min:a.validator.format("Унесите вредност већу или једнаку {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.js new file mode 100644 index 0000000000..4d6857c973 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SR (Serbian - Latin alphabet; srpski jezik - latinica) + */ +$.extend( $.validator.messages, { + required: "Polje je obavezno.", + remote: "Sredite ovo polje.", + email: "Unesite ispravnu e-mail adresu", + url: "Unesite ispravan URL.", + date: "Unesite ispravan datum.", + dateISO: "Unesite ispravan datum (ISO).", + number: "Unesite ispravan broj.", + digits: "Unesite samo cifre.", + creditcard: "Unesite ispravan broj kreditne kartice.", + equalTo: "Unesite istu vrednost ponovo.", + extension: "Unesite vrednost sa odgovarajućom ekstenzijom.", + maxlength: $.validator.format( "Unesite manje od {0} karaktera." ), + minlength: $.validator.format( "Unesite barem {0} karaktera." ), + rangelength: $.validator.format( "Unesite vrednost dugačku između {0} i {1} karaktera." ), + range: $.validator.format( "Unesite vrednost između {0} i {1}." ), + max: $.validator.format( "Unesite vrednost manju ili jednaku {0}." ), + min: $.validator.format( "Unesite vrednost veću ili jednaku {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.min.js new file mode 100644 index 0000000000..15326ab6a1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sr_lat.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Polje je obavezno.",remote:"Sredite ovo polje.",email:"Unesite ispravnu e-mail adresu",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo cifre.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite istu vrednost ponovo.",extension:"Unesite vrednost sa odgovarajućom ekstenzijom.",maxlength:a.validator.format("Unesite manje od {0} karaktera."),minlength:a.validator.format("Unesite barem {0} karaktera."),rangelength:a.validator.format("Unesite vrednost dugačku između {0} i {1} karaktera."),range:a.validator.format("Unesite vrednost između {0} i {1}."),max:a.validator.format("Unesite vrednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrednost veću ili jednaku {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.js new file mode 100644 index 0000000000..c19e8ca021 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: SV (Swedish; Svenska) + */ +$.extend( $.validator.messages, { + required: "Detta fält är obligatoriskt.", + remote: "Var snäll och åtgärda detta fält.", + maxlength: $.validator.format( "Du får ange högst {0} tecken." ), + minlength: $.validator.format( "Du måste ange minst {0} tecken." ), + rangelength: $.validator.format( "Ange minst {0} och max {1} tecken." ), + email: "Ange en korrekt e-postadress.", + url: "Ange en korrekt URL.", + date: "Ange ett korrekt datum.", + dateISO: "Ange ett korrekt datum (ÅÅÅÅ-MM-DD).", + number: "Ange ett korrekt nummer.", + digits: "Ange endast siffror.", + equalTo: "Ange samma värde igen.", + range: $.validator.format( "Ange ett värde mellan {0} och {1}." ), + max: $.validator.format( "Ange ett värde som är mindre eller lika med {0}." ), + min: $.validator.format( "Ange ett värde som är större eller lika med {0}." ), + creditcard: "Ange ett korrekt kreditkortsnummer.", + pattern: "Ogiltigt format." +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.min.js new file mode 100644 index 0000000000..68a7676ee7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_sv.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Detta fält är obligatoriskt.",remote:"Var snäll och åtgärda detta fält.",maxlength:a.validator.format("Du får ange högst {0} tecken."),minlength:a.validator.format("Du måste ange minst {0} tecken."),rangelength:a.validator.format("Ange minst {0} och max {1} tecken."),email:"Ange en korrekt e-postadress.",url:"Ange en korrekt URL.",date:"Ange ett korrekt datum.",dateISO:"Ange ett korrekt datum (ÅÅÅÅ-MM-DD).",number:"Ange ett korrekt nummer.",digits:"Ange endast siffror.",equalTo:"Ange samma värde igen.",range:a.validator.format("Ange ett värde mellan {0} och {1}."),max:a.validator.format("Ange ett värde som är mindre eller lika med {0}."),min:a.validator.format("Ange ett värde som är större eller lika med {0}."),creditcard:"Ange ett korrekt kreditkortsnummer.",pattern:"Ogiltigt format."}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.js new file mode 100644 index 0000000000..0ca954d3a7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: TH (Thai; ไทย) + */ +$.extend( $.validator.messages, { + required: "โปรดระบุ", + remote: "โปรดแก้ไขให้ถูกต้อง", + email: "โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง", + url: "โปรดระบุ URL ที่ถูกต้อง", + date: "โปรดระบุวันที่ ที่ถูกต้อง", + dateISO: "โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).", + number: "โปรดระบุทศนิยมที่ถูกต้อง", + digits: "โปรดระบุจำนวนเต็มที่ถูกต้อง", + creditcard: "โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง", + equalTo: "โปรดระบุค่าเดิมอีกครั้ง", + extension: "โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง", + maxlength: $.validator.format( "โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ" ), + minlength: $.validator.format( "โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ" ), + rangelength: $.validator.format( "โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ" ), + range: $.validator.format( "โปรดระบุค่าระหว่าง {0} และ {1}" ), + max: $.validator.format( "โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}" ), + min: $.validator.format( "โปรดระบุค่ามากกว่าหรือเท่ากับ {0}" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.min.js new file mode 100644 index 0000000000..33771b31cd --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_th.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"โปรดระบุ",remote:"โปรดแก้ไขให้ถูกต้อง",email:"โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง",url:"โปรดระบุ URL ที่ถูกต้อง",date:"โปรดระบุวันที่ ที่ถูกต้อง",dateISO:"โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).",number:"โปรดระบุทศนิยมที่ถูกต้อง",digits:"โปรดระบุจำนวนเต็มที่ถูกต้อง",creditcard:"โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง",equalTo:"โปรดระบุค่าเดิมอีกครั้ง",extension:"โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง",maxlength:a.validator.format("โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ"),minlength:a.validator.format("โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ"),rangelength:a.validator.format("โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ"),range:a.validator.format("โปรดระบุค่าระหว่าง {0} และ {1}"),max:a.validator.format("โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}"),min:a.validator.format("โปรดระบุค่ามากกว่าหรือเท่ากับ {0}")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.js new file mode 100644 index 0000000000..dfe45feed0 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: TJ (Tajikistan; Забони тоҷикӣ) + */ +$.extend( $.validator.messages, { + required: "Ворид кардани ин филд маҷбури аст.", + remote: "Илтимос, маълумоти саҳеҳ ворид кунед.", + email: "Илтимос, почтаи электронии саҳеҳ ворид кунед.", + url: "Илтимос, URL адреси саҳеҳ ворид кунед.", + date: "Илтимос, таърихи саҳеҳ ворид кунед.", + dateISO: "Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.", + number: "Илтимос, рақамҳои саҳеҳ ворид кунед.", + digits: "Илтимос, танҳо рақам ворид кунед.", + creditcard: "Илтимос, кредит карди саҳеҳ ворид кунед.", + equalTo: "Илтимос, миқдори баробар ворид кунед.", + extension: "Илтимос, қофияи файлро дуруст интихоб кунед", + maxlength: $.validator.format( "Илтимос, бештар аз {0} рамз ворид накунед." ), + minlength: $.validator.format( "Илтимос, камтар аз {0} рамз ворид накунед." ), + rangelength: $.validator.format( "Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед." ), + range: $.validator.format( "Илтимос, аз {0} то {1} рақам зиёд ворид кунед." ), + max: $.validator.format( "Илтимос, бештар аз {0} рақам ворид накунед." ), + min: $.validator.format( "Илтимос, камтар аз {0} рақам ворид накунед." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.min.js new file mode 100644 index 0000000000..3ae8d22ddb --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tj.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ворид кардани ин филд маҷбури аст.",remote:"Илтимос, маълумоти саҳеҳ ворид кунед.",email:"Илтимос, почтаи электронии саҳеҳ ворид кунед.",url:"Илтимос, URL адреси саҳеҳ ворид кунед.",date:"Илтимос, таърихи саҳеҳ ворид кунед.",dateISO:"Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.",number:"Илтимос, рақамҳои саҳеҳ ворид кунед.",digits:"Илтимос, танҳо рақам ворид кунед.",creditcard:"Илтимос, кредит карди саҳеҳ ворид кунед.",equalTo:"Илтимос, миқдори баробар ворид кунед.",extension:"Илтимос, қофияи файлро дуруст интихоб кунед",maxlength:a.validator.format("Илтимос, бештар аз {0} рамз ворид накунед."),minlength:a.validator.format("Илтимос, камтар аз {0} рамз ворид накунед."),rangelength:a.validator.format("Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед."),range:a.validator.format("Илтимос, аз {0} то {1} рақам зиёд ворид кунед."),max:a.validator.format("Илтимос, бештар аз {0} рақам ворид накунед."),min:a.validator.format("Илтимос, камтар аз {0} рақам ворид накунед.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.js new file mode 100644 index 0000000000..bb8c32ee89 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.js @@ -0,0 +1,36 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: TR (Turkish; Türkçe) + */ +$.extend( $.validator.messages, { + required: "Bu alanın doldurulması zorunludur.", + remote: "Lütfen bu alanı düzeltin.", + email: "Lütfen geçerli bir e-posta adresi giriniz.", + url: "Lütfen geçerli bir web adresi (URL) giriniz.", + date: "Lütfen geçerli bir tarih giriniz.", + dateISO: "Lütfen geçerli bir tarih giriniz(ISO formatında)", + number: "Lütfen geçerli bir sayı giriniz.", + digits: "Lütfen sadece sayısal karakterler giriniz.", + creditcard: "Lütfen geçerli bir kredi kartı giriniz.", + equalTo: "Lütfen aynı değeri tekrar giriniz.", + extension: "Lütfen geçerli uzantıya sahip bir değer giriniz.", + maxlength: $.validator.format( "Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz." ), + minlength: $.validator.format( "Lütfen en az {0} karakter uzunluğunda bir değer giriniz." ), + rangelength: $.validator.format( "Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz." ), + range: $.validator.format( "Lütfen {0} ile {1} arasında bir değer giriniz." ), + max: $.validator.format( "Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz." ), + min: $.validator.format( "Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz." ), + require_from_group: $.validator.format( "Lütfen bu alanların en az {0} tanesini doldurunuz." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.min.js new file mode 100644 index 0000000000..ee95102664 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_tr.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu alanın doldurulması zorunludur.",remote:"Lütfen bu alanı düzeltin.",email:"Lütfen geçerli bir e-posta adresi giriniz.",url:"Lütfen geçerli bir web adresi (URL) giriniz.",date:"Lütfen geçerli bir tarih giriniz.",dateISO:"Lütfen geçerli bir tarih giriniz(ISO formatında)",number:"Lütfen geçerli bir sayı giriniz.",digits:"Lütfen sadece sayısal karakterler giriniz.",creditcard:"Lütfen geçerli bir kredi kartı giriniz.",equalTo:"Lütfen aynı değeri tekrar giriniz.",extension:"Lütfen geçerli uzantıya sahip bir değer giriniz.",maxlength:a.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."),minlength:a.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."),rangelength:a.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."),range:a.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."),max:a.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."),min:a.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz."),require_from_group:a.validator.format("Lütfen bu alanların en az {0} tanesini doldurunuz.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.js new file mode 100644 index 0000000000..9531a95718 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: UK (Ukrainian; українська мова) + */ +$.extend( $.validator.messages, { + required: "Це поле необхідно заповнити.", + remote: "Будь ласка, введіть правильне значення.", + email: "Будь ласка, введіть коректну адресу електронної пошти.", + url: "Будь ласка, введіть коректний URL.", + date: "Будь ласка, введіть коректну дату.", + dateISO: "Будь ласка, введіть коректну дату у форматі ISO.", + number: "Будь ласка, введіть число.", + digits: "Вводите потрібно лише цифри.", + creditcard: "Будь ласка, введіть правильний номер кредитної карти.", + equalTo: "Будь ласка, введіть таке ж значення ще раз.", + extension: "Будь ласка, виберіть файл з правильним розширенням.", + maxlength: $.validator.format( "Будь ласка, введіть не більше {0} символів." ), + minlength: $.validator.format( "Будь ласка, введіть не менше {0} символів." ), + rangelength: $.validator.format( "Будь ласка, введіть значення довжиною від {0} до {1} символів." ), + range: $.validator.format( "Будь ласка, введіть число від {0} до {1}." ), + max: $.validator.format( "Будь ласка, введіть число, менше або рівно {0}." ), + min: $.validator.format( "Будь ласка, введіть число, більше або рівно {0}." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.min.js new file mode 100644 index 0000000000..2951a660cc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_uk.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Це поле необхідно заповнити.",remote:"Будь ласка, введіть правильне значення.",email:"Будь ласка, введіть коректну адресу електронної пошти.",url:"Будь ласка, введіть коректний URL.",date:"Будь ласка, введіть коректну дату.",dateISO:"Будь ласка, введіть коректну дату у форматі ISO.",number:"Будь ласка, введіть число.",digits:"Вводите потрібно лише цифри.",creditcard:"Будь ласка, введіть правильний номер кредитної карти.",equalTo:"Будь ласка, введіть таке ж значення ще раз.",extension:"Будь ласка, виберіть файл з правильним розширенням.",maxlength:a.validator.format("Будь ласка, введіть не більше {0} символів."),minlength:a.validator.format("Будь ласка, введіть не менше {0} символів."),rangelength:a.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."),range:a.validator.format("Будь ласка, введіть число від {0} до {1}."),max:a.validator.format("Будь ласка, введіть число, менше або рівно {0}."),min:a.validator.format("Будь ласка, введіть число, більше або рівно {0}.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.js new file mode 100644 index 0000000000..1327da075c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: UR (Urdu; اردو) + */ +$.extend( $.validator.messages, { + required: "ان معلومات کا اندراج ضروری ہے", + remote: "ان معلومات کا اندراج ضروری ہے", + email: "درج کی ہوئی ای میل درست نہیں ہے", + url: "درج کیا گیا پتہ درست نہیں ہے", + date: "درج کی گئی تاریخ درست نہیں ہے", + dateISO: "معیار کے مطابق نہیں ہے (ISO) درج کی گئی تاریخ", + number: "درج کیےگئے ہندسے درست نہیں ہیں", + digits: "صرف ہندسے اندراج کئے جاسکتے ہیں", + creditcard: "درج کیا گیا کارڈ نمبر درست نہیں ہے", + equalTo: "اندراج کا موازنہ درست نہیں ہے", + extension: "اندراج درست نہیں ہے", + maxlength: $.validator.format( "زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں" ), + minlength: $.validator.format( "کم سے کم {0} کا اندراج کرنا ضروری ہے" ), + rangelength: $.validator.format( "اندراج کا {0} اور {1}کے درمیان ہونا ضروری ہے" ), + range: $.validator.format( "اندراج کا {0} اور {1} کے درمیان ہونا ضروری ہے" ), + max: $.validator.format( "زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں" ), + min: $.validator.format( "کم سے کم {0} کا اندراج کرنا ضروری ہے" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.min.js new file mode 100644 index 0000000000..50b5585571 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_ur.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ان معلومات کا اندراج ضروری ہے",remote:"ان معلومات کا اندراج ضروری ہے",email:"درج کی ہوئی ای میل درست نہیں ہے",url:"درج کیا گیا پتہ درست نہیں ہے",date:"درج کی گئی تاریخ درست نہیں ہے",dateISO:"معیار کے مطابق نہیں ہے (ISO) درج کی گئی تاریخ",number:"درج کیےگئے ہندسے درست نہیں ہیں",digits:"صرف ہندسے اندراج کئے جاسکتے ہیں",creditcard:"درج کیا گیا کارڈ نمبر درست نہیں ہے",equalTo:"اندراج کا موازنہ درست نہیں ہے",extension:"اندراج درست نہیں ہے",maxlength:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),minlength:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے"),rangelength:a.validator.format("اندراج کا {0} اور {1}کے درمیان ہونا ضروری ہے"),range:a.validator.format("اندراج کا {0} اور {1} کے درمیان ہونا ضروری ہے"),max:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),min:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.js new file mode 100644 index 0000000000..ae415453dc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.js @@ -0,0 +1,35 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: VI (Vietnamese; Tiếng Việt) + */ +$.extend( $.validator.messages, { + required: "Hãy nhập.", + remote: "Hãy sửa cho đúng.", + email: "Hãy nhập email.", + url: "Hãy nhập URL.", + date: "Hãy nhập ngày.", + dateISO: "Hãy nhập ngày (ISO).", + number: "Hãy nhập số.", + digits: "Hãy nhập chữ số.", + creditcard: "Hãy nhập số thẻ tín dụng.", + equalTo: "Hãy nhập thêm lần nữa.", + extension: "Phần mở rộng không đúng.", + maxlength: $.validator.format( "Hãy nhập từ {0} kí tự trở xuống." ), + minlength: $.validator.format( "Hãy nhập từ {0} kí tự trở lên." ), + rangelength: $.validator.format( "Hãy nhập từ {0} đến {1} kí tự." ), + range: $.validator.format( "Hãy nhập từ {0} đến {1}." ), + max: $.validator.format( "Hãy nhập từ {0} trở xuống." ), + min: $.validator.format( "Hãy nhập từ {0} trở lên." ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.min.js new file mode 100644 index 0000000000..5c7def95fe --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_vi.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Hãy nhập.",remote:"Hãy sửa cho đúng.",email:"Hãy nhập email.",url:"Hãy nhập URL.",date:"Hãy nhập ngày.",dateISO:"Hãy nhập ngày (ISO).",number:"Hãy nhập số.",digits:"Hãy nhập chữ số.",creditcard:"Hãy nhập số thẻ tín dụng.",equalTo:"Hãy nhập thêm lần nữa.",extension:"Phần mở rộng không đúng.",maxlength:a.validator.format("Hãy nhập từ {0} kí tự trở xuống."),minlength:a.validator.format("Hãy nhập từ {0} kí tự trở lên."),rangelength:a.validator.format("Hãy nhập từ {0} đến {1} kí tự."),range:a.validator.format("Hãy nhập từ {0} đến {1}."),max:a.validator.format("Hãy nhập từ {0} trở xuống."),min:a.validator.format("Hãy nhập từ {0} trở lên.")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.js new file mode 100644 index 0000000000..afc74ab066 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.js @@ -0,0 +1,36 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ZH (Chinese, 中文 (Zhōngwén), 汉语, 漢語) + */ +$.extend( $.validator.messages, { + required: "这是必填字段", + remote: "请修正此字段", + email: "请输入有效的电子邮件地址", + url: "请输入有效的网址", + date: "请输入有效的日期", + dateISO: "请输入有效的日期 (YYYY-MM-DD)", + number: "请输入有效的数字", + digits: "只能输入数字", + creditcard: "请输入有效的信用卡号码", + equalTo: "你的输入不相同", + extension: "请输入有效的后缀", + maxlength: $.validator.format( "最多可以输入 {0} 个字符" ), + minlength: $.validator.format( "最少要输入 {0} 个字符" ), + rangelength: $.validator.format( "请输入长度在 {0} 到 {1} 之间的字符串" ), + range: $.validator.format( "请输入范围在 {0} 到 {1} 之间的数值" ), + step: $.validator.format( "请输入 {0} 的整数倍值" ), + max: $.validator.format( "请输入不大于 {0} 的数值" ), + min: $.validator.format( "请输入不小于 {0} 的数值" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.min.js new file mode 100644 index 0000000000..f006f5108b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"这是必填字段",remote:"请修正此字段",email:"请输入有效的电子邮件地址",url:"请输入有效的网址",date:"请输入有效的日期",dateISO:"请输入有效的日期 (YYYY-MM-DD)",number:"请输入有效的数字",digits:"只能输入数字",creditcard:"请输入有效的信用卡号码",equalTo:"你的输入不相同",extension:"请输入有效的后缀",maxlength:a.validator.format("最多可以输入 {0} 个字符"),minlength:a.validator.format("最少要输入 {0} 个字符"),rangelength:a.validator.format("请输入长度在 {0} 到 {1} 之间的字符串"),range:a.validator.format("请输入范围在 {0} 到 {1} 之间的数值"),step:a.validator.format("请输入 {0} 的整数倍值"),max:a.validator.format("请输入不大于 {0} 的数值"),min:a.validator.format("请输入不小于 {0} 的数值")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.js new file mode 100644 index 0000000000..95065a5ba7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.js @@ -0,0 +1,36 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Translated default messages for the jQuery validation plugin. + * Locale: ZH (Chinese; 中文 (Zhōngwén), 汉语, 漢語) + * Region: TW (Taiwan) + */ +$.extend( $.validator.messages, { + required: "必須填寫", + remote: "請修正此欄位", + email: "請輸入有效的電子郵件", + url: "請輸入有效的網址", + date: "請輸入有效的日期", + dateISO: "請輸入有效的日期 (YYYY-MM-DD)", + number: "請輸入正確的數值", + digits: "只可輸入數字", + creditcard: "請輸入有效的信用卡號碼", + equalTo: "請重複輸入一次", + extension: "請輸入有效的後綴", + maxlength: $.validator.format( "最多 {0} 個字" ), + minlength: $.validator.format( "最少 {0} 個字" ), + rangelength: $.validator.format( "請輸入長度為 {0} 至 {1} 之間的字串" ), + range: $.validator.format( "請輸入 {0} 至 {1} 之間的數值" ), + max: $.validator.format( "請輸入不大於 {0} 的數值" ), + min: $.validator.format( "請輸入不小於 {0} 的數值" ) +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.min.js new file mode 100644 index 0000000000..e2474bc16f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/messages_zh_TW.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"必須填寫",remote:"請修正此欄位",email:"請輸入有效的電子郵件",url:"請輸入有效的網址",date:"請輸入有效的日期",dateISO:"請輸入有效的日期 (YYYY-MM-DD)",number:"請輸入正確的數值",digits:"只可輸入數字",creditcard:"請輸入有效的信用卡號碼",equalTo:"請重複輸入一次",extension:"請輸入有效的後綴",maxlength:a.validator.format("最多 {0} 個字"),minlength:a.validator.format("最少 {0} 個字"),rangelength:a.validator.format("請輸入長度為 {0} 至 {1} 之間的字串"),range:a.validator.format("請輸入 {0} 至 {1} 之間的數值"),max:a.validator.format("請輸入不大於 {0} 的數值"),min:a.validator.format("請輸入不小於 {0} 的數值")}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.js new file mode 100644 index 0000000000..da10e46984 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.js @@ -0,0 +1,24 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: DE + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test( value ); + }, + number: function( value, element ) { + return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.min.js new file mode 100644 index 0000000000..187560c1b3 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_de.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.js new file mode 100644 index 0000000000..fc8971e951 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.js @@ -0,0 +1,24 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: ES_CL + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d\d?\-\d\d?\-\d\d\d?\d?$/.test( value ); + }, + number: function( value, element ) { + return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.min.js new file mode 100644 index 0000000000..f25c78412e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_es_CL.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.js new file mode 100644 index 0000000000..bb7e95eac0 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.js @@ -0,0 +1,24 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: FI + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d{1,2}\.\d{1,2}\.\d{4}$/.test( value ); + }, + number: function( value, element ) { + return this.optional( element ) || /^-?(?:\d+)(?:,\d+)?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.min.js new file mode 100644 index 0000000000..59c86e0ccc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_fi.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d{1,2}\.\d{1,2}\.\d{4}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+)(?:,\d+)?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.js new file mode 100644 index 0000000000..b0ad79e501 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.js @@ -0,0 +1,24 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: IT + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d\d?\-\d\d?\-\d\d\d?\d?$/.test( value ); + }, + number: function( value, element ) { + return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.min.js new file mode 100644 index 0000000000..f25c78412e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_it.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.js new file mode 100644 index 0000000000..e83f337ff8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.js @@ -0,0 +1,24 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: NL + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test( value ); + }, + number: function( value, element ) { + return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.min.js new file mode 100644 index 0000000000..bf4f132826 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_nl.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.js new file mode 100644 index 0000000000..a74b65fd4c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.js @@ -0,0 +1,21 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: PT_BR + */ +$.extend( $.validator.methods, { + date: function( value, element ) { + return this.optional( element ) || /^\d\d?\/\d\d?\/\d\d\d?\d?$/.test( value ); + } +} ); +return $; +})); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.min.js new file mode 100644 index 0000000000..dfed4d2621 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery-validation/localization/methods_pt.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018 + * https://jqueryvalidation.org/ + * Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(a)}}),a}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery/jquery.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery/jquery.js new file mode 100644 index 0000000000..9b5206bcc6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/jquery/jquery.js @@ -0,0 +1,10364 @@ +/*! + * jQuery JavaScript Library v3.3.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2018-01-20T17:24Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + var preservedScriptAttributes = { + type: true, + src: true, + noModule: true + }; + + function DOMEval( code, doc, node ) { + doc = doc || document; + + var i, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + if ( node[ i ] ) { + script[ i ] = node[ i ]; + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.3.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && Array.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + disabledAncestor( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( nodeName( elem, "iframe" ) ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + div.style.position = "absolute"; + scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + ) ); + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + val = curCSS( elem, dimension, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox; + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = valueIsBorderBox && + ( support.boxSizingReliable() || val === elem.style[ dimension ] ); + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + if ( val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { + + val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; + + // offsetWidth/offsetHeight provide border-box values + valueIsBorderBox = true; + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra && boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ); + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && support.scrollboxSize() === styles.position ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + +``` + +```html + + +``` + +### Usage + +Wrap your items (`div`, `a`, `img`, `span`, `li` etc.) with a container element (`div`, `ul` etc.). Only the class `owl-carousel` is mandatory to apply proper styles: + +```html + +``` +**NOTE:** The `owl-theme` class is optional, but without it, you will need to style navigation features on your own. + + +Call the [plugin](https://learn.jquery.com/plugins/) function and your carousel is ready. + +```javascript +$(document).ready(function(){ + $('.owl-carousel').owlCarousel(); +}); +``` + +## Documentation + +The documentation, included in this repo in the root directory, is built with [Assemble](http://assemble.io/) and publicly available at https://owlcarousel2.github.io/OwlCarousel2/. The documentation may also be run locally. + +## Building + +This package comes with [Grunt](http://gruntjs.com/) and [Bower](http://bower.io/). The following tasks are available: + + * `default` compiles the CSS and JS into `/dist` and builds the doc. + * `dist` compiles the CSS and JS into `/dist` only. + * `watch` watches source files and builds them automatically whenever you save. + * `test` runs [JSHint](http://www.jshint.com/) and [QUnit](http://qunitjs.com/) tests headlessly in [PhantomJS](http://phantomjs.org/). + +To define which plugins are build into the distribution just edit `/_config.json` to fit your needs. + +## Contributing + +Please read [CONTRIBUTING.md](CONTRIBUTING.md). + +## Roadmap + +Please make sure to check out our [Roadmap Discussion](https://github.com/OwlCarousel2/OwlCarousel2/issues/1756). + + +## License + +The code and the documentation are released under the [MIT License](LICENSE). diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/ajax-loader.gif b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/ajax-loader.gif new file mode 100644 index 0000000000..d3962f9699 Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/ajax-loader.gif differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.css new file mode 100644 index 0000000000..40237bc65f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.css @@ -0,0 +1,186 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +/* + * Owl Carousel - Core + */ +.owl-carousel { + display: none; + width: 100%; + -webkit-tap-highlight-color: transparent; + /* position relative and z-index fix webkit rendering fonts issue */ + position: relative; + z-index: 1; } + .owl-carousel .owl-stage { + position: relative; + -ms-touch-action: pan-Y; + touch-action: manipulation; + -moz-backface-visibility: hidden; + /* fix firefox animation glitch */ } + .owl-carousel .owl-stage:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; } + .owl-carousel .owl-stage-outer { + position: relative; + overflow: hidden; + /* fix for flashing background */ + -webkit-transform: translate3d(0px, 0px, 0px); } + .owl-carousel .owl-wrapper, + .owl-carousel .owl-item { + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); } + .owl-carousel .owl-item { + position: relative; + min-height: 1px; + float: left; + -webkit-backface-visibility: hidden; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; } + .owl-carousel .owl-item img { + display: block; + width: 100%; } + .owl-carousel .owl-nav.disabled, + .owl-carousel .owl-dots.disabled { + display: none; } + .owl-carousel .owl-nav .owl-prev, + .owl-carousel .owl-nav .owl-next, + .owl-carousel .owl-dot { + cursor: pointer; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .owl-carousel .owl-nav button.owl-prev, + .owl-carousel .owl-nav button.owl-next, + .owl-carousel button.owl-dot { + background: none; + color: inherit; + border: none; + padding: 0 !important; + font: inherit; } + .owl-carousel.owl-loaded { + display: block; } + .owl-carousel.owl-loading { + opacity: 0; + display: block; } + .owl-carousel.owl-hidden { + opacity: 0; } + .owl-carousel.owl-refresh .owl-item { + visibility: hidden; } + .owl-carousel.owl-drag .owl-item { + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .owl-carousel.owl-grab { + cursor: move; + cursor: grab; } + .owl-carousel.owl-rtl { + direction: rtl; } + .owl-carousel.owl-rtl .owl-item { + float: right; } + +/* No Js */ +.no-js .owl-carousel { + display: block; } + +/* + * Owl Carousel - Animate Plugin + */ +.owl-carousel .animated { + animation-duration: 1000ms; + animation-fill-mode: both; } + +.owl-carousel .owl-animated-in { + z-index: 0; } + +.owl-carousel .owl-animated-out { + z-index: 1; } + +.owl-carousel .fadeOut { + animation-name: fadeOut; } + +@keyframes fadeOut { + 0% { + opacity: 1; } + 100% { + opacity: 0; } } + +/* + * Owl Carousel - Auto Height Plugin + */ +.owl-height { + transition: height 500ms ease-in-out; } + +/* + * Owl Carousel - Lazy Load Plugin + */ +.owl-carousel .owl-item { + /** + This is introduced due to a bug in IE11 where lazy loading combined with autoheight plugin causes a wrong + calculation of the height of the owl-item that breaks page layouts + */ } + .owl-carousel .owl-item .owl-lazy { + opacity: 0; + transition: opacity 400ms ease; } + .owl-carousel .owl-item .owl-lazy[src^=""], .owl-carousel .owl-item .owl-lazy:not([src]) { + max-height: 0; } + .owl-carousel .owl-item img.owl-lazy { + transform-style: preserve-3d; } + +/* + * Owl Carousel - Video Plugin + */ +.owl-carousel .owl-video-wrapper { + position: relative; + height: 100%; + background: #000; } + +.owl-carousel .owl-video-play-icon { + position: absolute; + height: 80px; + width: 80px; + left: 50%; + top: 50%; + margin-left: -40px; + margin-top: -40px; + background: url("owl.video.play.png") no-repeat; + cursor: pointer; + z-index: 1; + -webkit-backface-visibility: hidden; + transition: transform 100ms ease; } + +.owl-carousel .owl-video-play-icon:hover { + -ms-transform: scale(1.3, 1.3); + transform: scale(1.3, 1.3); } + +.owl-carousel .owl-video-playing .owl-video-tn, +.owl-carousel .owl-video-playing .owl-video-play-icon { + display: none; } + +.owl-carousel .owl-video-tn { + opacity: 0; + height: 100%; + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + transition: opacity 400ms ease; } + +.owl-carousel .owl-video-frame { + position: relative; + z-index: 1; + height: 100%; + width: 100%; } diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.min.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.min.css new file mode 100644 index 0000000000..a71df11c01 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.carousel.min.css @@ -0,0 +1,6 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +.owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;touch-action:manipulation;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel .owl-nav button.owl-next,.owl-carousel .owl-nav button.owl-prev,.owl-carousel button.owl-dot{background:0 0;color:inherit;border:none;padding:0!important;font:inherit}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-ms-touch-action:pan-y;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item .owl-lazy:not([src]),.owl-carousel .owl-item .owl-lazy[src^=""]{max-height:0}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%} \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.css new file mode 100644 index 0000000000..e2020fb101 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.css @@ -0,0 +1,50 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +/* + * Default theme - Owl Carousel CSS File + */ +.owl-theme .owl-nav { + margin-top: 10px; + text-align: center; + -webkit-tap-highlight-color: transparent; } + .owl-theme .owl-nav [class*='owl-'] { + color: #FFF; + font-size: 14px; + margin: 5px; + padding: 4px 7px; + background: #D6D6D6; + display: inline-block; + cursor: pointer; + border-radius: 3px; } + .owl-theme .owl-nav [class*='owl-']:hover { + background: #869791; + color: #FFF; + text-decoration: none; } + .owl-theme .owl-nav .disabled { + opacity: 0.5; + cursor: default; } + +.owl-theme .owl-nav.disabled + .owl-dots { + margin-top: 10px; } + +.owl-theme .owl-dots { + text-align: center; + -webkit-tap-highlight-color: transparent; } + .owl-theme .owl-dots .owl-dot { + display: inline-block; + zoom: 1; + *display: inline; } + .owl-theme .owl-dots .owl-dot span { + width: 10px; + height: 10px; + margin: 5px 7px; + background: #D6D6D6; + display: block; + -webkit-backface-visibility: visible; + transition: opacity 200ms ease; + border-radius: 30px; } + .owl-theme .owl-dots .owl-dot.active span, .owl-theme .owl-dots .owl-dot:hover span { + background: #869791; } diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.min.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.min.css new file mode 100644 index 0000000000..487088d2e3 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.default.min.css @@ -0,0 +1,6 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +.owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#869791;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#869791} \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.css new file mode 100644 index 0000000000..5235fbe3bc --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.css @@ -0,0 +1,50 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +/* + * Green theme - Owl Carousel CSS File + */ +.owl-theme .owl-nav { + margin-top: 10px; + text-align: center; + -webkit-tap-highlight-color: transparent; } + .owl-theme .owl-nav [class*='owl-'] { + color: #FFF; + font-size: 14px; + margin: 5px; + padding: 4px 7px; + background: #D6D6D6; + display: inline-block; + cursor: pointer; + border-radius: 3px; } + .owl-theme .owl-nav [class*='owl-']:hover { + background: #4DC7A0; + color: #FFF; + text-decoration: none; } + .owl-theme .owl-nav .disabled { + opacity: 0.5; + cursor: default; } + +.owl-theme .owl-nav.disabled + .owl-dots { + margin-top: 10px; } + +.owl-theme .owl-dots { + text-align: center; + -webkit-tap-highlight-color: transparent; } + .owl-theme .owl-dots .owl-dot { + display: inline-block; + zoom: 1; + *display: inline; } + .owl-theme .owl-dots .owl-dot span { + width: 10px; + height: 10px; + margin: 5px 7px; + background: #D6D6D6; + display: block; + -webkit-backface-visibility: visible; + transition: opacity 200ms ease; + border-radius: 30px; } + .owl-theme .owl-dots .owl-dot.active span, .owl-theme .owl-dots .owl-dot:hover span { + background: #4DC7A0; } diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.min.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.min.css new file mode 100644 index 0000000000..187bea0879 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.theme.green.min.css @@ -0,0 +1,6 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +.owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#4DC7A0;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#4DC7A0} \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.video.play.png b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.video.play.png new file mode 100644 index 0000000000..5d0218d466 Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/assets/owl.video.play.png differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/owl.carousel.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/owl.carousel.js new file mode 100644 index 0000000000..66c67ebe09 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/owl.carousel/owl.carousel.js @@ -0,0 +1,3448 @@ +/** + * Owl Carousel v2.3.4 + * Copyright 2013-2018 David Deutsch + * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE + */ +/** + * Owl carousel + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author David Deutsch + * @license The MIT License (MIT) + * @todo Lazy Load Icon + * @todo prevent animationend bubling + * @todo itemsScaleUp + * @todo Test Zepto + * @todo stagePadding calculate wrong active classes + */ +;(function($, window, document, undefined) { + + /** + * Creates a carousel. + * @class The Owl Carousel. + * @public + * @param {HTMLElement|jQuery} element - The element to create the carousel for. + * @param {Object} [options] - The options + */ + function Owl(element, options) { + + /** + * Current settings for the carousel. + * @public + */ + this.settings = null; + + /** + * Current options set by the caller including defaults. + * @public + */ + this.options = $.extend({}, Owl.Defaults, options); + + /** + * Plugin element. + * @public + */ + this.$element = $(element); + + /** + * Proxied event handlers. + * @protected + */ + this._handlers = {}; + + /** + * References to the running plugins of this carousel. + * @protected + */ + this._plugins = {}; + + /** + * Currently suppressed events to prevent them from being retriggered. + * @protected + */ + this._supress = {}; + + /** + * Absolute current position. + * @protected + */ + this._current = null; + + /** + * Animation speed in milliseconds. + * @protected + */ + this._speed = null; + + /** + * Coordinates of all items in pixel. + * @todo The name of this member is missleading. + * @protected + */ + this._coordinates = []; + + /** + * Current breakpoint. + * @todo Real media queries would be nice. + * @protected + */ + this._breakpoint = null; + + /** + * Current width of the plugin element. + */ + this._width = null; + + /** + * All real items. + * @protected + */ + this._items = []; + + /** + * All cloned items. + * @protected + */ + this._clones = []; + + /** + * Merge values of all items. + * @todo Maybe this could be part of a plugin. + * @protected + */ + this._mergers = []; + + /** + * Widths of all items. + */ + this._widths = []; + + /** + * Invalidated parts within the update process. + * @protected + */ + this._invalidated = {}; + + /** + * Ordered list of workers for the update process. + * @protected + */ + this._pipe = []; + + /** + * Current state information for the drag operation. + * @todo #261 + * @protected + */ + this._drag = { + time: null, + target: null, + pointer: null, + stage: { + start: null, + current: null + }, + direction: null + }; + + /** + * Current state information and their tags. + * @type {Object} + * @protected + */ + this._states = { + current: {}, + tags: { + 'initializing': [ 'busy' ], + 'animating': [ 'busy' ], + 'dragging': [ 'interacting' ] + } + }; + + $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { + this._handlers[handler] = $.proxy(this[handler], this); + }, this)); + + $.each(Owl.Plugins, $.proxy(function(key, plugin) { + this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] + = new plugin(this); + }, this)); + + $.each(Owl.Workers, $.proxy(function(priority, worker) { + this._pipe.push({ + 'filter': worker.filter, + 'run': $.proxy(worker.run, this) + }); + }, this)); + + this.setup(); + this.initialize(); + } + + /** + * Default options for the carousel. + * @public + */ + Owl.Defaults = { + items: 3, + loop: false, + center: false, + rewind: false, + checkVisibility: true, + + mouseDrag: true, + touchDrag: true, + pullDrag: true, + freeDrag: false, + + margin: 0, + stagePadding: 0, + + merge: false, + mergeFit: true, + autoWidth: false, + + startPosition: 0, + rtl: false, + + smartSpeed: 250, + fluidSpeed: false, + dragEndSpeed: false, + + responsive: {}, + responsiveRefreshRate: 200, + responsiveBaseElement: window, + + fallbackEasing: 'swing', + slideTransition: '', + + info: false, + + nestedItemSelector: false, + itemElement: 'div', + stageElement: 'div', + + refreshClass: 'owl-refresh', + loadedClass: 'owl-loaded', + loadingClass: 'owl-loading', + rtlClass: 'owl-rtl', + responsiveClass: 'owl-responsive', + dragClass: 'owl-drag', + itemClass: 'owl-item', + stageClass: 'owl-stage', + stageOuterClass: 'owl-stage-outer', + grabClass: 'owl-grab' + }; + + /** + * Enumeration for width. + * @public + * @readonly + * @enum {String} + */ + Owl.Width = { + Default: 'default', + Inner: 'inner', + Outer: 'outer' + }; + + /** + * Enumeration for types. + * @public + * @readonly + * @enum {String} + */ + Owl.Type = { + Event: 'event', + State: 'state' + }; + + /** + * Contains all registered plugins. + * @public + */ + Owl.Plugins = {}; + + /** + * List of workers involved in the update process. + */ + Owl.Workers = [ { + filter: [ 'width', 'settings' ], + run: function() { + this._width = this.$element.width(); + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function(cache) { + cache.current = this._items && this._items[this.relative(this._current)]; + } + }, { + filter: [ 'items', 'settings' ], + run: function() { + this.$stage.children('.cloned').remove(); + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function(cache) { + var margin = this.settings.margin || '', + grid = !this.settings.autoWidth, + rtl = this.settings.rtl, + css = { + 'width': 'auto', + 'margin-left': rtl ? margin : '', + 'margin-right': rtl ? '' : margin + }; + + !grid && this.$stage.children().css(css); + + cache.css = css; + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function(cache) { + var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin, + merge = null, + iterator = this._items.length, + grid = !this.settings.autoWidth, + widths = []; + + cache.items = { + merge: false, + width: width + }; + + while (iterator--) { + merge = this._mergers[iterator]; + merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; + + cache.items.merge = merge > 1 || cache.items.merge; + + widths[iterator] = !grid ? this._items[iterator].width() : width * merge; + } + + this._widths = widths; + } + }, { + filter: [ 'items', 'settings' ], + run: function() { + var clones = [], + items = this._items, + settings = this.settings, + // TODO: Should be computed from number of min width items in stage + view = Math.max(settings.items * 2, 4), + size = Math.ceil(items.length / 2) * 2, + repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, + append = '', + prepend = ''; + + repeat /= 2; + + while (repeat > 0) { + // Switch to only using appended clones + clones.push(this.normalize(clones.length / 2, true)); + append = append + items[clones[clones.length - 1]][0].outerHTML; + clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); + prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; + repeat -= 1; + } + + this._clones = clones; + + $(append).addClass('cloned').appendTo(this.$stage); + $(prepend).addClass('cloned').prependTo(this.$stage); + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function() { + var rtl = this.settings.rtl ? 1 : -1, + size = this._clones.length + this._items.length, + iterator = -1, + previous = 0, + current = 0, + coordinates = []; + + while (++iterator < size) { + previous = coordinates[iterator - 1] || 0; + current = this._widths[this.relative(iterator)] + this.settings.margin; + coordinates.push(previous + current * rtl); + } + + this._coordinates = coordinates; + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function() { + var padding = this.settings.stagePadding, + coordinates = this._coordinates, + css = { + 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, + 'padding-left': padding || '', + 'padding-right': padding || '' + }; + + this.$stage.css(css); + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function(cache) { + var iterator = this._coordinates.length, + grid = !this.settings.autoWidth, + items = this.$stage.children(); + + if (grid && cache.items.merge) { + while (iterator--) { + cache.css.width = this._widths[this.relative(iterator)]; + items.eq(iterator).css(cache.css); + } + } else if (grid) { + cache.css.width = cache.items.width; + items.css(cache.css); + } + } + }, { + filter: [ 'items' ], + run: function() { + this._coordinates.length < 1 && this.$stage.removeAttr('style'); + } + }, { + filter: [ 'width', 'items', 'settings' ], + run: function(cache) { + cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; + cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); + this.reset(cache.current); + } + }, { + filter: [ 'position' ], + run: function() { + this.animate(this.coordinates(this._current)); + } + }, { + filter: [ 'width', 'position', 'items', 'settings' ], + run: function() { + var rtl = this.settings.rtl ? 1 : -1, + padding = this.settings.stagePadding * 2, + begin = this.coordinates(this.current()) + padding, + end = begin + this.width() * rtl, + inner, outer, matches = [], i, n; + + for (i = 0, n = this._coordinates.length; i < n; i++) { + inner = this._coordinates[i - 1] || 0; + outer = Math.abs(this._coordinates[i]) + padding * rtl; + + if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) + || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { + matches.push(i); + } + } + + this.$stage.children('.active').removeClass('active'); + this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); + + this.$stage.children('.center').removeClass('center'); + if (this.settings.center) { + this.$stage.children().eq(this.current()).addClass('center'); + } + } + } ]; + + /** + * Create the stage DOM element + */ + Owl.prototype.initializeStage = function() { + this.$stage = this.$element.find('.' + this.settings.stageClass); + + // if the stage is already in the DOM, grab it and skip stage initialization + if (this.$stage.length) { + return; + } + + this.$element.addClass(this.options.loadingClass); + + // create stage + this.$stage = $('<' + this.settings.stageElement + '>', { + "class": this.settings.stageClass + }).wrap( $( '
    ', { + "class": this.settings.stageOuterClass + })); + + // append stage + this.$element.append(this.$stage.parent()); + }; + + /** + * Create item DOM elements + */ + Owl.prototype.initializeItems = function() { + var $items = this.$element.find('.owl-item'); + + // if the items are already in the DOM, grab them and skip item initialization + if ($items.length) { + this._items = $items.get().map(function(item) { + return $(item); + }); + + this._mergers = this._items.map(function() { + return 1; + }); + + this.refresh(); + + return; + } + + // append content + this.replace(this.$element.children().not(this.$stage.parent())); + + // check visibility + if (this.isVisible()) { + // update view + this.refresh(); + } else { + // invalidate width + this.invalidate('width'); + } + + this.$element + .removeClass(this.options.loadingClass) + .addClass(this.options.loadedClass); + }; + + /** + * Initializes the carousel. + * @protected + */ + Owl.prototype.initialize = function() { + this.enter('initializing'); + this.trigger('initialize'); + + this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); + + if (this.settings.autoWidth && !this.is('pre-loading')) { + var imgs, nestedSelector, width; + imgs = this.$element.find('img'); + nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; + width = this.$element.children(nestedSelector).width(); + + if (imgs.length && width <= 0) { + this.preloadAutoWidthImages(imgs); + } + } + + this.initializeStage(); + this.initializeItems(); + + // register event handlers + this.registerEventHandlers(); + + this.leave('initializing'); + this.trigger('initialized'); + }; + + /** + * @returns {Boolean} visibility of $element + * if you know the carousel will always be visible you can set `checkVisibility` to `false` to + * prevent the expensive browser layout forced reflow the $element.is(':visible') does + */ + Owl.prototype.isVisible = function() { + return this.settings.checkVisibility + ? this.$element.is(':visible') + : true; + }; + + /** + * Setups the current settings. + * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? + * @todo Support for media queries by using `matchMedia` would be nice. + * @public + */ + Owl.prototype.setup = function() { + var viewport = this.viewport(), + overwrites = this.options.responsive, + match = -1, + settings = null; + + if (!overwrites) { + settings = $.extend({}, this.options); + } else { + $.each(overwrites, function(breakpoint) { + if (breakpoint <= viewport && breakpoint > match) { + match = Number(breakpoint); + } + }); + + settings = $.extend({}, this.options, overwrites[match]); + if (typeof settings.stagePadding === 'function') { + settings.stagePadding = settings.stagePadding(); + } + delete settings.responsive; + + // responsive class + if (settings.responsiveClass) { + this.$element.attr('class', + this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) + ); + } + } + + this.trigger('change', { property: { name: 'settings', value: settings } }); + this._breakpoint = match; + this.settings = settings; + this.invalidate('settings'); + this.trigger('changed', { property: { name: 'settings', value: this.settings } }); + }; + + /** + * Updates option logic if necessery. + * @protected + */ + Owl.prototype.optionsLogic = function() { + if (this.settings.autoWidth) { + this.settings.stagePadding = false; + this.settings.merge = false; + } + }; + + /** + * Prepares an item before add. + * @todo Rename event parameter `content` to `item`. + * @protected + * @returns {jQuery|HTMLElement} - The item container. + */ + Owl.prototype.prepare = function(item) { + var event = this.trigger('prepare', { content: item }); + + if (!event.data) { + event.data = $('<' + this.settings.itemElement + '/>') + .addClass(this.options.itemClass).append(item) + } + + this.trigger('prepared', { content: event.data }); + + return event.data; + }; + + /** + * Updates the view. + * @public + */ + Owl.prototype.update = function() { + var i = 0, + n = this._pipe.length, + filter = $.proxy(function(p) { return this[p] }, this._invalidated), + cache = {}; + + while (i < n) { + if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { + this._pipe[i].run(cache); + } + i++; + } + + this._invalidated = {}; + + !this.is('valid') && this.enter('valid'); + }; + + /** + * Gets the width of the view. + * @public + * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. + * @returns {Number} - The width of the view in pixel. + */ + Owl.prototype.width = function(dimension) { + dimension = dimension || Owl.Width.Default; + switch (dimension) { + case Owl.Width.Inner: + case Owl.Width.Outer: + return this._width; + default: + return this._width - this.settings.stagePadding * 2 + this.settings.margin; + } + }; + + /** + * Refreshes the carousel primarily for adaptive purposes. + * @public + */ + Owl.prototype.refresh = function() { + this.enter('refreshing'); + this.trigger('refresh'); + + this.setup(); + + this.optionsLogic(); + + this.$element.addClass(this.options.refreshClass); + + this.update(); + + this.$element.removeClass(this.options.refreshClass); + + this.leave('refreshing'); + this.trigger('refreshed'); + }; + + /** + * Checks window `resize` event. + * @protected + */ + Owl.prototype.onThrottledResize = function() { + window.clearTimeout(this.resizeTimer); + this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); + }; + + /** + * Checks window `resize` event. + * @protected + */ + Owl.prototype.onResize = function() { + if (!this._items.length) { + return false; + } + + if (this._width === this.$element.width()) { + return false; + } + + if (!this.isVisible()) { + return false; + } + + this.enter('resizing'); + + if (this.trigger('resize').isDefaultPrevented()) { + this.leave('resizing'); + return false; + } + + this.invalidate('width'); + + this.refresh(); + + this.leave('resizing'); + this.trigger('resized'); + }; + + /** + * Registers event handlers. + * @todo Check `msPointerEnabled` + * @todo #261 + * @protected + */ + Owl.prototype.registerEventHandlers = function() { + if ($.support.transition) { + this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); + } + + if (this.settings.responsive !== false) { + this.on(window, 'resize', this._handlers.onThrottledResize); + } + + if (this.settings.mouseDrag) { + this.$element.addClass(this.options.dragClass); + this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); + this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); + } + + if (this.settings.touchDrag){ + this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); + this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); + } + }; + + /** + * Handles `touchstart` and `mousedown` events. + * @todo Horizontal swipe threshold as option + * @todo #261 + * @protected + * @param {Event} event - The event arguments. + */ + Owl.prototype.onDragStart = function(event) { + var stage = null; + + if (event.which === 3) { + return; + } + + if ($.support.transform) { + stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); + stage = { + x: stage[stage.length === 16 ? 12 : 4], + y: stage[stage.length === 16 ? 13 : 5] + }; + } else { + stage = this.$stage.position(); + stage = { + x: this.settings.rtl ? + stage.left + this.$stage.width() - this.width() + this.settings.margin : + stage.left, + y: stage.top + }; + } + + if (this.is('animating')) { + $.support.transform ? this.animate(stage.x) : this.$stage.stop() + this.invalidate('position'); + } + + this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); + + this.speed(0); + + this._drag.time = new Date().getTime(); + this._drag.target = $(event.target); + this._drag.stage.start = stage; + this._drag.stage.current = stage; + this._drag.pointer = this.pointer(event); + + $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); + + $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { + var delta = this.difference(this._drag.pointer, this.pointer(event)); + + $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); + + if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { + return; + } + + event.preventDefault(); + + this.enter('dragging'); + this.trigger('drag'); + }, this)); + }; + + /** + * Handles the `touchmove` and `mousemove` events. + * @todo #261 + * @protected + * @param {Event} event - The event arguments. + */ + Owl.prototype.onDragMove = function(event) { + var minimum = null, + maximum = null, + pull = null, + delta = this.difference(this._drag.pointer, this.pointer(event)), + stage = this.difference(this._drag.stage.start, delta); + + if (!this.is('dragging')) { + return; + } + + event.preventDefault(); + + if (this.settings.loop) { + minimum = this.coordinates(this.minimum()); + maximum = this.coordinates(this.maximum() + 1) - minimum; + stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; + } else { + minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); + maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); + pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; + stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); + } + + this._drag.stage.current = stage; + + this.animate(stage.x); + }; + + /** + * Handles the `touchend` and `mouseup` events. + * @todo #261 + * @todo Threshold for click event + * @protected + * @param {Event} event - The event arguments. + */ + Owl.prototype.onDragEnd = function(event) { + var delta = this.difference(this._drag.pointer, this.pointer(event)), + stage = this._drag.stage.current, + direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; + + $(document).off('.owl.core'); + + this.$element.removeClass(this.options.grabClass); + + if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { + this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); + this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); + this.invalidate('position'); + this.update(); + + this._drag.direction = direction; + + if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { + this._drag.target.one('click.owl.core', function() { return false; }); + } + } + + if (!this.is('dragging')) { + return; + } + + this.leave('dragging'); + this.trigger('dragged'); + }; + + /** + * Gets absolute position of the closest item for a coordinate. + * @todo Setting `freeDrag` makes `closest` not reusable. See #165. + * @protected + * @param {Number} coordinate - The coordinate in pixel. + * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. + * @return {Number} - The absolute position of the closest item. + */ + Owl.prototype.closest = function(coordinate, direction) { + var position = -1, + pull = 30, + width = this.width(), + coordinates = this.coordinates(); + + if (!this.settings.freeDrag) { + // check closest item + $.each(coordinates, $.proxy(function(index, value) { + // on a left pull, check on current index + if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) { + position = index; + // on a right pull, check on previous index + // to do so, subtract width from value and set position = index + 1 + } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) { + position = index + 1; + } else if (this.op(coordinate, '<', value) + && this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) { + position = direction === 'left' ? index + 1 : index; + } + return position === -1; + }, this)); + } + + if (!this.settings.loop) { + // non loop boundries + if (this.op(coordinate, '>', coordinates[this.minimum()])) { + position = coordinate = this.minimum(); + } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { + position = coordinate = this.maximum(); + } + } + + return position; + }; + + /** + * Animates the stage. + * @todo #270 + * @public + * @param {Number} coordinate - The coordinate in pixels. + */ + Owl.prototype.animate = function(coordinate) { + var animate = this.speed() > 0; + + this.is('animating') && this.onTransitionEnd(); + + if (animate) { + this.enter('animating'); + this.trigger('translate'); + } + + if ($.support.transform3d && $.support.transition) { + this.$stage.css({ + transform: 'translate3d(' + coordinate + 'px,0px,0px)', + transition: (this.speed() / 1000) + 's' + ( + this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' + ) + }); + } else if (animate) { + this.$stage.animate({ + left: coordinate + 'px' + }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); + } else { + this.$stage.css({ + left: coordinate + 'px' + }); + } + }; + + /** + * Checks whether the carousel is in a specific state or not. + * @param {String} state - The state to check. + * @returns {Boolean} - The flag which indicates if the carousel is busy. + */ + Owl.prototype.is = function(state) { + return this._states.current[state] && this._states.current[state] > 0; + }; + + /** + * Sets the absolute position of the current item. + * @public + * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. + * @returns {Number} - The absolute position of the current item. + */ + Owl.prototype.current = function(position) { + if (position === undefined) { + return this._current; + } + + if (this._items.length === 0) { + return undefined; + } + + position = this.normalize(position); + + if (this._current !== position) { + var event = this.trigger('change', { property: { name: 'position', value: position } }); + + if (event.data !== undefined) { + position = this.normalize(event.data); + } + + this._current = position; + + this.invalidate('position'); + + this.trigger('changed', { property: { name: 'position', value: this._current } }); + } + + return this._current; + }; + + /** + * Invalidates the given part of the update routine. + * @param {String} [part] - The part to invalidate. + * @returns {Array.} - The invalidated parts. + */ + Owl.prototype.invalidate = function(part) { + if ($.type(part) === 'string') { + this._invalidated[part] = true; + this.is('valid') && this.leave('valid'); + } + return $.map(this._invalidated, function(v, i) { return i }); + }; + + /** + * Resets the absolute position of the current item. + * @public + * @param {Number} position - The absolute position of the new item. + */ + Owl.prototype.reset = function(position) { + position = this.normalize(position); + + if (position === undefined) { + return; + } + + this._speed = 0; + this._current = position; + + this.suppress([ 'translate', 'translated' ]); + + this.animate(this.coordinates(position)); + + this.release([ 'translate', 'translated' ]); + }; + + /** + * Normalizes an absolute or a relative position of an item. + * @public + * @param {Number} position - The absolute or relative position to normalize. + * @param {Boolean} [relative=false] - Whether the given position is relative or not. + * @returns {Number} - The normalized position. + */ + Owl.prototype.normalize = function(position, relative) { + var n = this._items.length, + m = relative ? 0 : this._clones.length; + + if (!this.isNumeric(position) || n < 1) { + position = undefined; + } else if (position < 0 || position >= n + m) { + position = ((position - m / 2) % n + n) % n + m / 2; + } + + return position; + }; + + /** + * Converts an absolute position of an item into a relative one. + * @public + * @param {Number} position - The absolute position to convert. + * @returns {Number} - The converted position. + */ + Owl.prototype.relative = function(position) { + position -= this._clones.length / 2; + return this.normalize(position, true); + }; + + /** + * Gets the maximum position for the current item. + * @public + * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. + * @returns {Number} + */ + Owl.prototype.maximum = function(relative) { + var settings = this.settings, + maximum = this._coordinates.length, + iterator, + reciprocalItemsWidth, + elementWidth; + + if (settings.loop) { + maximum = this._clones.length / 2 + this._items.length - 1; + } else if (settings.autoWidth || settings.merge) { + iterator = this._items.length; + if (iterator) { + reciprocalItemsWidth = this._items[--iterator].width(); + elementWidth = this.$element.width(); + while (iterator--) { + reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin; + if (reciprocalItemsWidth > elementWidth) { + break; + } + } + } + maximum = iterator + 1; + } else if (settings.center) { + maximum = this._items.length - 1; + } else { + maximum = this._items.length - settings.items; + } + + if (relative) { + maximum -= this._clones.length / 2; + } + + return Math.max(maximum, 0); + }; + + /** + * Gets the minimum position for the current item. + * @public + * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. + * @returns {Number} + */ + Owl.prototype.minimum = function(relative) { + return relative ? 0 : this._clones.length / 2; + }; + + /** + * Gets an item at the specified relative position. + * @public + * @param {Number} [position] - The relative position of the item. + * @return {jQuery|Array.} - The item at the given position or all items if no position was given. + */ + Owl.prototype.items = function(position) { + if (position === undefined) { + return this._items.slice(); + } + + position = this.normalize(position, true); + return this._items[position]; + }; + + /** + * Gets an item at the specified relative position. + * @public + * @param {Number} [position] - The relative position of the item. + * @return {jQuery|Array.} - The item at the given position or all items if no position was given. + */ + Owl.prototype.mergers = function(position) { + if (position === undefined) { + return this._mergers.slice(); + } + + position = this.normalize(position, true); + return this._mergers[position]; + }; + + /** + * Gets the absolute positions of clones for an item. + * @public + * @param {Number} [position] - The relative position of the item. + * @returns {Array.} - The absolute positions of clones for the item or all if no position was given. + */ + Owl.prototype.clones = function(position) { + var odd = this._clones.length / 2, + even = odd + this._items.length, + map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; + + if (position === undefined) { + return $.map(this._clones, function(v, i) { return map(i) }); + } + + return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); + }; + + /** + * Sets the current animation speed. + * @public + * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. + * @returns {Number} - The current animation speed in milliseconds. + */ + Owl.prototype.speed = function(speed) { + if (speed !== undefined) { + this._speed = speed; + } + + return this._speed; + }; + + /** + * Gets the coordinate of an item. + * @todo The name of this method is missleanding. + * @public + * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. + * @returns {Number|Array.} - The coordinate of the item in pixel or all coordinates. + */ + Owl.prototype.coordinates = function(position) { + var multiplier = 1, + newPosition = position - 1, + coordinate; + + if (position === undefined) { + return $.map(this._coordinates, $.proxy(function(coordinate, index) { + return this.coordinates(index); + }, this)); + } + + if (this.settings.center) { + if (this.settings.rtl) { + multiplier = -1; + newPosition = position + 1; + } + + coordinate = this._coordinates[position]; + coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier; + } else { + coordinate = this._coordinates[newPosition] || 0; + } + + coordinate = Math.ceil(coordinate); + + return coordinate; + }; + + /** + * Calculates the speed for a translation. + * @protected + * @param {Number} from - The absolute position of the start item. + * @param {Number} to - The absolute position of the target item. + * @param {Number} [factor=undefined] - The time factor in milliseconds. + * @returns {Number} - The time in milliseconds for the translation. + */ + Owl.prototype.duration = function(from, to, factor) { + if (factor === 0) { + return 0; + } + + return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); + }; + + /** + * Slides to the specified item. + * @public + * @param {Number} position - The position of the item. + * @param {Number} [speed] - The time in milliseconds for the transition. + */ + Owl.prototype.to = function(position, speed) { + var current = this.current(), + revert = null, + distance = position - this.relative(current), + direction = (distance > 0) - (distance < 0), + items = this._items.length, + minimum = this.minimum(), + maximum = this.maximum(); + + if (this.settings.loop) { + if (!this.settings.rewind && Math.abs(distance) > items / 2) { + distance += direction * -1 * items; + } + + position = current + distance; + revert = ((position - minimum) % items + items) % items + minimum; + + if (revert !== position && revert - distance <= maximum && revert - distance > 0) { + current = revert - distance; + position = revert; + this.reset(current); + } + } else if (this.settings.rewind) { + maximum += 1; + position = (position % maximum + maximum) % maximum; + } else { + position = Math.max(minimum, Math.min(maximum, position)); + } + + this.speed(this.duration(current, position, speed)); + this.current(position); + + if (this.isVisible()) { + this.update(); + } + }; + + /** + * Slides to the next item. + * @public + * @param {Number} [speed] - The time in milliseconds for the transition. + */ + Owl.prototype.next = function(speed) { + speed = speed || false; + this.to(this.relative(this.current()) + 1, speed); + }; + + /** + * Slides to the previous item. + * @public + * @param {Number} [speed] - The time in milliseconds for the transition. + */ + Owl.prototype.prev = function(speed) { + speed = speed || false; + this.to(this.relative(this.current()) - 1, speed); + }; + + /** + * Handles the end of an animation. + * @protected + * @param {Event} event - The event arguments. + */ + Owl.prototype.onTransitionEnd = function(event) { + + // if css2 animation then event object is undefined + if (event !== undefined) { + event.stopPropagation(); + + // Catch only owl-stage transitionEnd event + if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { + return false; + } + } + + this.leave('animating'); + this.trigger('translated'); + }; + + /** + * Gets viewport width. + * @protected + * @return {Number} - The width in pixel. + */ + Owl.prototype.viewport = function() { + var width; + if (this.options.responsiveBaseElement !== window) { + width = $(this.options.responsiveBaseElement).width(); + } else if (window.innerWidth) { + width = window.innerWidth; + } else if (document.documentElement && document.documentElement.clientWidth) { + width = document.documentElement.clientWidth; + } else { + console.warn('Can not detect viewport width.'); + } + return width; + }; + + /** + * Replaces the current content. + * @public + * @param {HTMLElement|jQuery|String} content - The new content. + */ + Owl.prototype.replace = function(content) { + this.$stage.empty(); + this._items = []; + + if (content) { + content = (content instanceof jQuery) ? content : $(content); + } + + if (this.settings.nestedItemSelector) { + content = content.find('.' + this.settings.nestedItemSelector); + } + + content.filter(function() { + return this.nodeType === 1; + }).each($.proxy(function(index, item) { + item = this.prepare(item); + this.$stage.append(item); + this._items.push(item); + this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); + }, this)); + + this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); + + this.invalidate('items'); + }; + + /** + * Adds an item. + * @todo Use `item` instead of `content` for the event arguments. + * @public + * @param {HTMLElement|jQuery|String} content - The item content to add. + * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. + */ + Owl.prototype.add = function(content, position) { + var current = this.relative(this._current); + + position = position === undefined ? this._items.length : this.normalize(position, true); + content = content instanceof jQuery ? content : $(content); + + this.trigger('add', { content: content, position: position }); + + content = this.prepare(content); + + if (this._items.length === 0 || position === this._items.length) { + this._items.length === 0 && this.$stage.append(content); + this._items.length !== 0 && this._items[position - 1].after(content); + this._items.push(content); + this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); + } else { + this._items[position].before(content); + this._items.splice(position, 0, content); + this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); + } + + this._items[current] && this.reset(this._items[current].index()); + + this.invalidate('items'); + + this.trigger('added', { content: content, position: position }); + }; + + /** + * Removes an item by its position. + * @todo Use `item` instead of `content` for the event arguments. + * @public + * @param {Number} position - The relative position of the item to remove. + */ + Owl.prototype.remove = function(position) { + position = this.normalize(position, true); + + if (position === undefined) { + return; + } + + this.trigger('remove', { content: this._items[position], position: position }); + + this._items[position].remove(); + this._items.splice(position, 1); + this._mergers.splice(position, 1); + + this.invalidate('items'); + + this.trigger('removed', { content: null, position: position }); + }; + + /** + * Preloads images with auto width. + * @todo Replace by a more generic approach + * @protected + */ + Owl.prototype.preloadAutoWidthImages = function(images) { + images.each($.proxy(function(i, element) { + this.enter('pre-loading'); + element = $(element); + $(new Image()).one('load', $.proxy(function(e) { + element.attr('src', e.target.src); + element.css('opacity', 1); + this.leave('pre-loading'); + !this.is('pre-loading') && !this.is('initializing') && this.refresh(); + }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); + }, this)); + }; + + /** + * Destroys the carousel. + * @public + */ + Owl.prototype.destroy = function() { + + this.$element.off('.owl.core'); + this.$stage.off('.owl.core'); + $(document).off('.owl.core'); + + if (this.settings.responsive !== false) { + window.clearTimeout(this.resizeTimer); + this.off(window, 'resize', this._handlers.onThrottledResize); + } + + for (var i in this._plugins) { + this._plugins[i].destroy(); + } + + this.$stage.children('.cloned').remove(); + + this.$stage.unwrap(); + this.$stage.children().contents().unwrap(); + this.$stage.children().unwrap(); + this.$stage.remove(); + this.$element + .removeClass(this.options.refreshClass) + .removeClass(this.options.loadingClass) + .removeClass(this.options.loadedClass) + .removeClass(this.options.rtlClass) + .removeClass(this.options.dragClass) + .removeClass(this.options.grabClass) + .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) + .removeData('owl.carousel'); + }; + + /** + * Operators to calculate right-to-left and left-to-right. + * @protected + * @param {Number} [a] - The left side operand. + * @param {String} [o] - The operator. + * @param {Number} [b] - The right side operand. + */ + Owl.prototype.op = function(a, o, b) { + var rtl = this.settings.rtl; + switch (o) { + case '<': + return rtl ? a > b : a < b; + case '>': + return rtl ? a < b : a > b; + case '>=': + return rtl ? a <= b : a >= b; + case '<=': + return rtl ? a >= b : a <= b; + default: + break; + } + }; + + /** + * Attaches to an internal event. + * @protected + * @param {HTMLElement} element - The event source. + * @param {String} event - The event name. + * @param {Function} listener - The event handler to attach. + * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. + */ + Owl.prototype.on = function(element, event, listener, capture) { + if (element.addEventListener) { + element.addEventListener(event, listener, capture); + } else if (element.attachEvent) { + element.attachEvent('on' + event, listener); + } + }; + + /** + * Detaches from an internal event. + * @protected + * @param {HTMLElement} element - The event source. + * @param {String} event - The event name. + * @param {Function} listener - The attached event handler to detach. + * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. + */ + Owl.prototype.off = function(element, event, listener, capture) { + if (element.removeEventListener) { + element.removeEventListener(event, listener, capture); + } else if (element.detachEvent) { + element.detachEvent('on' + event, listener); + } + }; + + /** + * Triggers a public event. + * @todo Remove `status`, `relatedTarget` should be used instead. + * @protected + * @param {String} name - The event name. + * @param {*} [data=null] - The event data. + * @param {String} [namespace=carousel] - The event namespace. + * @param {String} [state] - The state which is associated with the event. + * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. + * @returns {Event} - The event arguments. + */ + Owl.prototype.trigger = function(name, data, namespace, state, enter) { + var status = { + item: { count: this._items.length, index: this.current() } + }, handler = $.camelCase( + $.grep([ 'on', name, namespace ], function(v) { return v }) + .join('-').toLowerCase() + ), event = $.Event( + [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), + $.extend({ relatedTarget: this }, status, data) + ); + + if (!this._supress[name]) { + $.each(this._plugins, function(name, plugin) { + if (plugin.onTrigger) { + plugin.onTrigger(event); + } + }); + + this.register({ type: Owl.Type.Event, name: name }); + this.$element.trigger(event); + + if (this.settings && typeof this.settings[handler] === 'function') { + this.settings[handler].call(this, event); + } + } + + return event; + }; + + /** + * Enters a state. + * @param name - The state name. + */ + Owl.prototype.enter = function(name) { + $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { + if (this._states.current[name] === undefined) { + this._states.current[name] = 0; + } + + this._states.current[name]++; + }, this)); + }; + + /** + * Leaves a state. + * @param name - The state name. + */ + Owl.prototype.leave = function(name) { + $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { + this._states.current[name]--; + }, this)); + }; + + /** + * Registers an event or state. + * @public + * @param {Object} object - The event or state to register. + */ + Owl.prototype.register = function(object) { + if (object.type === Owl.Type.Event) { + if (!$.event.special[object.name]) { + $.event.special[object.name] = {}; + } + + if (!$.event.special[object.name].owl) { + var _default = $.event.special[object.name]._default; + $.event.special[object.name]._default = function(e) { + if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { + return _default.apply(this, arguments); + } + return e.namespace && e.namespace.indexOf('owl') > -1; + }; + $.event.special[object.name].owl = true; + } + } else if (object.type === Owl.Type.State) { + if (!this._states.tags[object.name]) { + this._states.tags[object.name] = object.tags; + } else { + this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); + } + + this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { + return $.inArray(tag, this._states.tags[object.name]) === i; + }, this)); + } + }; + + /** + * Suppresses events. + * @protected + * @param {Array.} events - The events to suppress. + */ + Owl.prototype.suppress = function(events) { + $.each(events, $.proxy(function(index, event) { + this._supress[event] = true; + }, this)); + }; + + /** + * Releases suppressed events. + * @protected + * @param {Array.} events - The events to release. + */ + Owl.prototype.release = function(events) { + $.each(events, $.proxy(function(index, event) { + delete this._supress[event]; + }, this)); + }; + + /** + * Gets unified pointer coordinates from event. + * @todo #261 + * @protected + * @param {Event} - The `mousedown` or `touchstart` event. + * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. + */ + Owl.prototype.pointer = function(event) { + var result = { x: null, y: null }; + + event = event.originalEvent || event || window.event; + + event = event.touches && event.touches.length ? + event.touches[0] : event.changedTouches && event.changedTouches.length ? + event.changedTouches[0] : event; + + if (event.pageX) { + result.x = event.pageX; + result.y = event.pageY; + } else { + result.x = event.clientX; + result.y = event.clientY; + } + + return result; + }; + + /** + * Determines if the input is a Number or something that can be coerced to a Number + * @protected + * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested + * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number + */ + Owl.prototype.isNumeric = function(number) { + return !isNaN(parseFloat(number)); + }; + + /** + * Gets the difference of two vectors. + * @todo #261 + * @protected + * @param {Object} - The first vector. + * @param {Object} - The second vector. + * @returns {Object} - The difference. + */ + Owl.prototype.difference = function(first, second) { + return { + x: first.x - second.x, + y: first.y - second.y + }; + }; + + /** + * The jQuery Plugin for the Owl Carousel + * @todo Navigation plugin `next` and `prev` + * @public + */ + $.fn.owlCarousel = function(option) { + var args = Array.prototype.slice.call(arguments, 1); + + return this.each(function() { + var $this = $(this), + data = $this.data('owl.carousel'); + + if (!data) { + data = new Owl(this, typeof option == 'object' && option); + $this.data('owl.carousel', data); + + $.each([ + 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' + ], function(i, event) { + data.register({ type: Owl.Type.Event, name: event }); + data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { + if (e.namespace && e.relatedTarget !== this) { + this.suppress([ event ]); + data[event].apply(this, [].slice.call(arguments, 1)); + this.release([ event ]); + } + }, data)); + }); + } + + if (typeof option == 'string' && option.charAt(0) !== '_') { + data[option].apply(data, args); + } + }); + }; + + /** + * The constructor for the jQuery Plugin + * @public + */ + $.fn.owlCarousel.Constructor = Owl; + +})(window.Zepto || window.jQuery, window, document); + +/** + * AutoRefresh Plugin + * @version 2.3.4 + * @author Artus Kolanowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the auto refresh plugin. + * @class The Auto Refresh Plugin + * @param {Owl} carousel - The Owl Carousel + */ + var AutoRefresh = function(carousel) { + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + /** + * Refresh interval. + * @protected + * @type {number} + */ + this._interval = null; + + /** + * Whether the element is currently visible or not. + * @protected + * @type {Boolean} + */ + this._visible = null; + + /** + * All event handlers. + * @protected + * @type {Object} + */ + this._handlers = { + 'initialized.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.autoRefresh) { + this.watch(); + } + }, this) + }; + + // set default options + this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); + + // register event handlers + this._core.$element.on(this._handlers); + }; + + /** + * Default options. + * @public + */ + AutoRefresh.Defaults = { + autoRefresh: true, + autoRefreshInterval: 500 + }; + + /** + * Watches the element. + */ + AutoRefresh.prototype.watch = function() { + if (this._interval) { + return; + } + + this._visible = this._core.isVisible(); + this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); + }; + + /** + * Refreshes the element. + */ + AutoRefresh.prototype.refresh = function() { + if (this._core.isVisible() === this._visible) { + return; + } + + this._visible = !this._visible; + + this._core.$element.toggleClass('owl-hidden', !this._visible); + + this._visible && (this._core.invalidate('width') && this._core.refresh()); + }; + + /** + * Destroys the plugin. + */ + AutoRefresh.prototype.destroy = function() { + var handler, property; + + window.clearInterval(this._interval); + + for (handler in this._handlers) { + this._core.$element.off(handler, this._handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] != 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; + +})(window.Zepto || window.jQuery, window, document); + +/** + * Lazy Plugin + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the lazy plugin. + * @class The Lazy Plugin + * @param {Owl} carousel - The Owl Carousel + */ + var Lazy = function(carousel) { + + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + /** + * Already loaded items. + * @protected + * @type {Array.} + */ + this._loaded = []; + + /** + * Event handlers. + * @protected + * @type {Object} + */ + this._handlers = { + 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) { + if (!e.namespace) { + return; + } + + if (!this._core.settings || !this._core.settings.lazyLoad) { + return; + } + + if ((e.property && e.property.name == 'position') || e.type == 'initialized') { + var settings = this._core.settings, + n = (settings.center && Math.ceil(settings.items / 2) || settings.items), + i = ((settings.center && n * -1) || 0), + position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i, + clones = this._core.clones().length, + load = $.proxy(function(i, v) { this.load(v) }, this); + //TODO: Need documentation for this new option + if (settings.lazyLoadEager > 0) { + n += settings.lazyLoadEager; + // If the carousel is looping also preload images that are to the "left" + if (settings.loop) { + position -= settings.lazyLoadEager; + n++; + } + } + + while (i++ < n) { + this.load(clones / 2 + this._core.relative(position)); + clones && $.each(this._core.clones(this._core.relative(position)), load); + position++; + } + } + }, this) + }; + + // set the default options + this._core.options = $.extend({}, Lazy.Defaults, this._core.options); + + // register event handler + this._core.$element.on(this._handlers); + }; + + /** + * Default options. + * @public + */ + Lazy.Defaults = { + lazyLoad: false, + lazyLoadEager: 0 + }; + + /** + * Loads all resources of an item at the specified position. + * @param {Number} position - The absolute position of the item. + * @protected + */ + Lazy.prototype.load = function(position) { + var $item = this._core.$stage.children().eq(position), + $elements = $item && $item.find('.owl-lazy'); + + if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { + return; + } + + $elements.each($.proxy(function(index, element) { + var $element = $(element), image, + url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset'); + + this._core.trigger('load', { element: $element, url: url }, 'lazy'); + + if ($element.is('img')) { + $element.one('load.owl.lazy', $.proxy(function() { + $element.css('opacity', 1); + this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); + }, this)).attr('src', url); + } else if ($element.is('source')) { + $element.one('load.owl.lazy', $.proxy(function() { + this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); + }, this)).attr('srcset', url); + } else { + image = new Image(); + image.onload = $.proxy(function() { + $element.css({ + 'background-image': 'url("' + url + '")', + 'opacity': '1' + }); + this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); + }, this); + image.src = url; + } + }, this)); + + this._loaded.push($item.get(0)); + }; + + /** + * Destroys the plugin. + * @public + */ + Lazy.prototype.destroy = function() { + var handler, property; + + for (handler in this.handlers) { + this._core.$element.off(handler, this.handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] != 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; + +})(window.Zepto || window.jQuery, window, document); + +/** + * AutoHeight Plugin + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the auto height plugin. + * @class The Auto Height Plugin + * @param {Owl} carousel - The Owl Carousel + */ + var AutoHeight = function(carousel) { + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + this._previousHeight = null; + + /** + * All event handlers. + * @protected + * @type {Object} + */ + this._handlers = { + 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.autoHeight) { + this.update(); + } + }, this), + 'changed.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){ + this.update(); + } + }, this), + 'loaded.owl.lazy': $.proxy(function(e) { + if (e.namespace && this._core.settings.autoHeight + && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { + this.update(); + } + }, this) + }; + + // set default options + this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); + + // register event handlers + this._core.$element.on(this._handlers); + this._intervalId = null; + var refThis = this; + + // These changes have been taken from a PR by gavrochelegnou proposed in #1575 + // and have been made compatible with the latest jQuery version + $(window).on('load', function() { + if (refThis._core.settings.autoHeight) { + refThis.update(); + } + }); + + // Autoresize the height of the carousel when window is resized + // When carousel has images, the height is dependent on the width + // and should also change on resize + $(window).resize(function() { + if (refThis._core.settings.autoHeight) { + if (refThis._intervalId != null) { + clearTimeout(refThis._intervalId); + } + + refThis._intervalId = setTimeout(function() { + refThis.update(); + }, 250); + } + }); + + }; + + /** + * Default options. + * @public + */ + AutoHeight.Defaults = { + autoHeight: false, + autoHeightClass: 'owl-height' + }; + + /** + * Updates the view. + */ + AutoHeight.prototype.update = function() { + var start = this._core._current, + end = start + this._core.settings.items, + lazyLoadEnabled = this._core.settings.lazyLoad, + visible = this._core.$stage.children().toArray().slice(start, end), + heights = [], + maxheight = 0; + + $.each(visible, function(index, item) { + heights.push($(item).height()); + }); + + maxheight = Math.max.apply(null, heights); + + if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) { + maxheight = this._previousHeight; + } + + this._previousHeight = maxheight; + + this._core.$stage.parent() + .height(maxheight) + .addClass(this._core.settings.autoHeightClass); + }; + + AutoHeight.prototype.destroy = function() { + var handler, property; + + for (handler in this._handlers) { + this._core.$element.off(handler, this._handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] !== 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; + +})(window.Zepto || window.jQuery, window, document); + +/** + * Video Plugin + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the video plugin. + * @class The Video Plugin + * @param {Owl} carousel - The Owl Carousel + */ + var Video = function(carousel) { + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + /** + * Cache all video URLs. + * @protected + * @type {Object} + */ + this._videos = {}; + + /** + * Current playing item. + * @protected + * @type {jQuery} + */ + this._playing = null; + + /** + * All event handlers. + * @todo The cloned content removale is too late + * @protected + * @type {Object} + */ + this._handlers = { + 'initialized.owl.carousel': $.proxy(function(e) { + if (e.namespace) { + this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); + } + }, this), + 'resize.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.video && this.isInFullScreen()) { + e.preventDefault(); + } + }, this), + 'refreshed.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.is('resizing')) { + this._core.$stage.find('.cloned .owl-video-frame').remove(); + } + }, this), + 'changed.owl.carousel': $.proxy(function(e) { + if (e.namespace && e.property.name === 'position' && this._playing) { + this.stop(); + } + }, this), + 'prepared.owl.carousel': $.proxy(function(e) { + if (!e.namespace) { + return; + } + + var $element = $(e.content).find('.owl-video'); + + if ($element.length) { + $element.css('display', 'none'); + this.fetch($element, $(e.content)); + } + }, this) + }; + + // set default options + this._core.options = $.extend({}, Video.Defaults, this._core.options); + + // register event handlers + this._core.$element.on(this._handlers); + + this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { + this.play(e); + }, this)); + }; + + /** + * Default options. + * @public + */ + Video.Defaults = { + video: false, + videoHeight: false, + videoWidth: false + }; + + /** + * Gets the video ID and the type (YouTube/Vimeo/vzaar only). + * @protected + * @param {jQuery} target - The target containing the video data. + * @param {jQuery} item - The item containing the video. + */ + Video.prototype.fetch = function(target, item) { + var type = (function() { + if (target.attr('data-vimeo-id')) { + return 'vimeo'; + } else if (target.attr('data-vzaar-id')) { + return 'vzaar' + } else { + return 'youtube'; + } + })(), + id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'), + width = target.attr('data-width') || this._core.settings.videoWidth, + height = target.attr('data-height') || this._core.settings.videoHeight, + url = target.attr('href'); + + if (url) { + + /* + Parses the id's out of the following urls (and probably more): + https://www.youtube.com/watch?v=:id + https://youtu.be/:id + https://vimeo.com/:id + https://vimeo.com/channels/:channel/:id + https://vimeo.com/groups/:group/videos/:id + https://app.vzaar.com/videos/:id + + Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F + */ + + id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); + + if (id[3].indexOf('youtu') > -1) { + type = 'youtube'; + } else if (id[3].indexOf('vimeo') > -1) { + type = 'vimeo'; + } else if (id[3].indexOf('vzaar') > -1) { + type = 'vzaar'; + } else { + throw new Error('Video URL not supported.'); + } + id = id[6]; + } else { + throw new Error('Missing video URL.'); + } + + this._videos[url] = { + type: type, + id: id, + width: width, + height: height + }; + + item.attr('data-video', url); + + this.thumbnail(target, this._videos[url]); + }; + + /** + * Creates video thumbnail. + * @protected + * @param {jQuery} target - The target containing the video data. + * @param {Object} info - The video info object. + * @see `fetch` + */ + Video.prototype.thumbnail = function(target, video) { + var tnLink, + icon, + path, + dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '', + customTn = target.find('img'), + srcType = 'src', + lazyClass = '', + settings = this._core.settings, + create = function(path) { + icon = '
    '; + + if (settings.lazyLoad) { + tnLink = $('
    ',{ + "class": 'owl-video-tn ' + lazyClass, + "srcType": path + }); + } else { + tnLink = $( '
    ', { + "class": "owl-video-tn", + "style": 'opacity:1;background-image:url(' + path + ')' + }); + } + target.after(tnLink); + target.after(icon); + }; + + // wrap video content into owl-video-wrapper div + target.wrap( $( '
    ', { + "class": "owl-video-wrapper", + "style": dimensions + })); + + if (this._core.settings.lazyLoad) { + srcType = 'data-src'; + lazyClass = 'owl-lazy'; + } + + // custom thumbnail + if (customTn.length) { + create(customTn.attr(srcType)); + customTn.remove(); + return false; + } + + if (video.type === 'youtube') { + path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; + create(path); + } else if (video.type === 'vimeo') { + $.ajax({ + type: 'GET', + url: '//vimeo.com/api/v2/video/' + video.id + '.json', + jsonp: 'callback', + dataType: 'jsonp', + success: function(data) { + path = data[0].thumbnail_large; + create(path); + } + }); + } else if (video.type === 'vzaar') { + $.ajax({ + type: 'GET', + url: '//vzaar.com/api/videos/' + video.id + '.json', + jsonp: 'callback', + dataType: 'jsonp', + success: function(data) { + path = data.framegrab_url; + create(path); + } + }); + } + }; + + /** + * Stops the current video. + * @public + */ + Video.prototype.stop = function() { + this._core.trigger('stop', null, 'video'); + this._playing.find('.owl-video-frame').remove(); + this._playing.removeClass('owl-video-playing'); + this._playing = null; + this._core.leave('playing'); + this._core.trigger('stopped', null, 'video'); + }; + + /** + * Starts the current video. + * @public + * @param {Event} event - The event arguments. + */ + Video.prototype.play = function(event) { + var target = $(event.target), + item = target.closest('.' + this._core.settings.itemClass), + video = this._videos[item.attr('data-video')], + width = video.width || '100%', + height = video.height || this._core.$stage.height(), + html, + iframe; + + if (this._playing) { + return; + } + + this._core.enter('playing'); + this._core.trigger('play', null, 'video'); + + item = this._core.items(this._core.relative(item.index())); + + this._core.reset(item.index()); + + html = $( '' ); + html.attr( 'height', height ); + html.attr( 'width', width ); + if (video.type === 'youtube') { + html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id ); + } else if (video.type === 'vimeo') { + html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' ); + } else if (video.type === 'vzaar') { + html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' ); + } + + iframe = $(html).wrap( '
    ' ).insertAfter(item.find('.owl-video')); + + this._playing = item.addClass('owl-video-playing'); + }; + + /** + * Checks whether an video is currently in full screen mode or not. + * @todo Bad style because looks like a readonly method but changes members. + * @protected + * @returns {Boolean} + */ + Video.prototype.isInFullScreen = function() { + var element = document.fullscreenElement || document.mozFullScreenElement || + document.webkitFullscreenElement; + + return element && $(element).parent().hasClass('owl-video-frame'); + }; + + /** + * Destroys the plugin. + */ + Video.prototype.destroy = function() { + var handler, property; + + this._core.$element.off('click.owl.video'); + + for (handler in this._handlers) { + this._core.$element.off(handler, this._handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] != 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.Video = Video; + +})(window.Zepto || window.jQuery, window, document); + +/** + * Animate Plugin + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the animate plugin. + * @class The Navigation Plugin + * @param {Owl} scope - The Owl Carousel + */ + var Animate = function(scope) { + this.core = scope; + this.core.options = $.extend({}, Animate.Defaults, this.core.options); + this.swapping = true; + this.previous = undefined; + this.next = undefined; + + this.handlers = { + 'change.owl.carousel': $.proxy(function(e) { + if (e.namespace && e.property.name == 'position') { + this.previous = this.core.current(); + this.next = e.property.value; + } + }, this), + 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { + if (e.namespace) { + this.swapping = e.type == 'translated'; + } + }, this), + 'translate.owl.carousel': $.proxy(function(e) { + if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { + this.swap(); + } + }, this) + }; + + this.core.$element.on(this.handlers); + }; + + /** + * Default options. + * @public + */ + Animate.Defaults = { + animateOut: false, + animateIn: false + }; + + /** + * Toggles the animation classes whenever an translations starts. + * @protected + * @returns {Boolean|undefined} + */ + Animate.prototype.swap = function() { + + if (this.core.settings.items !== 1) { + return; + } + + if (!$.support.animation || !$.support.transition) { + return; + } + + this.core.speed(0); + + var left, + clear = $.proxy(this.clear, this), + previous = this.core.$stage.children().eq(this.previous), + next = this.core.$stage.children().eq(this.next), + incoming = this.core.settings.animateIn, + outgoing = this.core.settings.animateOut; + + if (this.core.current() === this.previous) { + return; + } + + if (outgoing) { + left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); + previous.one($.support.animation.end, clear) + .css( { 'left': left + 'px' } ) + .addClass('animated owl-animated-out') + .addClass(outgoing); + } + + if (incoming) { + next.one($.support.animation.end, clear) + .addClass('animated owl-animated-in') + .addClass(incoming); + } + }; + + Animate.prototype.clear = function(e) { + $(e.target).css( { 'left': '' } ) + .removeClass('animated owl-animated-out owl-animated-in') + .removeClass(this.core.settings.animateIn) + .removeClass(this.core.settings.animateOut); + this.core.onTransitionEnd(); + }; + + /** + * Destroys the plugin. + * @public + */ + Animate.prototype.destroy = function() { + var handler, property; + + for (handler in this.handlers) { + this.core.$element.off(handler, this.handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] != 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; + +})(window.Zepto || window.jQuery, window, document); + +/** + * Autoplay Plugin + * @version 2.3.4 + * @author Bartosz Wojciechowski + * @author Artus Kolanowski + * @author David Deutsch + * @author Tom De Caluwé + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + + /** + * Creates the autoplay plugin. + * @class The Autoplay Plugin + * @param {Owl} scope - The Owl Carousel + */ + var Autoplay = function(carousel) { + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + /** + * The autoplay timeout id. + * @type {Number} + */ + this._call = null; + + /** + * Depending on the state of the plugin, this variable contains either + * the start time of the timer or the current timer value if it's + * paused. Since we start in a paused state we initialize the timer + * value. + * @type {Number} + */ + this._time = 0; + + /** + * Stores the timeout currently used. + * @type {Number} + */ + this._timeout = 0; + + /** + * Indicates whenever the autoplay is paused. + * @type {Boolean} + */ + this._paused = true; + + /** + * All event handlers. + * @protected + * @type {Object} + */ + this._handlers = { + 'changed.owl.carousel': $.proxy(function(e) { + if (e.namespace && e.property.name === 'settings') { + if (this._core.settings.autoplay) { + this.play(); + } else { + this.stop(); + } + } else if (e.namespace && e.property.name === 'position' && this._paused) { + // Reset the timer. This code is triggered when the position + // of the carousel was changed through user interaction. + this._time = 0; + } + }, this), + 'initialized.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.autoplay) { + this.play(); + } + }, this), + 'play.owl.autoplay': $.proxy(function(e, t, s) { + if (e.namespace) { + this.play(t, s); + } + }, this), + 'stop.owl.autoplay': $.proxy(function(e) { + if (e.namespace) { + this.stop(); + } + }, this), + 'mouseover.owl.autoplay': $.proxy(function() { + if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { + this.pause(); + } + }, this), + 'mouseleave.owl.autoplay': $.proxy(function() { + if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { + this.play(); + } + }, this), + 'touchstart.owl.core': $.proxy(function() { + if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { + this.pause(); + } + }, this), + 'touchend.owl.core': $.proxy(function() { + if (this._core.settings.autoplayHoverPause) { + this.play(); + } + }, this) + }; + + // register event handlers + this._core.$element.on(this._handlers); + + // set default options + this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); + }; + + /** + * Default options. + * @public + */ + Autoplay.Defaults = { + autoplay: false, + autoplayTimeout: 5000, + autoplayHoverPause: false, + autoplaySpeed: false + }; + + /** + * Transition to the next slide and set a timeout for the next transition. + * @private + * @param {Number} [speed] - The animation speed for the animations. + */ + Autoplay.prototype._next = function(speed) { + this._call = window.setTimeout( + $.proxy(this._next, this, speed), + this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read() + ); + + if (this._core.is('interacting') || document.hidden) { + return; + } + this._core.next(speed || this._core.settings.autoplaySpeed); + } + + /** + * Reads the current timer value when the timer is playing. + * @public + */ + Autoplay.prototype.read = function() { + return new Date().getTime() - this._time; + }; + + /** + * Starts the autoplay. + * @public + * @param {Number} [timeout] - The interval before the next animation starts. + * @param {Number} [speed] - The animation speed for the animations. + */ + Autoplay.prototype.play = function(timeout, speed) { + var elapsed; + + if (!this._core.is('rotating')) { + this._core.enter('rotating'); + } + + timeout = timeout || this._core.settings.autoplayTimeout; + + // Calculate the elapsed time since the last transition. If the carousel + // wasn't playing this calculation will yield zero. + elapsed = Math.min(this._time % (this._timeout || timeout), timeout); + + if (this._paused) { + // Start the clock. + this._time = this.read(); + this._paused = false; + } else { + // Clear the active timeout to allow replacement. + window.clearTimeout(this._call); + } + + // Adjust the origin of the timer to match the new timeout value. + this._time += this.read() % timeout - elapsed; + + this._timeout = timeout; + this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed); + }; + + /** + * Stops the autoplay. + * @public + */ + Autoplay.prototype.stop = function() { + if (this._core.is('rotating')) { + // Reset the clock. + this._time = 0; + this._paused = true; + + window.clearTimeout(this._call); + this._core.leave('rotating'); + } + }; + + /** + * Pauses the autoplay. + * @public + */ + Autoplay.prototype.pause = function() { + if (this._core.is('rotating') && !this._paused) { + // Pause the clock. + this._time = this.read(); + this._paused = true; + + window.clearTimeout(this._call); + } + }; + + /** + * Destroys the plugin. + */ + Autoplay.prototype.destroy = function() { + var handler, property; + + this.stop(); + + for (handler in this._handlers) { + this._core.$element.off(handler, this._handlers[handler]); + } + for (property in Object.getOwnPropertyNames(this)) { + typeof this[property] != 'function' && (this[property] = null); + } + }; + + $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; + +})(window.Zepto || window.jQuery, window, document); + +/** + * Navigation Plugin + * @version 2.3.4 + * @author Artus Kolanowski + * @author David Deutsch + * @license The MIT License (MIT) + */ +;(function($, window, document, undefined) { + 'use strict'; + + /** + * Creates the navigation plugin. + * @class The Navigation Plugin + * @param {Owl} carousel - The Owl Carousel. + */ + var Navigation = function(carousel) { + /** + * Reference to the core. + * @protected + * @type {Owl} + */ + this._core = carousel; + + /** + * Indicates whether the plugin is initialized or not. + * @protected + * @type {Boolean} + */ + this._initialized = false; + + /** + * The current paging indexes. + * @protected + * @type {Array} + */ + this._pages = []; + + /** + * All DOM elements of the user interface. + * @protected + * @type {Object} + */ + this._controls = {}; + + /** + * Markup for an indicator. + * @protected + * @type {Array.} + */ + this._templates = []; + + /** + * The carousel element. + * @type {jQuery} + */ + this.$element = this._core.$element; + + /** + * Overridden methods of the carousel. + * @protected + * @type {Object} + */ + this._overrides = { + next: this._core.next, + prev: this._core.prev, + to: this._core.to + }; + + /** + * All event handlers. + * @protected + * @type {Object} + */ + this._handlers = { + 'prepared.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.dotsData) { + this._templates.push('
    ' + + $(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '
    '); + } + }, this), + 'added.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.dotsData) { + this._templates.splice(e.position, 0, this._templates.pop()); + } + }, this), + 'remove.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._core.settings.dotsData) { + this._templates.splice(e.position, 1); + } + }, this), + 'changed.owl.carousel': $.proxy(function(e) { + if (e.namespace && e.property.name == 'position') { + this.draw(); + } + }, this), + 'initialized.owl.carousel': $.proxy(function(e) { + if (e.namespace && !this._initialized) { + this._core.trigger('initialize', null, 'navigation'); + this.initialize(); + this.update(); + this.draw(); + this._initialized = true; + this._core.trigger('initialized', null, 'navigation'); + } + }, this), + 'refreshed.owl.carousel': $.proxy(function(e) { + if (e.namespace && this._initialized) { + this._core.trigger('refresh', null, 'navigation'); + this.update(); + this.draw(); + this._core.trigger('refreshed', null, 'navigation'); + } + }, this) + }; + + // set default options + this._core.options = $.extend({}, Navigation.Defaults, this._core.options); + + // register event handlers + this.$element.on(this._handlers); + }; + + /** + * Default options. + * @public + * @todo Rename `slideBy` to `navBy` + */ + Navigation.Defaults = { + nav: false, + navText: [ + '', + '' + ], + navSpeed: false, + navElement: 'button type="button" role="presentation"', + navContainer: false, + navContainerClass: 'owl-nav', + navClass: [ + 'owl-prev', + 'owl-next' + ], + slideBy: 1, + dotClass: 'owl-dot', + dotsClass: 'owl-dots', + dots: true, + dotsEach: false, + dotsData: false, + dotsSpeed: false, + dotsContainer: false + }; + + /** + * Initializes the layout of the plugin and extends the carousel. + * @protected + */ + Navigation.prototype.initialize = function() { + var override, + settings = this._core.settings; + + // create DOM structure for relative navigation + this._controls.$relative = (settings.navContainer ? $(settings.navContainer) + : $('
    ').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); + + this._controls.$previous = $('<' + settings.navElement + '>') + .addClass(settings.navClass[0]) + .html(settings.navText[0]) + .prependTo(this._controls.$relative) + .on('click', $.proxy(function(e) { + this.prev(settings.navSpeed); + }, this)); + this._controls.$next = $('<' + settings.navElement + '>') + .addClass(settings.navClass[1]) + .html(settings.navText[1]) + .appendTo(this._controls.$relative) + .on('click', $.proxy(function(e) { + this.next(settings.navSpeed); + }, this)); + + // create DOM structure for absolute navigation + if (!settings.dotsData) { + this._templates = [ $('\n\n
    \n
    \n
    \n
    \n
    \n\n
    \n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(4),r=n(2),i=n(0),a=i.default.ICON,s=i.default.ICON_CUSTOM,c=["error","warning","success","info"],l={error:r.errorIconMarkup(),warning:r.warningIconMarkup(),success:r.successIconMarkup()},u=function(t,e){var n=a+"--"+t;e.classList.add(n);var o=l[t];o&&(e.innerHTML=o)},f=function(t,e){e.classList.add(s);var n=document.createElement("img");n.src=t,e.appendChild(n)},d=function(t){if(t){var e=o.injectElIntoModal(r.iconMarkup);c.includes(t)?u(t,e):f(t,e)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),r=n(4),i=function(t){navigator.userAgent.includes("AppleWebKit")&&(t.style.display="none",t.offsetHeight,t.style.display="")};e.initTitle=function(t){if(t){var e=r.injectElIntoModal(o.titleMarkup);e.textContent=t,i(e)}},e.initText=function(t){if(t){var e=document.createDocumentFragment();t.split("\n").forEach(function(t,n,o){e.appendChild(document.createTextNode(t)),n0}).forEach(function(t){b.classList.add(t)})}n&&t===c.CONFIRM_KEY&&b.classList.add(s),b.textContent=r;var g={};return g[t]=i,f.setActionValue(g),f.setActionOptionsFor(t,{closeModal:p}),b.addEventListener("click",function(){return u.onAction(t)}),m},p=function(t,e){var n=r.injectElIntoModal(l.footerMarkup);for(var o in t){var i=t[o],a=d(o,i,e);i.visible&&n.appendChild(a)}0===n.children.length&&n.remove()};e.default=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r=n(4),i=n(2),a=n(5),s=n(6),c=n(0),l=c.default.CONTENT,u=function(t){t.addEventListener("input",function(t){var e=t.target,n=e.value;a.setActionValue(n)}),t.addEventListener("keyup",function(t){if("Enter"===t.key)return s.onAction(o.CONFIRM_KEY)}),setTimeout(function(){t.focus(),a.setActionValue("")},0)},f=function(t,e,n){var o=document.createElement(e),r=l+"__"+e;o.classList.add(r);for(var i in n){var a=n[i];o[i]=a}"input"===e&&u(o),t.appendChild(o)},d=function(t){if(t){var e=r.injectElIntoModal(i.contentMarkup),n=t.element,o=t.attributes;"string"==typeof n?f(e,n,o):e.appendChild(n)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=function(){var t=o.stringToNode(r.overlayMarkup);document.body.appendChild(t)};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(5),r=n(6),i=n(1),a=n(3),s=n(0),c=s.default.MODAL,l=s.default.BUTTON,u=s.default.OVERLAY,f=function(t){t.preventDefault(),v()},d=function(t){t.preventDefault(),g()},p=function(t){if(o.default.isOpen)switch(t.key){case"Escape":return r.onAction(a.CANCEL_KEY)}},m=function(t){if(o.default.isOpen)switch(t.key){case"Tab":return f(t)}},b=function(t){if(o.default.isOpen)return"Tab"===t.key&&t.shiftKey?d(t):void 0},v=function(){var t=i.getNode(l);t&&(t.tabIndex=0,t.focus())},g=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l),n=e.length-1,o=e[n];o&&o.focus()},h=function(t){t[t.length-1].addEventListener("keydown",m)},w=function(t){t[0].addEventListener("keydown",b)},y=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l);e.length&&(h(e),w(e))},x=function(t){if(i.getNode(u)===t.target)return r.onAction(a.CANCEL_KEY)},_=function(t){var e=i.getNode(u);e.removeEventListener("click",x),t&&e.addEventListener("click",x)},k=function(t){o.default.timer&&clearTimeout(o.default.timer),t&&(o.default.timer=window.setTimeout(function(){return r.onAction(a.CANCEL_KEY)},t))},O=function(t){t.closeOnEsc?document.addEventListener("keyup",p):document.removeEventListener("keyup",p),t.dangerMode?v():g(),y(),_(t.closeOnClickOutside),k(t.timer)};e.default=O},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(37),a=n(38),s={title:null,text:null,icon:null,buttons:r.defaultButtonList,content:null,className:null,closeOnClickOutside:!0,closeOnEsc:!0,dangerMode:!1,timer:null},c=Object.assign({},s);e.setDefaults=function(t){c=Object.assign({},s,t)};var l=function(t){var e=t&&t.button,n=t&&t.buttons;return void 0!==e&&void 0!==n&&o.throwErr("Cannot set both 'button' and 'buttons' options!"),void 0!==e?{confirm:e}:n},u=function(t){return o.ordinalSuffixOf(t+1)},f=function(t,e){o.throwErr(u(e)+" argument ('"+t+"') is invalid")},d=function(t,e){var n=t+1,r=e[n];o.isPlainObject(r)||void 0===r||o.throwErr("Expected "+u(n)+" argument ('"+r+"') to be a plain object")},p=function(t,e){var n=t+1,r=e[n];void 0!==r&&o.throwErr("Unexpected "+u(n)+" argument ("+r+")")},m=function(t,e,n,r){var i=typeof e,a="string"===i,s=e instanceof Element;if(a){if(0===n)return{text:e};if(1===n)return{text:e,title:r[0]};if(2===n)return d(n,r),{icon:e};f(e,n)}else{if(s&&0===n)return d(n,r),{content:e};if(o.isPlainObject(e))return p(n,r),e;f(e,n)}};e.getOpts=function(){for(var t=[],e=0;e= 0) { + return this.settings.strings.inPast; + } + + var seconds = Math.abs(distanceMillis) / 1000; + var minutes = seconds / 60; + var hours = minutes / 60; + var days = hours / 24; + var years = days / 365; + + function substitute(stringOrFunction, number) { + var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; + var value = ($l.numbers && $l.numbers[number]) || number; + return string.replace(/%d/i, value); + } + + var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || + seconds < 90 && substitute($l.minute, 1) || + minutes < 45 && substitute($l.minutes, Math.round(minutes)) || + minutes < 90 && substitute($l.hour, 1) || + hours < 24 && substitute($l.hours, Math.round(hours)) || + hours < 42 && substitute($l.day, 1) || + days < 30 && substitute($l.days, Math.round(days)) || + days < 45 && substitute($l.month, 1) || + days < 365 && substitute($l.months, Math.round(days / 30)) || + years < 1.5 && substitute($l.year, 1) || + substitute($l.years, Math.round(years)); + + var separator = $l.wordSeparator || ""; + if ($l.wordSeparator === undefined) { separator = " "; } + return $.trim([prefix, words, suffix].join(separator)); + }, + + parse: function(iso8601) { + var s = $.trim(iso8601); + s = s.replace(/\.\d+/,""); // remove milliseconds + s = s.replace(/-/,"/").replace(/-/,"/"); + s = s.replace(/T/," ").replace(/Z/," UTC"); + s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 + s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900 + return new Date(s); + }, + datetime: function(elem) { + var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); + return $t.parse(iso8601); + }, + isTime: function(elem) { + // jQuery's `is()` doesn't play well with HTML5 in IE + return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); + } + }); + + // functions that can be called via $(el).timeago('action') + // init is default when no action is given + // functions are called with context of a single element + var functions = { + init: function() { + functions.dispose.call(this); + var refresh_el = $.proxy(refresh, this); + refresh_el(); + var $s = $t.settings; + if ($s.refreshMillis > 0) { + this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis); + } + }, + update: function(timestamp) { + var date = (timestamp instanceof Date) ? timestamp : $t.parse(timestamp); + $(this).data('timeago', { datetime: date }); + if ($t.settings.localeTitle) { + $(this).attr("title", date.toLocaleString()); + } + refresh.apply(this); + }, + updateFromDOM: function() { + $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) }); + refresh.apply(this); + }, + dispose: function () { + if (this._timeagoInterval) { + window.clearInterval(this._timeagoInterval); + this._timeagoInterval = null; + } + } + }; + + $.fn.timeago = function(action, options) { + var fn = action ? functions[action] : functions.init; + if (!fn) { + throw new Error("Unknown function name '"+ action +"' for timeago"); + } + // each over objects here and call the requested function + this.each(function() { + fn.call(this, options); + }); + return this; + }; + + function refresh() { + var $s = $t.settings; + + //check if it's still visible + if ($s.autoDispose && !$.contains(document.documentElement,this)) { + //stop if it has been removed + $(this).timeago("dispose"); + return this; + } + + var data = prepareData(this); + + if (!isNaN(data.datetime)) { + if ( $s.cutoff === 0 || Math.abs(distance(data.datetime)) < $s.cutoff) { + $(this).text(inWords(data.datetime)); + } else { + if ($(this).attr('title').length > 0) { + $(this).text($(this).attr('title')); + } + } + } + return this; + } + + function prepareData(element) { + element = $(element); + if (!element.data("timeago")) { + element.data("timeago", { datetime: $t.datetime(element) }); + var text = $.trim(element.text()); + if ($t.settings.localeTitle) { + element.attr("title", element.data('timeago').datetime.toLocaleString()); + } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { + element.attr("title", text); + } + } + return element.data("timeago"); + } + + function inWords(date) { + return $t.inWords(distance(date)); + } + + function distance(date) { + return (new Date().getTime() - date.getTime()); + } + + // fix for IE6 suckage + document.createElement("abbr"); + document.createElement("time"); +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/README.md b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/README.md new file mode 100644 index 0000000000..7557112da6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/README.md @@ -0,0 +1,27 @@ +# Locale override examples for timeago + +You can represent time statements in most western languages where +a prefix and/or suffix is used. + +The default case is to use suffix only (as in English), which you +do by providing the `suffixAgo` and `suffixFromNow` settings in +the strings hash (earlier versions of timeago used the deprecated +`ago` and `fromNow` options). If present, they are used. + + 2 minutes [suffixAgo] + 2 minutes [suffixFromNow] + +In case you want to use prefix only instead of +suffix (e.g. Greek), you provide the `prefixAgo` and +`prefixFromNow` options in the strings hash and leave `suffixAgo` +and `suffixFromNow` empty or null. + + [prefixAgo] 2 minutes + [prefixFromNow] 2 minutes + +For languages where you want to use a prefix only for future +tense and prefix/suffix for past tense (for example swedish), you +can combine the prefix and suffixes as needed. + + [prefixAgo] 2 minutes [suffixAgo] + [prefixFromNow] 2 minutes diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.af.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.af.js new file mode 100644 index 0000000000..817a7fa594 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.af.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Afrikaans + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "gelede", + suffixFromNow: "van nou af", + seconds: "%d sekondes", + minute: "1 minuut", + minutes: "%d minute", + hour: "1 uur", + hours: "%d ure", + day: "1 dag", + days: "%d dae", + month: "1 maand", + months: "%d maande", + year: "1 jaar", + years: "%d jaar", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.am.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.am.js new file mode 100644 index 0000000000..65502c39de --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.am.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Amharic + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "በፊት", + suffixFromNow: "በኋላ", + seconds: "ከአንድ ደቂቃ በታች", + minute: "ከአንድ ደቂቃ ገደማ", + minutes: "ከ%d ደቂቃ", + hour: "ከአንድ ሰዓት ገደማ", + hours: "ከ%d ሰዓት ገደማ", + day: "ከአንድ ቀን", + days: "ከ%d ቀን", + month: "ከአንድ ወር ገደማ", + months: "ከ%d ወር", + year: "ከአንድ ዓመት ገደማ", + years: "ከ%d ዓመት", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ar.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ar.js new file mode 100644 index 0000000000..14cd18f230 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ar.js @@ -0,0 +1,104 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + function numpf(n, a) { + return a[plural=n===0 ? 0 : n===1 ? 1 : n===2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5]; + } + + jQuery.timeago.settings.strings = { + prefixAgo: "منذ", + prefixFromNow: "بعد", + suffixAgo: null, + suffixFromNow: null, // null OR "من الآن" + second: function(value) { return numpf(value, [ + 'أقل من ثانية', + 'ثانية واحدة', + 'ثانيتين', + '%d ثوانٍ', + '%d ثانية', + '%d ثانية']); }, + seconds: function(value) { return numpf(value, [ + 'أقل من ثانية', + 'ثانية واحدة', + 'ثانيتين', + '%d ثوانٍ', + '%d ثانية', + '%d ثانية']); }, + minute: function(value) { return numpf(value, [ + 'أقل من دقيقة', + 'دقيقة واحدة', + 'دقيقتين', + '%d دقائق', + '%d دقيقة', + 'دقيقة']); }, + minutes: function(value) { return numpf(value, [ + 'أقل من دقيقة', + 'دقيقة واحدة', + 'دقيقتين', + '%d دقائق', + '%d دقيقة', + 'دقيقة']); }, + hour: function(value) { return numpf(value, [ + 'أقل من ساعة', + 'ساعة واحدة', + 'ساعتين', + '%d ساعات', + '%d ساعة', + '%d ساعة']); }, + hours: function(value) { return numpf(value, [ + 'أقل من ساعة', + 'ساعة واحدة', + 'ساعتين', + '%d ساعات', + '%d ساعة', + '%d ساعة']); }, + day: function(value) { return numpf(value, [ + 'أقل من يوم', + 'يوم واحد', + 'يومين', + '%d أيام', + '%d يومًا', + '%d يوم']); }, + days: function(value) { return numpf(value, [ + 'أقل من يوم', + 'يوم واحد', + 'يومين', + '%d أيام', + '%d يومًا', + '%d يوم']); }, + month: function(value) { return numpf(value, [ + 'أقل من شهر', + 'شهر واحد', + 'شهرين', + '%d أشهر', + '%d شهرًا', + '%d شهر']); }, + months: function(value) { return numpf(value, [ + 'أقل من شهر', + 'شهر واحد', + 'شهرين', + '%d أشهر', + '%d شهرًا', + '%d شهر']); }, + year: function(value) { return numpf(value, [ + 'أقل من عام', + 'عام واحد', + '%d عامين', + '%d أعوام', + '%d عامًا']); + }, + years: function(value) { return numpf(value, [ + 'أقل من عام', + 'عام واحد', + 'عامين', + '%d أعوام', + '%d عامًا', + '%d عام']);} + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az-short.js new file mode 100644 index 0000000000..a1d5740e7b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Azerbaijani shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: '1 dəq', + minute: '1 dəq', + minutes: '%d dəq', + hour: '1 saat', + hours: '%d saat', + day: '1 gün', + days: '%d gün', + month: '1 ay', + months: '%d ay', + year: '1 il', + years: '%d il', + wordSeparator: '', + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az.js new file mode 100644 index 0000000000..8332c41cf8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.az.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Azerbaijani + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: 'əvvəl', + suffixFromNow: 'sonra', + seconds: 'saniyələr', + minute: '1 dəqiqə', + minutes: '%d dəqiqə', + hour: '1 saat', + hours: '%d saat', + day: '1 gün', + days: '%d gün', + month: '1 ay', + months: '%d ay', + year: '1 il', + years: '%d il', + wordSeparator: '', + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bg.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bg.js new file mode 100644 index 0000000000..a3bd343af5 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bg.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Bulgarian + jQuery.timeago.settings.strings = { + prefixAgo: "преди", + prefixFromNow: "след", + suffixAgo: null, + suffixFromNow: null, + seconds: "по-малко от минута", + minute: "една минута", + minutes: "%d минути", + hour: "един час", + hours: "%d часа", + day: "един ден", + days: "%d дни", + month: "един месец", + months: "%d месеца", + year: "една година", + years: "%d години" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bs.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bs.js new file mode 100644 index 0000000000..cbb178069f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.bs.js @@ -0,0 +1,55 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Bosnian + var numpf = function(n, f, s, t) { + var n10; + n10 = n % 10; + if (n10 === 1 && (n === 1 || n > 20)) { + return f; + } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) { + return s; + } else { + return t; + } + }; + + jQuery.timeago.settings.strings = { + prefixAgo: "prije", + prefixFromNow: "za", + suffixAgo: null, + suffixFromNow: null, + second: "sekund", + seconds: function(value) { + return numpf(value, "%d sekund", "%d sekunde", "%d sekundi"); + }, + minute: "oko minut", + minutes: function(value) { + return numpf(value, "%d minut", "%d minute", "%d minuta"); + }, + hour: "oko sat", + hours: function(value) { + return numpf(value, "%d sat", "%d sata", "%d sati"); + }, + day: "oko jednog dana", + days: function(value) { + return numpf(value, "%d dan", "%d dana", "%d dana"); + }, + month: "mjesec dana", + months: function(value) { + return numpf(value, "%d mjesec", "%d mjeseca", "%d mjeseci"); + }, + year: "prije godinu dana ", + years: function(value) { + return numpf(value, "%d godinu", "%d godine", "%d godina"); + }, + wordSeparator: " " + }; + +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ca.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ca.js new file mode 100644 index 0000000000..e4cb5cab7f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ca.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Catalan + jQuery.timeago.settings.strings = { + prefixAgo: "fa", + prefixFromNow: "d'aquí", + suffixAgo: null, + suffixFromNow: null, + seconds: "menys d'un minut", + minute: "un minut", + minutes: "%d minuts", + hour: "una hora", + hours: "%d hores", + day: "un dia", + days: "%d dies", + month: "un mes", + months: "%d mesos", + year: "un any", + years: "%d anys", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cs.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cs.js new file mode 100644 index 0000000000..b940f69495 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cs.js @@ -0,0 +1,34 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Czech + (function() { + function f(n, d, a) { + return a[d>=0 ? 0 : a.length===2 || n<5 ? 1 : 2]; + } + + jQuery.timeago.settings.strings = { + prefixAgo: 'před', + prefixFromNow: 'za', + suffixAgo: null, + suffixFromNow: null, + seconds: function(n, d) {return f(n, d, ['méně než minutou', 'méně než minutu']);}, + minute: function(n, d) {return f(n, d, ['minutou', 'minutu']);}, + minutes: function(n, d) {return f(n, d, ['%d minutami', '%d minuty', '%d minut']);}, + hour: function(n, d) {return f(n, d, ['hodinou', 'hodinu']);}, + hours: function(n, d) {return f(n, d, ['%d hodinami', '%d hodiny', '%d hodin']);}, + day: function(n, d) {return f(n, d, ['%d dnem', '%d den']);}, + days: function(n, d) {return f(n, d, ['%d dny', '%d dny', '%d dní']);}, + month: function(n, d) {return f(n, d, ['%d měsícem', '%d měsíc']);}, + months: function(n, d) {return f(n, d, ['%d měsíci', '%d měsíce', '%d měsíců']);}, + year: function(n, d) {return f(n, d, ['%d rokem', '%d rok']);}, + years: function(n, d) {return f(n, d, ['%d lety', '%d roky', '%d let']);} + }; + })(); +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cy.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cy.js new file mode 100644 index 0000000000..4c514a8df4 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.cy.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Welsh + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "yn ôl", + suffixFromNow: "o hyn", + seconds: "llai na munud", + minute: "am funud", + minutes: "%d munud", + hour: "tua awr", + hours: "am %d awr", + day: "y dydd", + days: "%d diwrnod", + month: "tua mis", + months: "%d mis", + year: "am y flwyddyn", + years: "%d blynedd", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.da.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.da.js new file mode 100644 index 0000000000..236c34c44f --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.da.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Danish + jQuery.timeago.settings.strings = { + prefixAgo: "for", + prefixFromNow: "om", + suffixAgo: "siden", + suffixFromNow: "", + seconds: "mindre end et minut", + minute: "ca. et minut", + minutes: "%d minutter", + hour: "ca. en time", + hours: "ca. %d timer", + day: "en dag", + days: "%d dage", + month: "ca. en måned", + months: "%d måneder", + year: "ca. et år", + years: "%d år" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de-short.js new file mode 100644 index 0000000000..15b446e315 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // German shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "s", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1T.", + days: "%dT.", + month: "1Mt.", + months: "%dMt.", + year: "1J.", + years: "%dJ.", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de.js new file mode 100644 index 0000000000..6a877a2317 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.de.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // German + jQuery.timeago.settings.strings = { + prefixAgo: "vor", + prefixFromNow: "in", + suffixAgo: "", + suffixFromNow: "", + seconds: "wenigen Sekunden", + minute: "etwa einer Minute", + minutes: "%d Minuten", + hour: "etwa einer Stunde", + hours: "%d Stunden", + day: "etwa einem Tag", + days: "%d Tagen", + month: "etwa einem Monat", + months: "%d Monaten", + year: "etwa einem Jahr", + years: "%d Jahren" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.dv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.dv.js new file mode 100644 index 0000000000..0d70a493c2 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.dv.js @@ -0,0 +1,32 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + /** + * Dhivehi time in Thaana for timeago.js + **/ + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "ކުރިން", + suffixFromNow: "ފަހުން", + seconds: "ސިކުންތުކޮޅެއް", + minute: "މިނިޓެއްވަރު", + minutes: "%d މިނިޓު", + hour: "ގަޑިއެއްވަރު", + hours: "ގާތްގަނޑަކަށް %d ގަޑިއިރު", + day: "އެއް ދުވަސް", + days: "މީގެ %d ދުވަސް", + month: "މަހެއްވަރު", + months: "މީގެ %d މަސް", + year: "އަހަރެއްވަރު", + years: "މީގެ %d އަހަރު", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.el.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.el.js new file mode 100644 index 0000000000..2db9ebea89 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.el.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Greek + jQuery.timeago.settings.strings = { + prefixAgo: "πριν", + prefixFromNow: "σε", + suffixAgo: "", + suffixFromNow: "", + seconds: "λιγότερο από ένα λεπτό", + minute: "περίπου ένα λεπτό", + minutes: "%d λεπτά", + hour: "περίπου μία ώρα", + hours: "περίπου %d ώρες", + day: "μία μέρα", + days: "%d μέρες", + month: "περίπου ένα μήνα", + months: "%d μήνες", + year: "περίπου ένα χρόνο", + years: "%d χρόνια" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en-short.js new file mode 100644 index 0000000000..157aaa48dd --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // English shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1m", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1d", + days: "%dd", + month: "1mo", + months: "%dmo", + year: "1yr", + years: "%dyr", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en.js new file mode 100644 index 0000000000..8ca50affff --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.en.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // English (Template) + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "ago", + suffixFromNow: "from now", + seconds: "less than a minute", + minute: "about a minute", + minutes: "%d minutes", + hour: "about an hour", + hours: "about %d hours", + day: "a day", + days: "%d days", + month: "about a month", + months: "%d months", + year: "about a year", + years: "%d years", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es-short.js new file mode 100644 index 0000000000..f762a06dbf --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es-short.js @@ -0,0 +1,31 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Spanish shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1m", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1d", + days: "%dd", + month: "1me", + months: "%dme", + year: "1a", + years: "%da", + wordSeparator: " ", + numbers: [] + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es.js new file mode 100644 index 0000000000..0785b3f42c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.es.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Spanish + jQuery.timeago.settings.strings = { + prefixAgo: "hace", + prefixFromNow: "dentro de", + suffixAgo: "", + suffixFromNow: "", + seconds: "menos de un minuto", + minute: "un minuto", + minutes: "unos %d minutos", + hour: "una hora", + hours: "%d horas", + day: "un día", + days: "%d días", + month: "un mes", + months: "%d meses", + year: "un año", + years: "%d años" + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.et.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.et.js new file mode 100644 index 0000000000..ac2461ec78 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.et.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Estonian + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "tagasi", + suffixFromNow: "pärast", + seconds: function(n, d) { return d < 0 ? "vähem kui minuti aja" : "vähem kui minut aega"; }, + minute: function(n, d) { return d < 0 ? "umbes minuti aja" : "umbes minut aega"; }, + minutes: function(n, d) { return d < 0 ? "%d minuti" : "%d minutit"; }, + hour: function(n, d) { return d < 0 ? "umbes tunni aja" : "umbes tund aega"; }, + hours: function(n, d) { return d < 0 ? "%d tunni" : "%d tundi"; }, + day: function(n, d) { return d < 0 ? "umbes päeva" : "umbes päev"; }, + days: "%d päeva", + month: function(n, d) { return d < 0 ? "umbes kuu aja" : "umbes kuu aega"; }, + months: function(n, d) { return d < 0 ? "%d kuu" : "%d kuud"; }, + year: function(n, d) { return d < 0 ? "umbes aasta aja" : "umbes aasta aega"; }, + years: function(n, d) { return d < 0 ? "%d aasta" : "%d aastat"; } + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.eu.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.eu.js new file mode 100644 index 0000000000..5c2c32c7ef --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.eu.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + jQuery.timeago.settings.strings = { + prefixAgo: "duela", + prefixFromNow: "hemendik", + suffixAgo: "", + suffixFromNow: "barru", + seconds: "minutu bat bainu gutxiago", + minute: "minutu bat", + minutes: "%d minutu inguru", + hour: "ordu bat", + hours: "%d ordu", + day: "egun bat", + days: "%d egun", + month: "hilabete bat", + months: "%d hilabete", + year: "urte bat", + years: "%d urte" + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa-short.js new file mode 100644 index 0000000000..fae384116c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // persion shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1دقیقه", + minute: "1دقیقه", + minutes: "%dدقیقه", + hour: "1ساعت", + hours: "%dساعت", + day: "1روز", + days: "%dروز", + month: "1ماه", + months: "%dماه", + year: "1سال", + years: "%dسال", + wordSeparator: " ", + numbers: ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa.js new file mode 100644 index 0000000000..ec8ccb9522 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fa.js @@ -0,0 +1,32 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Persian + // Use DIR attribute for RTL text in Persian Language for ABBR tag . + // By MB.seifollahi@gmail.com + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "پیش", + suffixFromNow: "از حال", + seconds: "کمتر از یک دقیقه", + minute: "حدود یک دقیقه", + minutes: "%d دقیقه", + hour: "حدود یک ساعت", + hours: "حدود %d ساعت", + day: "یک روز", + days: "%d روز", + month: "حدود یک ماه", + months: "%d ماه", + year: "حدود یک سال", + years: "%d سال", + wordSeparator: " ", + numbers: ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fi.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fi.js new file mode 100644 index 0000000000..b5f7e696de --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fi.js @@ -0,0 +1,38 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Finnish + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "sitten", + suffixFromNow: "tulevaisuudessa", + seconds: "alle minuutti", + minute: "minuutti", + minutes: "%d minuuttia", + hour: "tunti", + hours: "%d tuntia", + day: "päivä", + days: "%d päivää", + month: "kuukausi", + months: "%d kuukautta", + year: "vuosi", + years: "%d vuotta" + }; + + // The above is not a great localization because one would usually + // write "2 days ago" in Finnish as "2 päivää sitten", however + // one would write "2 days into the future" as "2:n päivän päästä" + // which cannot be achieved with localization support this simple. + // This is because Finnish has word suffixes (attached directly + // to the end of the word). The word "day" is "päivä" in Finnish. + // As workaround, the above localizations will say + // "2 päivää tulevaisuudessa" which is understandable but + // not as fluent. +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr-short.js new file mode 100644 index 0000000000..a116eadab7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr-short.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // French shortened + jQuery.timeago.settings.strings = { + prefixAgo: "il y a", + prefixFromNow: "d'ici", + seconds: "moins d'une minute", + minute: "une minute", + minutes: "%d minutes", + hour: "une heure", + hours: "%d heures", + day: "un jour", + days: "%d jours", + month: "un mois", + months: "%d mois", + year: "un an", + years: "%d ans" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr.js new file mode 100644 index 0000000000..1bb052aa16 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.fr.js @@ -0,0 +1,27 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // French + jQuery.timeago.settings.strings = { + // environ ~= about, it's optional + prefixAgo: "il y a", + prefixFromNow: "d'ici", + seconds: "moins d'une minute", + minute: "environ une minute", + minutes: "environ %d minutes", + hour: "environ une heure", + hours: "environ %d heures", + day: "environ un jour", + days: "environ %d jours", + month: "environ un mois", + months: "environ %d mois", + year: "un an", + years: "%d ans" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.gl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.gl.js new file mode 100644 index 0000000000..277bbf70f7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.gl.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Galician + jQuery.timeago.settings.strings = { + prefixAgo: "hai", + prefixFromNow: "dentro de", + suffixAgo: "", + suffixFromNow: "", + seconds: "menos dun minuto", + minute: "un minuto", + minutes: "uns %d minutos", + hour: "unha hora", + hours: "%d horas", + day: "un día", + days: "%d días", + month: "un mes", + months: "%d meses", + year: "un ano", + years: "%d anos" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.he.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.he.js new file mode 100644 index 0000000000..2cd31ab602 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.he.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Hebrew + jQuery.timeago.settings.strings = { + prefixAgo: "לפני", + prefixFromNow: "עוד", + seconds: "פחות מדקה", + minute: "דקה", + minutes: "%d דקות", + hour: "שעה", + hours: function(number){return (number===2) ? "שעתיים" : "%d שעות";}, + day: "יום", + days: function(number){return (number===2) ? "יומיים" : "%d ימים";}, + month: "חודש", + months: function(number){return (number===2) ? "חודשיים" : "%d חודשים";}, + year: "שנה", + years: function(number){return (number===2) ? "שנתיים" : "%d שנים";} + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hr.js new file mode 100644 index 0000000000..bd142979a9 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hr.js @@ -0,0 +1,54 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Croatian + var numpf = function (n, f, s, t) { + var n10; + n10 = n % 10; + if (n10 === 1 && (n === 1 || n > 20)) { + return f; + } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) { + return s; + } else { + return t; + } + }; + + jQuery.timeago.settings.strings = { + prefixAgo: "prije", + prefixFromNow: "za", + suffixAgo: null, + suffixFromNow: null, + second: "sekundu", + seconds: function (value) { + return numpf(value, "%d sekundu", "%d sekunde", "%d sekundi"); + }, + minute: "oko minutu", + minutes: function (value) { + return numpf(value, "%d minutu", "%d minute", "%d minuta"); + }, + hour: "oko jedan sat", + hours: function (value) { + return numpf(value, "%d sat", "%d sata", "%d sati"); + }, + day: "jedan dan", + days: function (value) { + return numpf(value, "%d dan", "%d dana", "%d dana"); + }, + month: "mjesec dana", + months: function (value) { + return numpf(value, "%d mjesec", "%d mjeseca", "%d mjeseci"); + }, + year: "prije godinu dana", + years: function (value) { + return numpf(value, "%d godinu", "%d godine", "%d godina"); + }, + wordSeparator: " " + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hu.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hu.js new file mode 100644 index 0000000000..0009de9e23 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hu.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Hungarian + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: null, + suffixFromNow: null, + seconds: "kevesebb mint egy perce", + minute: "körülbelül egy perce", + minutes: "%d perce", + hour: "körülbelül egy órája", + hours: "körülbelül %d órája", + day: "körülbelül egy napja", + days: "%d napja", + month: "körülbelül egy hónapja", + months: "%d hónapja", + year: "körülbelül egy éve", + years: "%d éve" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hy.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hy.js new file mode 100644 index 0000000000..3f0de6e7de --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.hy.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Armenian + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "առաջ", + suffixFromNow: "հետո", + seconds: "վայրկյաններ", + minute: "մեկ րոպե", + minutes: "%d րոպե", + hour: "մեկ ժամ", + hours: "%d ժամ", + day: "մեկ օր", + days: "%d օր", + month: "մեկ ամիս", + months: "%d ամիս", + year: "մեկ տարի", + years: "%d տարի" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.id.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.id.js new file mode 100644 index 0000000000..ca530ccf8b --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.id.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Indonesian + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "yang lalu", + suffixFromNow: "dari sekarang", + seconds: "kurang dari semenit", + minute: "sekitar satu menit", + minutes: "%d menit", + hour: "sekitar sejam", + hours: "sekitar %d jam", + day: "sehari", + days: "%d hari", + month: "sekitar sebulan", + months: "%d bulan", + year: "sekitar setahun", + years: "%d tahun" + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.is.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.is.js new file mode 100644 index 0000000000..e3d4b1fd1c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.is.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + jQuery.timeago.settings.strings = { + prefixAgo: "fyrir", + prefixFromNow: "eftir", + suffixAgo: "síðan", + suffixFromNow: null, + seconds: "minna en mínútu", + minute: "mínútu", + minutes: "%d mínútum", + hour: "klukkutíma", + hours: "um %d klukkutímum", + day: "degi", + days: "%d dögum", + month: "mánuði", + months: "%d mánuðum", + year: "ári", + years: "%d árum", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it-short.js new file mode 100644 index 0000000000..f1da0cc1b0 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Italian shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1m", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1g", + days: "%dg", + month: "1me", + months: "%dme", + year: "1a", + years: "%da", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it.js new file mode 100644 index 0000000000..e1cac84313 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.it.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Italian + jQuery.timeago.settings.strings = { + suffixAgo: "fa", + suffixFromNow: "da ora", + seconds: "meno di un minuto", + minute: "circa un minuto", + minutes: "%d minuti", + hour: "circa un'ora", + hours: "circa %d ore", + day: "un giorno", + days: "%d giorni", + month: "circa un mese", + months: "%d mesi", + year: "circa un anno", + years: "%d anni" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ja.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ja.js new file mode 100644 index 0000000000..30f3308c30 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ja.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Japanese + jQuery.timeago.settings.strings = { + prefixAgo: "", + prefixFromNow: "今から", + suffixAgo: "前", + suffixFromNow: "後", + seconds: "1 分未満", + minute: "約 1 分", + minutes: "%d 分", + hour: "約 1 時間", + hours: "約 %d 時間", + day: "約 1 日", + days: "約 %d 日", + month: "約 1 ヶ月", + months: "約 %d ヶ月", + year: "約 1 年", + years: "約 %d 年", + wordSeparator: "" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.jv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.jv.js new file mode 100644 index 0000000000..0344053d72 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.jv.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Javanesse (Boso Jowo) + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "kepungkur", + suffixFromNow: "seko saiki", + seconds: "kurang seko sakmenit", + minute: "kurang luwih sakmenit", + minutes: "%d menit", + hour: "kurang luwih sakjam", + hours: "kurang luwih %d jam", + day: "sedina", + days: "%d dina", + month: "kurang luwih sewulan", + months: "%d wulan", + year: "kurang luwih setahun", + years: "%d tahun" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ko.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ko.js new file mode 100644 index 0000000000..23d1d37808 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ko.js @@ -0,0 +1,31 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Korean + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "전", + suffixFromNow: "후", + seconds: "1분", + minute: "약 1분", + minutes: "%d분", + hour: "약 1시간", + hours: "약 %d시간", + day: "하루", + days: "%d일", + month: "약 1개월", + months: "%d개월", + year: "약 1년", + years: "%d년", + wordSeparator: " ", + numbers: [] + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ky.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ky.js new file mode 100644 index 0000000000..58dba293a8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ky.js @@ -0,0 +1,42 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Russian + function numpf(n, f, s, t) { + // f - 1, 21, 31, ... + // s - 2-4, 22-24, 32-34 ... + // t - 5-20, 25-30, ... + var n10 = n % 10; + if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) { + return f; + } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) { + return s; + } else { + return t; + } + } + + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "через", + suffixAgo: "мурун", + suffixFromNow: null, + seconds: "1 минуттан аз", + minute: "минута", + minutes: function(value) { return numpf(value, "%d минута", "%d минута", "%d минут"); }, + hour: "саат", + hours: function(value) { return numpf(value, "%d саат", "%d саат", "%d саат"); }, + day: "күн", + days: function(value) { return numpf(value, "%d күн", "%d күн", "%d күн"); }, + month: "ай", + months: function(value) { return numpf(value, "%d ай", "%d ай", "%d ай"); }, + year: "жыл", + years: function(value) { return numpf(value, "%d жыл", "%d жыл", "%d жыл"); } + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lt.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lt.js new file mode 100644 index 0000000000..2079fccd30 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lt.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + //Lithuanian + jQuery.timeago.settings.strings = { + prefixAgo: "prieš", + prefixFromNow: null, + suffixAgo: null, + suffixFromNow: "nuo dabar", + seconds: "%d sek.", + minute: "min.", + minutes: "%d min.", + hour: "val.", + hours: "%d val.", + day: "1 d.", + days: "%d d.", + month: "mėn.", + months: "%d mėn.", + year: "metus", + years: "%d metus", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lv.js new file mode 100644 index 0000000000..855d1a4ddf --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.lv.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + //Latvian + jQuery.timeago.settings.strings = { + prefixAgo: "pirms", + prefixFromNow: null, + suffixAgo: null, + suffixFromNow: "no šī brīža", + seconds: "%d sek.", + minute: "min.", + minutes: "%d min.", + hour: "st.", + hours: "%d st.", + day: "1 d.", + days: "%d d.", + month: "mēnesis.", + months: "%d mēnesis.", + year: "gads", + years: "%d gads", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.mk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.mk.js new file mode 100644 index 0000000000..301a5da835 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.mk.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Macedonian + (function() { + jQuery.timeago.settings.strings={ + prefixAgo: "пред", + prefixFromNow: "за", + suffixAgo: null, + suffixFromNow: null, + seconds: "%d секунди", + minute: "%d минута", + minutes: "%d минути", + hour: "%d час", + hours: "%d часа", + day: "%d ден", + days: "%d денови" , + month: "%d месец", + months: "%d месеци", + year: "%d година", + years: "%d години" + }; + })(); +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.nl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.nl.js new file mode 100644 index 0000000000..2c5de89c0e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.nl.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Dutch + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "over", + suffixAgo: "geleden", + suffixFromNow: null, + seconds: "minder dan een minuut", + minute: "ongeveer een minuut", + minutes: "%d minuten", + hour: "ongeveer een uur", + hours: "ongeveer %d uur", + day: "een dag", + days: "%d dagen", + month: "ongeveer een maand", + months: "%d maanden", + year: "ongeveer een jaar", + years: "%d jaar", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.no.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.no.js new file mode 100644 index 0000000000..c896337c7c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.no.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Norwegian + jQuery.timeago.settings.strings = { + prefixAgo: "for", + prefixFromNow: "om", + suffixAgo: "siden", + suffixFromNow: "", + seconds: "mindre enn et minutt", + minute: "ca. et minutt", + minutes: "%d minutter", + hour: "ca. en time", + hours: "ca. %d timer", + day: "en dag", + days: "%d dager", + month: "ca. en måned", + months: "%d måneder", + year: "ca. et år", + years: "%d år" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pl.js new file mode 100644 index 0000000000..48427846ab --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pl.js @@ -0,0 +1,39 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Polish + function numpf(n, s, t) { + // s - 2-4, 22-24, 32-34 ... + // t - 5-21, 25-31, ... + var n10 = n % 10; + if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) { + return s; + } else { + return t; + } + } + + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "za", + suffixAgo: "temu", + suffixFromNow: null, + seconds: "mniej niż minutę", + minute: "minutę", + minutes: function(value) { return numpf(value, "%d minuty", "%d minut"); }, + hour: "godzinę", + hours: function(value) { return numpf(value, "%d godziny", "%d godzin"); }, + day: "dzień", + days: "%d dni", + month: "miesiąc", + months: function(value) { return numpf(value, "%d miesiące", "%d miesięcy"); }, + year: "rok", + years: function(value) { return numpf(value, "%d lata", "%d lat"); } + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br-short.js new file mode 100644 index 0000000000..f7cd7e8d04 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Portuguese Brasil shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1m", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1d", + days: "%dd", + month: "1M", + months: "%dM", + year: "1a", + years: "%da", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br.js new file mode 100644 index 0000000000..a8701a8801 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-br.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Brazilian Portuguese + jQuery.timeago.settings.strings = { + prefixAgo: "há", + prefixFromNow: "em", + suffixAgo: null, + suffixFromNow: null, + seconds: "alguns segundos", + minute: "um minuto", + minutes: "%d minutos", + hour: "uma hora", + hours: "%d horas", + day: "um dia", + days: "%d dias", + month: "um mês", + months: "%d meses", + year: "um ano", + years: "%d anos" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-short.js new file mode 100644 index 0000000000..0b146a7998 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Portuguese shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1m", + minute: "1m", + minutes: "%dm", + hour: "1h", + hours: "%dh", + day: "1d", + days: "%dd", + month: "1M", + months: "%dM", + year: "1a", + years: "%da", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt.js new file mode 100644 index 0000000000..13791a0375 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.pt.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Portuguese + jQuery.timeago.settings.strings = { + suffixAgo: "atrás", + suffixFromNow: "a partir de agora", + seconds: "menos de um minuto", + minute: "cerca de um minuto", + minutes: "%d minutos", + hour: "cerca de uma hora", + hours: "cerca de %d horas", + day: "um dia", + days: "%d dias", + month: "cerca de um mês", + months: "%d meses", + year: "cerca de um ano", + years: "%d anos" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ro.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ro.js new file mode 100644 index 0000000000..fe59db900c --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ro.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Romanian + jQuery.timeago.settings.strings = { + prefixAgo: "acum", + prefixFromNow: "in timp de", + suffixAgo: "", + suffixFromNow: "", + seconds: "mai putin de un minut", + minute: "un minut", + minutes: "%d minute", + hour: "o ora", + hours: "%d ore", + day: "o zi", + days: "%d zile", + month: "o luna", + months: "%d luni", + year: "un an", + years: "%d ani" + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rs.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rs.js new file mode 100644 index 0000000000..b9e5188257 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rs.js @@ -0,0 +1,54 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Serbian + var numpf = function (n, f, s, t) { + var n10; + n10 = n % 10; + if (n10 === 1 && (n === 1 || n > 20)) { + return f; + } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) { + return s; + } else { + return t; + } + }; + + jQuery.timeago.settings.strings = { + prefixAgo: "pre", + prefixFromNow: "za", + suffixAgo: null, + suffixFromNow: null, + second: "sekund", + seconds: function (value) { + return numpf(value, "%d sekund", "%d sekunde", "%d sekundi"); + }, + minute: "oko minut", + minutes: function (value) { + return numpf(value, "%d minut", "%d minuta", "%d minuta"); + }, + hour: "oko jedan sat", + hours: function (value) { + return numpf(value, "%d sat", "%d sata", "%d sati"); + }, + day: "jedan dan", + days: function (value) { + return numpf(value, "%d dan", "%d dana", "%d dana"); + }, + month: "mesec dana", + months: function (value) { + return numpf(value, "%d mesec", "%d meseca", "%d meseci"); + }, + year: "godinu dana", + years: function (value) { + return numpf(value, "%d godinu", "%d godine", "%d godina"); + }, + wordSeparator: " " + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ru.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ru.js new file mode 100644 index 0000000000..4ff3f8d301 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ru.js @@ -0,0 +1,43 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Russian + function numpf(n, f, s, t) { + // f - 1, 21, 31, ... + // s - 2-4, 22-24, 32-34 ... + // t - 5-20, 25-30, ... + n = n % 100; + var n10 = n % 10; + if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) { + return f; + } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) { + return s; + } else { + return t; + } + } + + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "через", + suffixAgo: "назад", + suffixFromNow: null, + seconds: "меньше минуты", + minute: "минуту", + minutes: function(value) { return numpf(value, "%d минуту", "%d минуты", "%d минут"); }, + hour: "час", + hours: function(value) { return numpf(value, "%d час", "%d часа", "%d часов"); }, + day: "день", + days: function(value) { return numpf(value, "%d день", "%d дня", "%d дней"); }, + month: "месяц", + months: function(value) { return numpf(value, "%d месяц", "%d месяца", "%d месяцев"); }, + year: "год", + years: function(value) { return numpf(value, "%d год", "%d года", "%d лет"); } + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rw.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rw.js new file mode 100644 index 0000000000..50119e1e8e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.rw.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Kinyarwanda + jQuery.timeago.settings.strings = { + prefixAgo: "hashize", + prefixFromNow: "mu", + suffixAgo: null, + suffixFromNow: null, + seconds: "amasegonda macye", + minute: "umunota", + minutes: "iminota %d", + hour: "isaha", + hours: "amasaha %d", + day: "umunsi", + days: "iminsi %d", + month: "ukwezi", + months: "amezi %d", + year: "umwaka", + years: "imyaka %d", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.si.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.si.js new file mode 100644 index 0000000000..6fa215e9a7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.si.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Sinhalese (SI) + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "පෙර", + suffixFromNow: "පසුව", + seconds: "තත්පර කිහිපයකට", + minute: "මිනිත්තුවකට පමණ", + minutes: "මිනිත්තු %d කට", + hour: "පැයක් පමණ ", + hours: "පැය %d කට පමණ", + day: "දවසක ට", + days: "දවස් %d කට ", + month: "මාසයක් පමණ", + months: "මාස %d කට", + year: "වසරක් පමණ", + years: "වසරක් %d කට පමණ" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sk.js new file mode 100644 index 0000000000..e28ab7c9be --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sk.js @@ -0,0 +1,34 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Slovak + (function() { + function f(n, d, a) { + return a[d>=0 ? 0 : a.length===2 || n<5 ? 1 : 2]; + } + + jQuery.timeago.settings.strings = { + prefixAgo: 'pred', + prefixFromNow: 'o', + suffixAgo: null, + suffixFromNow: null, + seconds: function(n, d) {return f(n, d, ['menej ako minútou', 'menej ako minútu']);}, + minute: function(n, d) {return f(n, d, ['minútou', 'minútu']);}, + minutes: function(n, d) {return f(n, d, ['%d minútami', '%d minúty', '%d minút']);}, + hour: function(n, d) {return f(n, d, ['hodinou', 'hodinu']);}, + hours: function(n, d) {return f(n, d, ['%d hodinami', '%d hodiny', '%d hodín']);}, + day: function(n, d) {return f(n, d, ['%d dňom', '%d deň']);}, + days: function(n, d) {return f(n, d, ['%d dňami', '%d dni', '%d dní']);}, + month: function(n, d) {return f(n, d, ['%d mesiacom', '%d mesiac']);}, + months: function(n, d) {return f(n, d, ['%d mesiacmi', '%d mesiace', '%d mesiacov']);}, + year: function(n, d) {return f(n, d, ['%d rokom', '%d rok']);}, + years: function(n, d) {return f(n, d, ['%d rokmi', '%d roky', '%d rokov']);} + }; + })(); +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sl.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sl.js new file mode 100644 index 0000000000..9f0329ac67 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sl.js @@ -0,0 +1,46 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Slovenian with support for dual + var numpf = function (n, a) { + return a[n%100===1 ? 1 : n%100===2 ? 2 : n%100===3 || n%100===4 ? 3 : 0]; + }; + + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "čez", + suffixAgo: "nazaj", + suffixFromNow: null, + second: "sekundo", + seconds: function (value) { + return numpf(value, ["%d sekund", "%d sekundo", "%d sekundi", "%d sekunde"]); + }, + minute: "minuto", + minutes: function (value) { + return numpf(value, ["%d minut", "%d minuto", "%d minuti", "%d minute"]); + }, + hour: "eno uro", + hours: function (value) { + return numpf(value, ["%d ur", "%d uro", "%d uri", "%d ure"]); + }, + day: "en dan", + days: function (value) { + return numpf(value, ["%d dni", "%d dan", "%d dneva", "%d dni"]); + }, + month: "en mesec", + months: function (value) { + return numpf(value, ["%d mesecev", "%d mesec", "%d meseca", "%d mesece"]); + }, + year: "eno leto", + years: function (value) { + return numpf(value, ["%d let", "%d leto", "%d leti", "%d leta"]); + }, + wordSeparator: " " + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sq.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sq.js new file mode 100644 index 0000000000..cb8ae703a8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sq.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Albanian SQ + jQuery.timeago.settings.strings = { + suffixAgo: "më parë", + suffixFromNow: "tani", + seconds: "më pak se një minutë", + minute: "rreth një minutë", + minutes: "%d minuta", + hour: "rreth një orë", + hours: "rreth %d orë", + day: "një ditë", + days: "%d ditë", + month: "rreth një muaj", + months: "%d muaj", + year: "rreth një vit", + years: "%d vjet" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sr.js new file mode 100644 index 0000000000..bd1efe79a7 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sr.js @@ -0,0 +1,54 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Serbian + var numpf = function (n, f, s, t) { + var n10; + n10 = n % 10; + if (n10 === 1 && (n === 1 || n > 20)) { + return f; + } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) { + return s; + } else { + return t; + } + }; + + jQuery.timeago.settings.strings = { + prefixAgo: "пре", + prefixFromNow: "за", + suffixAgo: null, + suffixFromNow: null, + second: "секунд", + seconds: function (value) { + return numpf(value, "%d секунд", "%d секунде", "%d секунди"); + }, + minute: "један минут", + minutes: function (value) { + return numpf(value, "%d минут", "%d минута", "%d минута"); + }, + hour: "један сат", + hours: function (value) { + return numpf(value, "%d сат", "%d сата", "%d сати"); + }, + day: "један дан", + days: function (value) { + return numpf(value, "%d дан", "%d дана", "%d дана"); + }, + month: "месец дана", + months: function (value) { + return numpf(value, "%d месец", "%d месеца", "%d месеци"); + }, + year: "годину дана", + years: function (value) { + return numpf(value, "%d годину", "%d године", "%d година"); + }, + wordSeparator: " " + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sv.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sv.js new file mode 100644 index 0000000000..caf09dbb0a --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.sv.js @@ -0,0 +1,28 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Swedish + jQuery.timeago.settings.strings = { + prefixAgo: "för", + prefixFromNow: "om", + suffixAgo: "sedan", + suffixFromNow: "", + seconds: "mindre än en minut", + minute: "ungefär en minut", + minutes: "%d minuter", + hour: "ungefär en timme", + hours: "ungefär %d timmar", + day: "en dag", + days: "%d dagar", + month: "ungefär en månad", + months: "%d månader", + year: "ungefär ett år", + years: "%d år" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.th.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.th.js new file mode 100644 index 0000000000..23d59d48e6 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.th.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Thai + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "ที่แล้ว", + suffixFromNow: "จากตอนนี้", + seconds: "น้อยกว่าหนึ่งนาที", + minute: "ประมาณหนึ่งนาที", + minutes: "%d นาที", + hour: "ประมาณหนึ่งชั่วโมง", + hours: "ประมาณ %d ชั่วโมง", + day: "หนึ่งวัน", + days: "%d วัน", + month: "ประมาณหนึ่งเดือน", + months: "%d เดือน", + year: "ประมาณหนึ่งปี", + years: "%d ปี", + wordSeparator: "", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr-short.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr-short.js new file mode 100644 index 0000000000..ba290dd399 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr-short.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Turkish shortened + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "", + suffixFromNow: "", + seconds: "1dk", + minute: "1dk", + minutes: "%ddk", + hour: "1s", + hours: "%ds", + day: "1g", + days: "%dg", + month: "1ay", + months: "%day", + year: "1y", + years: "%dy", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr.js new file mode 100644 index 0000000000..8e0d2d4e9d --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.tr.js @@ -0,0 +1,26 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Turkish + jQuery.timeago.settings.strings = { + suffixAgo: 'önce', + suffixFromNow: null, + seconds: 'birkaç saniye', + minute: '1 dakika', + minutes: '%d dakika', + hour: '1 saat', + hours: '%d saat', + day: '1 gün', + days: '%d gün', + month: '1 ay', + months: '%d ay', + year: '1 yıl', + years: '%d yıl' + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uk.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uk.js new file mode 100644 index 0000000000..489963b5d1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uk.js @@ -0,0 +1,42 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Ukrainian + function numpf(n, f, s, t) { + // f - 1, 21, 31, ... + // s - 2-4, 22-24, 32-34 ... + // t - 5-20, 25-30, ... + var n10 = n % 10; + if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) { + return f; + } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) { + return s; + } else { + return t; + } + } + + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "через", + suffixAgo: "тому", + suffixFromNow: null, + seconds: "менше хвилини", + minute: "хвилина", + minutes: function(value) { return numpf(value, "%d хвилина", "%d хвилини", "%d хвилин"); }, + hour: "година", + hours: function(value) { return numpf(value, "%d година", "%d години", "%d годин"); }, + day: "день", + days: function(value) { return numpf(value, "%d день", "%d дні", "%d днів"); }, + month: "місяць", + months: function(value) { return numpf(value, "%d місяць", "%d місяці", "%d місяців"); }, + year: "рік", + years: function(value) { return numpf(value, "%d рік", "%d роки", "%d років"); } + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ur.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ur.js new file mode 100644 index 0000000000..9d0cd402da --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.ur.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Urdu + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "پہلے", + suffixFromNow: "اب سے", + seconds: "کچھ سیکنڈز", + minute: "تقریباً ایک منٹ", + minutes: "%d منٹ", + hour: "تقریباً ایک گھنٹہ", + hours: "تقریباً %d گھنٹے", + day: "ایک دن", + days: "%d دن", + month: "تقریباً ایک مہینہ", + months: "%d مہینے", + year: "تقریباً ایک سال", + years: "%d سال", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uz.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uz.js new file mode 100644 index 0000000000..f4ce8b33b1 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.uz.js @@ -0,0 +1,29 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + //Uzbek + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "keyin", + suffixAgo: "avval", + suffixFromNow: null, + seconds: "bir necha soniya", + minute: "1 daqiqa", + minutes: function(value) { return "%d daqiqa"; }, + hour: "1 soat", + hours: function(value) { return "%d soat"; }, + day: "1 kun", + days: function(value) { return "%d kun"; }, + month: "1 oy", + months: function(value) { return "%d oy"; }, + year: "1 yil", + years: function(value) { return "%d yil"; }, + wordSeparator: " " + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.vi.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.vi.js new file mode 100644 index 0000000000..30f592ac35 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.vi.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Vietnamese + jQuery.timeago.settings.strings = { + prefixAgo: 'cách đây', + prefixFromNow: null, + suffixAgo: null, + suffixFromNow: "trước", + seconds: "chưa đến một phút", + minute: "khoảng một phút", + minutes: "%d phút", + hour: "khoảng một tiếng", + hours: "khoảng %d tiếng", + day: "một ngày", + days: "%d ngày", + month: "khoảng một tháng", + months: "%d tháng", + year: "khoảng một năm", + years: "%d năm", + wordSeparator: " ", + numbers: [] + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-CN.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-CN.js new file mode 100644 index 0000000000..c672fb7b38 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-CN.js @@ -0,0 +1,31 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Simplified Chinese + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "从现在开始", + suffixAgo: "之前", + suffixFromNow: null, + seconds: "不到1分钟", + minute: "大约1分钟", + minutes: "%d分钟", + hour: "大约1小时", + hours: "大约%d小时", + day: "1天", + days: "%d天", + month: "大约1个月", + months: "%d月", + year: "大约1年", + years: "%d年", + numbers: [], + wordSeparator: "" + }; +})); + diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-TW.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-TW.js new file mode 100644 index 0000000000..33f9f74627 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/timeago/locales/jquery.timeago.zh-TW.js @@ -0,0 +1,30 @@ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function (jQuery) { + // Traditional Chinese, zh-tw + jQuery.timeago.settings.strings = { + prefixAgo: null, + prefixFromNow: "從現在開始", + suffixAgo: "之前", + suffixFromNow: null, + seconds: "不到1分鐘", + minute: "大約1分鐘", + minutes: "%d分鐘", + hour: "大約1小時", + hours: "%d小時", + day: "大約1天", + days: "%d天", + month: "大約1個月", + months: "%d個月", + year: "大約1年", + years: "%d年", + numbers: [], + wordSeparator: "" + }; +})); diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/to-mark/to-mark.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/to-mark/to-mark.min.js new file mode 100644 index 0000000000..a12048b67e --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/to-mark/to-mark.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["to-mark"]=t():e.toMark=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=3)}([function(e,t,n){"use strict";var r=n(1),o=/\n$/g,i=/[ \xA0]+\n\n/g,u=/([ \xA0]+\n){2,}/g,a=/href\=\"(.*?)\"/,c=/^/gm,s=r.factory({TEXT_NODE:function(e){var t;return t=this.trim(this.getSpaceCollapsedText(e.nodeValue)),this._isNeedEscapeHtml(t)&&(t=this.escapeTextHtml(t)),this._isNeedEscape(t)&&(t=this.escapeText(t)),this.getSpaceControlled(t,e)},"CODE TEXT_NODE":function(e){return e.nodeValue},"EM, I":function(e,t){var n="";return this.isEmptyText(t)||(n="_"+t+"_"),n},"STRONG, B":function(e,t){var n="";return this.isEmptyText(t)||(n="**"+t+"**"),n},A:function(e,t){var n,r,o=t,i="";return n=a.exec(e.outerHTML),n&&(r=n[1].replace(/&/g,"&")),e.title&&(i=' "'+e.title+'"'),!this.isEmptyText(t)&&r&&(o="["+this.escapeTextForLink(t)+"]("+r+i+")"),o},IMG:function(e){var t="",n=e.getAttribute("src"),r=e.alt;return n&&(t="!["+this.escapeTextForLink(r)+"]("+n+")"),t},BR:function(){return" \n"},CODE:function(e,t){var n,r,o="";return this.isEmptyText(t)||(r=parseInt(e.getAttribute("data-backticks"),10),n=isNaN(r)?"`":Array(r+1).join("`"),o=n+t+n),o},P:function(e,t){var n="";return t=t.replace(u," \n"),this.isEmptyText(t)||(n="\n\n"+t+"\n\n"),n},"BLOCKQUOTE P":function(e,t){return t},"LI P":function(e,t){var n="";return this.isEmptyText(t)||(n=t),n},"H1, H2, H3, H4, H5, H6":function(e,t){for(var n="",r=parseInt(e.tagName.charAt(1),10);r;)n+="#",r-=1;return n+=" ",n+=t,"\n\n"+n+"\n\n"},"LI H1, LI H2, LI H3, LI H4, LI H5, LI H6":function(e){return"<"+e.tagName.toLowerCase()+">"+e.innerHTML+""},"UL, OL":function(e,t){return"\n\n"+t+"\n\n"},"LI OL, LI UL":function(e,t){var n,r;return r=t.replace(i,"\n"),r=r.replace(o,""),n=r.replace(c," "),"\n"+n},"UL LI":function(e,t){var n="";return t=t.replace(u," \n"),e.firstChild&&"P"===e.firstChild.tagName&&(n+="\n"),n+="* "+t+"\n"},"OL LI":function(e,t){for(var n="",r=1;e.previousSibling;)e=e.previousSibling,1===e.nodeType&&"LI"===e.tagName&&(r+=1);return t=t.replace(u," \n"),e.firstChild&&"P"===e.firstChild.tagName&&(n+="\n"),n+=r+". "+t+"\n"},HR:function(){return"\n\n- - -\n\n"},BLOCKQUOTE:function(e,t){var n,r;return t=t.replace(u,"\n\n"),r=this.trim(t),n=r.replace(c,"> "),"\n\n"+n+"\n\n"},"PRE CODE":function(e,t){var n,r;return r=t.replace(o,""),n=r.replace(c," "),"\n\n"+n+"\n\n"}});e.exports=s},function(e,t,n){"use strict";function r(e,t,n){var r;n=n||null;for(r in e)if(e.hasOwnProperty(r)&&t.call(n,e[r],r,e)===!1)break}function o(e){this.rules={},e&&this.addRules(e)}function i(e){var t=e.tagName;return"S"===t||"B"===t||"I"===t||"EM"===t||"STRONG"===t||"A"===t||"IMG"===t||"CODE"===t}function u(e,t){r(t,function(t,n){"converter"!==n?(e[n]||(e[n]={}),u(e[n],t)):e[n]=t})}var a=/^\u0020/,c=/.+\u0020$/,s=/[\n\s\t]+/g,p=/^[\u0020\r\n\t]+|[\u0020\r\n\t]+$/g,l=/[\u0020]+/g,f=/[~>()*{}\[\]_`+-.!#|]/g,d=/[\[\]\(\)<>]/g,g=3;o.prototype.lineFeedReplacement="​​",o.prototype.addRule=function(e,t){var n=e.split(", "),r=n.pop();for(t.fname=e;r;)this._setConverterWithSelector(r,t),r=n.pop()},o.prototype.addRules=function(e){r(e,function(e,t){this.addRule(t,e)},this)},o.prototype.getSpaceControlled=function(e,t){var n,r="",o="";return t.previousSibling&&(t.previousSibling.nodeType===g||i(t.previousSibling))&&(n=t.previousSibling.innerHTML||t.previousSibling.nodeValue,(c.test(n)||a.test(t.innerHTML||t.nodeValue))&&(r=" ")),t.nextSibling&&(t.nextSibling.nodeType===g||i(t.nextSibling))&&(n=t.nextSibling.innerHTML||t.nextSibling.nodeValue,(a.test(n)||c.test(t.innerHTML||t.nodeValue))&&(o=" ")),r+e+o},o.prototype.convert=function(e,t){var n,r=this._getConverter(e);return e&&e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("data-tomark-pass")?(e.removeAttribute("data-tomark-pass"),n=e.outerHTML):r?n=r.call(this,e,t):e&&(n=this.getSpaceControlled(this._getInlineHtml(e,t),e)),n||""},o.prototype._getInlineHtml=function(e,t){var n=e.outerHTML,r=e.tagName,o=t.replace(/\$/g,"$$$$");return n.replace(new RegExp("(<"+r+" ?.*?>).*()","i"),"$1"+o+"$2")},o.prototype._getConverter=function(e){for(var t,n=this.rules;e&&n;)n=this._getNextRule(n,this._getRuleNameFromNode(e)),e=this._getPrevNode(e),n&&n.converter&&(t=n.converter);return t},o.prototype._getNextRule=function(e,t){return e[t]},o.prototype._getRuleNameFromNode=function(e){return e.tagName||"TEXT_NODE"},o.prototype._getPrevNode=function(e){var t,n=e.parentNode;return n&&!n.__htmlRootByToMark&&(t=n),t},o.prototype._setConverterWithSelector=function(e,t){var n=this.rules;this._eachSelector(e,function(e){n[e]||(n[e]={}),n=n[e]}),n.converter=t},o.prototype._eachSelector=function(e,t){var n,r;for(n=e.split(" "),r=n.length-1;r>=0;)t(n[r]),r-=1},o.prototype.trim=function(e){return e.replace(p,"")},o.prototype.isEmptyText=function(e){return""===e.replace(s,"")},o.prototype.getSpaceCollapsedText=function(e){return e.replace(l," ")},o.prototype.escapeText=function(e){return e.replace(f,function(e){return"\\"+e})},o.prototype.escapeTextForLink=function(e){return e.replace(d,function(e){return"\\"+e})},o.prototype.escapeTextHtml=function(e){return e=e.replace(o.markdownTextToEscapeHtmlRx,function(e){return"\\"+e})},o.markdownTextToEscapeRx={codeblock:/(^ {4}[^\n]+\n*)+/,hr:/^ *((\* *){3,}|(- *){3,} *|(_ *){3,}) */,heading:/^(#{1,6}) +[\s\S]+/,lheading:/^([^\n]+)\n *(=|-){2,} */,blockquote:/^( *>[^\n]+.*)+/,list:/^ *(\*+|-+|\d+\.) [\s\S]+/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? */,link:/!?\[.*\]\(.*\)/,reflink:/!?\[.*\]\s*\[([^\]]*)\]/,strong:/__(\S[\s\S]*\h)__|\*\*(\S[\s\S]*\S)\*\*/,em:/_(\S[\s\S]*\S)_|\*(\S[\s\S]*\S)\*/,strikeThrough:/~~(\S[\s\S]*\S)~~/,code:/(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,verticalBar:/\u007C/,codeblockGfm:/^(`{3,})/,codeblockTildes:/^(~{3,})/},o.markdownTextToEscapeHtmlRx=/<([a-zA-Z_][a-zA-Z0-9\-\._]*)(\s|[^\\\/>])*\/?>|<(\/)([a-zA-Z_][a-zA-Z0-9\-\._]*)\s*\/?>||<([a-zA-Z_][a-zA-Z0-9\-\.:\/]*)>/g,o.prototype._isNeedEscape=function(e){var t,n=!1,r=o.markdownTextToEscapeRx;for(t in r)if(r.hasOwnProperty(t)&&r[t].test(e)){n=!0;break}return n},o.prototype._isNeedEscapeHtml=function(e){return o.markdownTextToEscapeHtmlRx.test(e)},o.prototype.mix=function(e){u(this.rules,e.rules)},o.factory=function(e,t){var n=new o;return t?n.mix(e):t=e,n.addRules(t),n},e.exports=o},function(e,t,n){"use strict";function r(e,t){var n;return e.className.indexOf("task-list-item")!==-1&&(n=e.className.indexOf("checked")!==-1?"x":" ",t="["+n+"] "+t),t}function o(e){var t,n,r,o;return t=e.align,o=e.textContent?e.textContent.length:e.innerText.length,n="",r="",t&&("left"===t?(n=":",o-=1):"right"===t?(r=":",o-=1):"center"===t&&(r=":",n=":",o-=2)),n+u("-",o)+r}function i(e,t){var n,r=e.childNodes,o=r.length,i=[];for(n=0;n1;)n+=e,t-=1;return n}var a=n(1),c=n(0),s=a.factory(c,{"DEL, S":function(e,t){return"~~"+t+"~~"},"PRE CODE":function(e,t){var n,r="",o=e.getAttribute("data-backticks");return e.getAttribute("data-language")&&(r=" "+e.getAttribute("data-language")),o=parseInt(o,10),n=isNaN(o)?"```":Array(o+1).join("`"),t=t.replace(/(\r\n)|(\r)|(\n)/g,this.lineFeedReplacement),"\n\n"+n+r+"\n"+t+"\n"+n+"\n\n"},PRE:function(e,t){return t},"UL LI":function(e,t){return c.convert(e,r(e,t))},"OL LI":function(e,t){return c.convert(e,r(e,t))},TABLE:function(e,t){return"\n\n"+t+"\n\n"},"TBODY, TFOOT":function(e,t){return t},"TR TD, TR TH":function(e,t){return t=t.replace(/(\r\n)|(\r)|(\n)/g,"")," "+t+" |"},"TD BR, TH BR":function(){return"
    "},TR:function(e,t){return"|"+t+"\n"},THEAD:function(e,t){var n,r,u,a="";for(r=i(i(e,"TR")[0],"TH"),u=r.length,n=0;n=3?"\n\n":e>=1?"\n":e}),e=e.replace(f,""),e=e.replace(new RegExp(n,"g"),"\n"),t&&(e=e.replace(g,"\n")),e}function u(e,t){var n,r,o,i="",a=e.getNode();for(n=0,r=a.childNodes.length;n<"),e=e.replace(a,"> <")}var i=/^[\s\r\n\t]+|[\s\r\n\t]+$/g,u=/>[\r\n\t]+[ ]+ div { + position: relative; + pointer-events: auto; + overflow: hidden; + margin: 0 0 6px; + padding: 15px 15px 15px 50px; + width: 300px; + -moz-border-radius: 3px 3px 3px 3px; + -webkit-border-radius: 3px 3px 3px 3px; + border-radius: 3px 3px 3px 3px; + background-position: 15px center; + background-repeat: no-repeat; + -moz-box-shadow: 0 0 12px #999999; + -webkit-box-shadow: 0 0 12px #999999; + box-shadow: 0 0 12px #999999; + color: #FFFFFF; + opacity: 0.8; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); + filter: alpha(opacity=80); +} +#toast-container > div.rtl { + direction: rtl; + padding: 15px 50px 15px 15px; + background-position: right 15px center; +} +#toast-container > div:hover { + -moz-box-shadow: 0 0 12px #000000; + -webkit-box-shadow: 0 0 12px #000000; + box-shadow: 0 0 12px #000000; + opacity: 1; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); + filter: alpha(opacity=100); + cursor: pointer; +} +#toast-container > .toast-info { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; +} +#toast-container > .toast-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; +} +#toast-container > .toast-success { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; +} +#toast-container > .toast-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; +} +#toast-container.toast-top-center > div, +#toast-container.toast-bottom-center > div { + width: 300px; + margin-left: auto; + margin-right: auto; +} +#toast-container.toast-top-full-width > div, +#toast-container.toast-bottom-full-width > div { + width: 96%; + margin-left: auto; + margin-right: auto; +} +.toast { + background-color: #030303; +} +.toast-success { + background-color: #51A351; +} +.toast-error { + background-color: #BD362F; +} +.toast-info { + background-color: #2F96B4; +} +.toast-warning { + background-color: #F89406; +} +.toast-progress { + position: absolute; + left: 0; + bottom: 0; + height: 4px; + background-color: #000000; + opacity: 0.4; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); + filter: alpha(opacity=40); +} +/*Responsive Design*/ +@media all and (max-width: 240px) { + #toast-container > div { + padding: 8px 8px 8px 50px; + width: 11em; + } + #toast-container > div.rtl { + padding: 8px 50px 8px 8px; + } + #toast-container .toast-close-button { + right: -0.2em; + top: -0.2em; + } + #toast-container .rtl .toast-close-button { + left: -0.2em; + right: 0.2em; + } +} +@media all and (min-width: 241px) and (max-width: 480px) { + #toast-container > div { + padding: 8px 8px 8px 50px; + width: 18em; + } + #toast-container > div.rtl { + padding: 8px 50px 8px 8px; + } + #toast-container .toast-close-button { + right: -0.2em; + top: -0.2em; + } + #toast-container .rtl .toast-close-button { + left: -0.2em; + right: 0.2em; + } +} +@media all and (min-width: 481px) and (max-width: 768px) { + #toast-container > div { + padding: 15px 15px 15px 50px; + width: 25em; + } + #toast-container > div.rtl { + padding: 15px 50px 15px 15px; + } +} diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.js.map b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.js.map new file mode 100644 index 0000000000..47a9639aba --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["toastr.js"],"names":["define","$","error","message","title","optionsOverride","notify","type","toastType","iconClass","getOptions","iconClasses","getContainer","options","create","$container","containerId","length","createContainer","info","subscribe","callback","listener","success","warning","clear","$toastElement","clearOptions","clearToast","clearContainer","remove","removeToast","children","toastsToClear","i","force","hideMethod","duration","hideDuration","easing","hideEasing","complete","attr","addClass","positionClass","appendTo","target","getDefaults","tapToDismiss","toastClass","debug","showMethod","showDuration","showEasing","onShown","undefined","onHidden","closeMethod","closeDuration","closeEasing","closeOnHover","extendedTimeOut","timeOut","titleClass","messageClass","escapeHtml","closeHtml","closeClass","newestOnTop","preventDuplicates","progressBar","progressClass","rtl","publish","args","map","source","replace","personalizeToast","setIcon","setTitle","setMessage","setCloseButton","setProgressBar","setRTL","setSequence","setAria","ariaValue","handleEvents","hover","stickAround","delayedHideToast","onclick","click","hideToast","closeButton","$closeElement","event","stopPropagation","cancelBubble","onCloseClick","displayToast","hide","intervalId","setTimeout","maxHideTime","parseFloat","hideEta","Date","getTime","setInterval","updateProgress","prepend","append","suffix","$titleElement","$messageElement","$progressElement","shouldExit","previousToast","override","method","clearTimeout","response","state","endTime","stop","percentage","width","extend","toastId","startTime","console","log","toastr","is","version","amd","deps","factory","module","exports","require","window","jQuery"],"mappings":"CAaC,SAAUA,GACPA,GAAQ,UAAW,SAAUC,GACzB,MAAO,YA8BH,QAASC,GAAMC,EAASC,EAAOC,GAC3B,MAAOC,IACHC,KAAMC,EAAUN,MAChBO,UAAWC,IAAaC,YAAYT,MACpCC,QAASA,EACTE,gBAAiBA,EACjBD,MAAOA,IAIf,QAASQ,GAAaC,EAASC,GAG3B,MAFKD,KAAWA,EAAUH,KAC1BK,EAAad,EAAE,IAAMY,EAAQG,aACzBD,EAAWE,OACJF,GAEPD,IACAC,EAAaG,EAAgBL,IAE1BE,GAGX,QAASI,GAAKhB,EAASC,EAAOC,GAC1B,MAAOC,IACHC,KAAMC,EAAUW,KAChBV,UAAWC,IAAaC,YAAYQ,KACpChB,QAASA,EACTE,gBAAiBA,EACjBD,MAAOA,IAIf,QAASgB,GAAUC,GACfC,EAAWD,EAGf,QAASE,GAAQpB,EAASC,EAAOC,GAC7B,MAAOC,IACHC,KAAMC,EAAUe,QAChBd,UAAWC,IAAaC,YAAYY,QACpCpB,QAASA,EACTE,gBAAiBA,EACjBD,MAAOA,IAIf,QAASoB,GAAQrB,EAASC,EAAOC,GAC7B,MAAOC,IACHC,KAAMC,EAAUgB,QAChBf,UAAWC,IAAaC,YAAYa,QACpCrB,QAASA,EACTE,gBAAiBA,EACjBD,MAAOA,IAIf,QAASqB,GAAMC,EAAeC,GAC1B,GAAId,GAAUH,GACTK,IAAcH,EAAaC,GAC3Be,EAAWF,EAAeb,EAASc,IACpCE,EAAehB,GAIvB,QAASiB,GAAOJ,GACZ,GAAIb,GAAUH,GAEd,OADKK,IAAcH,EAAaC,GAC5Ba,GAAuD,IAAtCzB,EAAE,SAAUyB,GAAeT,WAC5Cc,GAAYL,QAGZX,EAAWiB,WAAWf,QACtBF,EAAWe,UAMnB,QAASD,GAAgBhB,GAErB,IAAK,GADDoB,GAAgBlB,EAAWiB,WACtBE,EAAID,EAAchB,OAAS,EAAGiB,GAAK,EAAGA,IAC3CN,EAAW3B,EAAEgC,EAAcC,IAAKrB,GAIxC,QAASe,GAAYF,EAAeb,EAASc,GACzC,GAAIQ,MAAQR,IAAgBA,EAAaQ,QAAQR,EAAaQ,KAC9D,UAAIT,IAAkBS,GAA+C,IAAtClC,EAAE,SAAUyB,GAAeT,UACtDS,EAAcb,EAAQuB,aAClBC,SAAUxB,EAAQyB,aAClBC,OAAQ1B,EAAQ2B,WAChBC,SAAU,WAAcV,EAAYL,OAEjC,GAKf,QAASR,GAAgBL,GAMrB,MALAE,GAAad,EAAE,UACVyC,KAAK,KAAM7B,EAAQG,aACnB2B,SAAS9B,EAAQ+B,eAEtB7B,EAAW8B,SAAS5C,EAAEY,EAAQiC,SACvB/B,EAGX,QAASgC,KACL,OACIC,cAAc,EACdC,WAAY,QACZjC,YAAa,kBACbkC,OAAO,EAEPC,WAAY,SACZC,aAAc,IACdC,WAAY,QACZC,QAASC,OACTnB,WAAY,UACZE,aAAc,IACdE,WAAY,QACZgB,SAAUD,OACVE,aAAa,EACbC,eAAe,EACfC,aAAa,EACbC,cAAc,EAEdC,gBAAiB,IACjBlD,aACIT,MAAO,cACPiB,KAAM,aACNI,QAAS,gBACTC,QAAS,iBAEbf,UAAW,aACXmC,cAAe,kBACfkB,QAAS,IACTC,WAAY,cACZC,aAAc,gBACdC,YAAY,EACZnB,OAAQ,OACRoB,UAAW,yCACXC,WAAY,qBACZC,aAAa,EACbC,mBAAmB,EACnBC,aAAa,EACbC,cAAe,iBACfC,KAAK,GAIb,QAASC,GAAQC,GACRpD,GACLA,EAASoD,GAGb,QAASpE,GAAOqE,GAgDZ,QAASV,GAAWW,GAKhB,MAJc,OAAVA,IACAA,EAAS,IAGNA,EACFC,QAAQ,KAAM,SACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QAGvB,QAASC,KACLC,IACAC,IACAC,IACAC,IACAC,IACAC,IACAC,IACAC,IAGJ,QAASA,KACL,GAAIC,GAAY,EAChB,QAAQZ,EAAIlE,WACR,IAAK,gBACL,IAAK,aACD8E,EAAa,QACb,MACJ,SACIA,EAAY,YAEpB7D,EAAcgB,KAAK,YAAa6C,GAGpC,QAASC,KACD3E,EAAQ+C,cACRlC,EAAc+D,MAAMC,EAAaC,IAGhC9E,EAAQ+E,SAAW/E,EAAQmC,cAC5BtB,EAAcmE,MAAMC,GAGpBjF,EAAQkF,aAAeC,GACvBA,EAAcH,MAAM,SAAUI,GACtBA,EAAMC,gBACND,EAAMC,kBACwB3C,SAAvB0C,EAAME,cAA8BF,EAAME,gBAAiB,IAClEF,EAAME,cAAe,GAGrBtF,EAAQuF,cACRvF,EAAQuF,aAAaH,GAGzBH,GAAU,KAIdjF,EAAQ+E,SACRlE,EAAcmE,MAAM,SAAUI,GAC1BpF,EAAQ+E,QAAQK,GAChBH,MAKZ,QAASO,KACL3E,EAAc4E,OAEd5E,EAAcb,EAAQsC,aACjBd,SAAUxB,EAAQuC,aAAcb,OAAQ1B,EAAQwC,WAAYZ,SAAU5B,EAAQyC,UAG/EzC,EAAQiD,QAAU,IAClByC,EAAaC,WAAWV,EAAWjF,EAAQiD,SAC3CQ,EAAYmC,YAAcC,WAAW7F,EAAQiD,SAC7CQ,EAAYqC,SAAU,GAAIC,OAAOC,UAAYvC,EAAYmC,YACrD5F,EAAQyD,cACRA,EAAYiC,WAAaO,YAAYC,EAAgB,MAKjE,QAAShC,KACDJ,EAAIlE,WACJiB,EAAciB,SAAS9B,EAAQoC,YAAYN,SAASlC,GAI5D,QAAS4E,KACDxE,EAAQuD,YACRrD,EAAWiG,QAAQtF,GAEnBX,EAAWkG,OAAOvF,GAI1B,QAASsD,KACL,GAAIL,EAAIvE,MAAO,CACX,GAAI8G,GAASvC,EAAIvE,KACbS,GAAQoD,aACRiD,EAASjD,EAAWU,EAAIvE,QAE5B+G,EAAcF,OAAOC,GAAQvE,SAAS9B,EAAQkD,YAC9CrC,EAAcuF,OAAOE,IAI7B,QAASlC,KACL,GAAIN,EAAIxE,QAAS,CACb,GAAI+G,GAASvC,EAAIxE,OACbU,GAAQoD,aACRiD,EAASjD,EAAWU,EAAIxE,UAE5BiH,EAAgBH,OAAOC,GAAQvE,SAAS9B,EAAQmD,cAChDtC,EAAcuF,OAAOG,IAI7B,QAASlC,KACDrE,EAAQkF,cACRC,EAAcrD,SAAS9B,EAAQsD,YAAYzB,KAAK,OAAQ,UACxDhB,EAAcsF,QAAQhB,IAI9B,QAASb,KACDtE,EAAQyD,cACR+C,EAAiB1E,SAAS9B,EAAQ0D,eAClC7C,EAAcsF,QAAQK,IAI9B,QAASjC,KACDvE,EAAQ2D,KACR9C,EAAciB,SAAS,OAI/B,QAAS2E,GAAWzG,EAAS8D,GACzB,GAAI9D,EAAQwD,kBAAmB,CAC3B,GAAIM,EAAIxE,UAAYoH,EAChB,OAAO,CAEPA,GAAgB5C,EAAIxE,QAG5B,OAAO,EAGX,QAAS2F,GAAU0B,GACf,GAAIC,GAASD,GAAY3G,EAAQ4C,eAAgB,EAAQ5C,EAAQ4C,YAAc5C,EAAQuB,WACnFC,EAAWmF,GAAY3G,EAAQ6C,iBAAkB,EACjD7C,EAAQ6C,cAAgB7C,EAAQyB,aAChCC,EAASiF,GAAY3G,EAAQ8C,eAAgB,EAAQ9C,EAAQ8C,YAAc9C,EAAQ2B,UACvF,KAAIvC,EAAE,SAAUyB,GAAeT,QAAWuG,EAI1C,MADAE,cAAapD,EAAYiC,YAClB7E,EAAc+F,IACjBpF,SAAUA,EACVE,OAAQA,EACRE,SAAU,WACNV,EAAYL,GACZgG,aAAanB,GACT1F,EAAQ2C,UAA+B,WAAnBmE,EAASC,OAC7B/G,EAAQ2C,WAEZmE,EAASC,MAAQ,SACjBD,EAASE,QAAU,GAAIjB,MACvBnC,EAAQkD,MAKpB,QAAShC,MACD9E,EAAQiD,QAAU,GAAKjD,EAAQgD,gBAAkB,KACjD0C,EAAaC,WAAWV,EAAWjF,EAAQgD,iBAC3CS,EAAYmC,YAAcC,WAAW7F,EAAQgD,iBAC7CS,EAAYqC,SAAU,GAAIC,OAAOC,UAAYvC,EAAYmC,aAIjE,QAASf,KACLgC,aAAanB,GACbjC,EAAYqC,QAAU,EACtBjF,EAAcoG,MAAK,GAAM,GAAMjH,EAAQsC,aAClCd,SAAUxB,EAAQuC,aAAcb,OAAQ1B,EAAQwC,aAIzD,QAAS0D,KACL,GAAIgB,IAAezD,EAAYqC,SAAW,GAAIC,OAAOC,WAAcvC,EAAYmC,YAAe,GAC9FY,GAAiBW,MAAMD,EAAa,KApPxC,GAAIlH,GAAUH,IACVD,EAAYkE,EAAIlE,WAAaI,EAAQJ,SAOzC,IALqC,mBAAzBkE,GAAmB,kBAC3B9D,EAAUZ,EAAEgI,OAAOpH,EAAS8D,EAAItE,iBAChCI,EAAYkE,EAAItE,gBAAgBI,WAAaA,IAG7C6G,EAAWzG,EAAS8D,GAAxB,CAEAuD,IAEAnH,EAAaH,EAAaC,GAAS,EAEnC,IAAI0F,GAAa,KACb7E,EAAgBzB,EAAE,UAClBkH,EAAgBlH,EAAE,UAClBmH,EAAkBnH,EAAE,UACpBoH,EAAmBpH,EAAE,UACrB+F,EAAgB/F,EAAEY,EAAQqD,WAC1BI,GACAiC,WAAY,KACZI,QAAS,KACTF,YAAa,MAEbkB,GACAO,QAASA,EACTN,MAAO,UACPO,UAAW,GAAIvB,MACf/F,QAASA,EACT8D,IAAKA,EAeT,OAZAG,KAEAuB,IAEAb,IAEAf,EAAQkD,GAEJ9G,EAAQqC,OAASkF,SACjBA,QAAQC,IAAIV,GAGTjG,GA2MX,QAAShB,KACL,MAAOT,GAAEgI,UAAWlF,IAAeuF,EAAOzH,SAG9C,QAASkB,GAAYL,GACZX,IAAcA,EAAaH,KAC5Bc,EAAc6G,GAAG,cAGrB7G,EAAcI,SACdJ,EAAgB,KACqB,IAAjCX,EAAWiB,WAAWf,SACtBF,EAAWe,SACXyF,EAAgBhE,SA/bxB,GAAIxC,GACAO,EAsBAiG,EArBAW,EAAU,EACV1H,GACAN,MAAO,QACPiB,KAAM,OACNI,QAAS,UACTC,QAAS,WAGT8G,GACA7G,MAAOA,EACPK,OAAQA,EACR5B,MAAOA,EACPU,aAAcA,EACdO,KAAMA,EACNN,WACAO,UAAWA,EACXG,QAASA,EACTiH,QAAS,QACThH,QAASA,EAKb,OAAO8G,SA4aC,kBAAXtI,SAAyBA,OAAOyI,IAAMzI,OAAS,SAAU0I,EAAMC,GAC9C,mBAAXC,SAA0BA,OAAOC,QACxCD,OAAOC,QAAUF,EAAQG,QAAQ,WAEjCC,OAAOT,OAASK,EAAQI,OAAOC","file":"toastr.js","sourcesContent":["/*\n * Toastr\n * Copyright 2012-2015\n * Authors: John Papa, Hans Fjällemark, and Tim Ferrell.\n * All Rights Reserved.\n * Use, reproduction, distribution, and modification of this code is subject to the terms and\n * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php\n *\n * ARIA Support: Greta Krafsig\n *\n * Project: https://github.com/CodeSeven/toastr\n */\n/* global define */\n(function (define) {\n define(['jquery'], function ($) {\n return (function () {\n var $container;\n var listener;\n var toastId = 0;\n var toastType = {\n error: 'error',\n info: 'info',\n success: 'success',\n warning: 'warning'\n };\n\n var toastr = {\n clear: clear,\n remove: remove,\n error: error,\n getContainer: getContainer,\n info: info,\n options: {},\n subscribe: subscribe,\n success: success,\n version: '2.1.4',\n warning: warning\n };\n\n var previousToast;\n\n return toastr;\n\n ////////////////\n\n function error(message, title, optionsOverride) {\n return notify({\n type: toastType.error,\n iconClass: getOptions().iconClasses.error,\n message: message,\n optionsOverride: optionsOverride,\n title: title\n });\n }\n\n function getContainer(options, create) {\n if (!options) { options = getOptions(); }\n $container = $('#' + options.containerId);\n if ($container.length) {\n return $container;\n }\n if (create) {\n $container = createContainer(options);\n }\n return $container;\n }\n\n function info(message, title, optionsOverride) {\n return notify({\n type: toastType.info,\n iconClass: getOptions().iconClasses.info,\n message: message,\n optionsOverride: optionsOverride,\n title: title\n });\n }\n\n function subscribe(callback) {\n listener = callback;\n }\n\n function success(message, title, optionsOverride) {\n return notify({\n type: toastType.success,\n iconClass: getOptions().iconClasses.success,\n message: message,\n optionsOverride: optionsOverride,\n title: title\n });\n }\n\n function warning(message, title, optionsOverride) {\n return notify({\n type: toastType.warning,\n iconClass: getOptions().iconClasses.warning,\n message: message,\n optionsOverride: optionsOverride,\n title: title\n });\n }\n\n function clear($toastElement, clearOptions) {\n var options = getOptions();\n if (!$container) { getContainer(options); }\n if (!clearToast($toastElement, options, clearOptions)) {\n clearContainer(options);\n }\n }\n\n function remove($toastElement) {\n var options = getOptions();\n if (!$container) { getContainer(options); }\n if ($toastElement && $(':focus', $toastElement).length === 0) {\n removeToast($toastElement);\n return;\n }\n if ($container.children().length) {\n $container.remove();\n }\n }\n\n // internal functions\n\n function clearContainer (options) {\n var toastsToClear = $container.children();\n for (var i = toastsToClear.length - 1; i >= 0; i--) {\n clearToast($(toastsToClear[i]), options);\n }\n }\n\n function clearToast ($toastElement, options, clearOptions) {\n var force = clearOptions && clearOptions.force ? clearOptions.force : false;\n if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {\n $toastElement[options.hideMethod]({\n duration: options.hideDuration,\n easing: options.hideEasing,\n complete: function () { removeToast($toastElement); }\n });\n return true;\n }\n return false;\n }\n\n function createContainer(options) {\n $container = $('
    ')\n .attr('id', options.containerId)\n .addClass(options.positionClass);\n\n $container.appendTo($(options.target));\n return $container;\n }\n\n function getDefaults() {\n return {\n tapToDismiss: true,\n toastClass: 'toast',\n containerId: 'toast-container',\n debug: false,\n\n showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery\n showDuration: 300,\n showEasing: 'swing', //swing and linear are built into jQuery\n onShown: undefined,\n hideMethod: 'fadeOut',\n hideDuration: 1000,\n hideEasing: 'swing',\n onHidden: undefined,\n closeMethod: false,\n closeDuration: false,\n closeEasing: false,\n closeOnHover: true,\n\n extendedTimeOut: 1000,\n iconClasses: {\n error: 'toast-error',\n info: 'toast-info',\n success: 'toast-success',\n warning: 'toast-warning'\n },\n iconClass: 'toast-info',\n positionClass: 'toast-top-right',\n timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky\n titleClass: 'toast-title',\n messageClass: 'toast-message',\n escapeHtml: false,\n target: 'body',\n closeHtml: '',\n closeClass: 'toast-close-button',\n newestOnTop: true,\n preventDuplicates: false,\n progressBar: false,\n progressClass: 'toast-progress',\n rtl: false\n };\n }\n\n function publish(args) {\n if (!listener) { return; }\n listener(args);\n }\n\n function notify(map) {\n var options = getOptions();\n var iconClass = map.iconClass || options.iconClass;\n\n if (typeof (map.optionsOverride) !== 'undefined') {\n options = $.extend(options, map.optionsOverride);\n iconClass = map.optionsOverride.iconClass || iconClass;\n }\n\n if (shouldExit(options, map)) { return; }\n\n toastId++;\n\n $container = getContainer(options, true);\n\n var intervalId = null;\n var $toastElement = $('
    ');\n var $titleElement = $('
    ');\n var $messageElement = $('
    ');\n var $progressElement = $('
    ');\n var $closeElement = $(options.closeHtml);\n var progressBar = {\n intervalId: null,\n hideEta: null,\n maxHideTime: null\n };\n var response = {\n toastId: toastId,\n state: 'visible',\n startTime: new Date(),\n options: options,\n map: map\n };\n\n personalizeToast();\n\n displayToast();\n\n handleEvents();\n\n publish(response);\n\n if (options.debug && console) {\n console.log(response);\n }\n\n return $toastElement;\n\n function escapeHtml(source) {\n if (source == null) {\n source = '';\n }\n\n return source\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n }\n\n function personalizeToast() {\n setIcon();\n setTitle();\n setMessage();\n setCloseButton();\n setProgressBar();\n setRTL();\n setSequence();\n setAria();\n }\n\n function setAria() {\n var ariaValue = '';\n switch (map.iconClass) {\n case 'toast-success':\n case 'toast-info':\n ariaValue = 'polite';\n break;\n default:\n ariaValue = 'assertive';\n }\n $toastElement.attr('aria-live', ariaValue);\n }\n\n function handleEvents() {\n if (options.closeOnHover) {\n $toastElement.hover(stickAround, delayedHideToast);\n }\n\n if (!options.onclick && options.tapToDismiss) {\n $toastElement.click(hideToast);\n }\n\n if (options.closeButton && $closeElement) {\n $closeElement.click(function (event) {\n if (event.stopPropagation) {\n event.stopPropagation();\n } else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {\n event.cancelBubble = true;\n }\n\n if (options.onCloseClick) {\n options.onCloseClick(event);\n }\n\n hideToast(true);\n });\n }\n\n if (options.onclick) {\n $toastElement.click(function (event) {\n options.onclick(event);\n hideToast();\n });\n }\n }\n\n function displayToast() {\n $toastElement.hide();\n\n $toastElement[options.showMethod](\n {duration: options.showDuration, easing: options.showEasing, complete: options.onShown}\n );\n\n if (options.timeOut > 0) {\n intervalId = setTimeout(hideToast, options.timeOut);\n progressBar.maxHideTime = parseFloat(options.timeOut);\n progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;\n if (options.progressBar) {\n progressBar.intervalId = setInterval(updateProgress, 10);\n }\n }\n }\n\n function setIcon() {\n if (map.iconClass) {\n $toastElement.addClass(options.toastClass).addClass(iconClass);\n }\n }\n\n function setSequence() {\n if (options.newestOnTop) {\n $container.prepend($toastElement);\n } else {\n $container.append($toastElement);\n }\n }\n\n function setTitle() {\n if (map.title) {\n var suffix = map.title;\n if (options.escapeHtml) {\n suffix = escapeHtml(map.title);\n }\n $titleElement.append(suffix).addClass(options.titleClass);\n $toastElement.append($titleElement);\n }\n }\n\n function setMessage() {\n if (map.message) {\n var suffix = map.message;\n if (options.escapeHtml) {\n suffix = escapeHtml(map.message);\n }\n $messageElement.append(suffix).addClass(options.messageClass);\n $toastElement.append($messageElement);\n }\n }\n\n function setCloseButton() {\n if (options.closeButton) {\n $closeElement.addClass(options.closeClass).attr('role', 'button');\n $toastElement.prepend($closeElement);\n }\n }\n\n function setProgressBar() {\n if (options.progressBar) {\n $progressElement.addClass(options.progressClass);\n $toastElement.prepend($progressElement);\n }\n }\n\n function setRTL() {\n if (options.rtl) {\n $toastElement.addClass('rtl');\n }\n }\n\n function shouldExit(options, map) {\n if (options.preventDuplicates) {\n if (map.message === previousToast) {\n return true;\n } else {\n previousToast = map.message;\n }\n }\n return false;\n }\n\n function hideToast(override) {\n var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod;\n var duration = override && options.closeDuration !== false ?\n options.closeDuration : options.hideDuration;\n var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing;\n if ($(':focus', $toastElement).length && !override) {\n return;\n }\n clearTimeout(progressBar.intervalId);\n return $toastElement[method]({\n duration: duration,\n easing: easing,\n complete: function () {\n removeToast($toastElement);\n clearTimeout(intervalId);\n if (options.onHidden && response.state !== 'hidden') {\n options.onHidden();\n }\n response.state = 'hidden';\n response.endTime = new Date();\n publish(response);\n }\n });\n }\n\n function delayedHideToast() {\n if (options.timeOut > 0 || options.extendedTimeOut > 0) {\n intervalId = setTimeout(hideToast, options.extendedTimeOut);\n progressBar.maxHideTime = parseFloat(options.extendedTimeOut);\n progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;\n }\n }\n\n function stickAround() {\n clearTimeout(intervalId);\n progressBar.hideEta = 0;\n $toastElement.stop(true, true)[options.showMethod](\n {duration: options.showDuration, easing: options.showEasing}\n );\n }\n\n function updateProgress() {\n var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;\n $progressElement.width(percentage + '%');\n }\n }\n\n function getOptions() {\n return $.extend({}, getDefaults(), toastr.options);\n }\n\n function removeToast($toastElement) {\n if (!$container) { $container = getContainer(); }\n if ($toastElement.is(':visible')) {\n return;\n }\n $toastElement.remove();\n $toastElement = null;\n if ($container.children().length === 0) {\n $container.remove();\n previousToast = undefined;\n }\n }\n\n })();\n });\n}(typeof define === 'function' && define.amd ? define : function (deps, factory) {\n if (typeof module !== 'undefined' && module.exports) { //Node\n module.exports = factory(require('jquery'));\n } else {\n window.toastr = factory(window.jQuery);\n }\n}));\n"]} \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.css b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.css new file mode 100644 index 0000000000..064afd0718 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.css @@ -0,0 +1 @@ +.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#FFF}.toast-message a:hover{color:#CCC;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#FFF;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);line-height:1}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}.rtl .toast-close-button{left:-.3em;float:left;right:.3em}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999;pointer-events:none}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}} \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.js new file mode 100644 index 0000000000..06e4814ff8 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/toastr/toastr.min.js @@ -0,0 +1,2 @@ +!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("
    ").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e("
    "),M=e("
    "),B=e("
    "),q=e("
    "),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.4",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)}); +//# sourceMappingURL=toastr.js.map diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-code-snippet/tui-code-snippet.min.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-code-snippet/tui-code-snippet.min.js new file mode 100644 index 0000000000..4fad66dbed --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-code-snippet/tui-code-snippet.min.js @@ -0,0 +1,7 @@ +/*! + * tui-code-snippet.min.js + * @version 1.5.0 + * @author NHNEnt FE Development Lab + * @license MIT + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.util=e():(t.tui=t.tui||{},t.tui.util=e())}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="dist",e(0)}([function(t,e,n){"use strict";var r={},o=n(1),i=o.extend;i(r,o),i(r,n(3)),i(r,n(2)),i(r,n(4)),i(r,n(5)),i(r,n(6)),i(r,n(7)),i(r,n(8)),i(r,n(9)),r.browser=n(10),r.popup=n(11),r.formatDate=n(12),r.defineClass=n(13),r.defineModule=n(14),r.defineNamespace=n(15),r.CustomEvents=n(16),r.Enum=n(17),r.ExMap=n(18),r.HashMap=n(20),r.Map=n(19),t.exports=r},function(t,e,n){"use strict";function r(t,e){var n,r,o,i,u=Object.prototype.hasOwnProperty;for(o=1,i=arguments.length;o-1||h.inArray(e,o)>-1)return!1;for(n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;if(typeof e[n]!=typeof t[n])return!1}for(n in t){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;if(typeof e[n]!=typeof t[n])return!1;if("object"==typeof t[n]||"function"==typeof t[n]){if(r.push(t),o.push(e),!c(t[n],e[n]))return!1;r.pop(),o.pop()}else if(t[n]!==e[n])return!1}return!0}function p(t,e){for(var n=arguments,r=n[0],o=1,i=n.length;o=0&&r","'":"'"," ":" "};return t.replace(/&|<|>|"|'| /g,function(t){return e[t]?e[t]:t})}function o(t){var e={'"':"quot","&":"amp","<":"lt",">":"gt","'":"#39"};return t.replace(/[<>&"']/g,function(t){return e[t]?"&"+e[t]+";":t})}function i(t){return/[<>&"']/.test(t)}function u(t,e){for(var n,r,o=0,i=t.length,u={};o1}),u=a.keys(u).sort(),n=u.join("")}var s=n(4),a=n(1);t.exports={decodeHTMLEntity:r,encodeHTMLEntity:o,hasEncodableString:i,getDuplicatedChar:u}},function(t,e){"use strict";function n(t,e){function n(){o=u.call(arguments),window.clearTimeout(r),r=window.setTimeout(function(){t.apply(null,o)},e)}var r,o;return e=e||0,n}function r(){return Number(new Date)}function o(t,e){function n(){return c=u.call(arguments),p?(f(c),void(p=!1)):(a=i.timestamp(),o=o||a,s(c),void(a-o>=e&&f(c)))}function r(){p=!0,o=null}var o,s,a,c,p=!0,f=function(e){t.apply(null,e),o=null};return e=e||0,s=i.debounce(f,e),n.reset=r,n}var i={},u=Array.prototype.slice;i.timestamp=r,i.debounce=n,i.throttle=o,t.exports=i},function(t,e,n){"use strict";function r(t){var e=(new Date).getTime();return e-t>c}function o(t,e){var n="https://www.google-analytics.com/collect",o=location.hostname,u="event",s="use",c="TOAST UI "+t+" for "+o+": Statistics",p=window.localStorage.getItem(c);(a.isUndefined(window.tui)||window.tui.usageStatistics!==!1)&&(p&&!r(p)||(window.localStorage.setItem(c,(new Date).getTime()),setTimeout(function(){"interactive"!==document.readyState&&"complete"!==document.readyState||i(n,{v:1,t:u,tid:e,cid:o,dp:o,dh:t,el:t,ec:s})},1e3)))}function i(t,e){var n=s.map(u.keys(e),function(t,n){var r=0===n?"":"&";return r+t+"="+e[t]}).join(""),r=document.createElement("img");return r.src=t+"?"+n,r.style.display="none",document.body.appendChild(r),document.body.removeChild(r),r}var u=n(1),s=n(4),a=n(2),c=6048e5;t.exports={imagePing:i,sendHostname:o}},function(t,e){"use strict";var n,r,o={chrome:!1,firefox:!1,safari:!1,msie:!1,edge:!1,others:!1,version:0},i=window.navigator,u=i.appName.replace(/\s/g,"_"),s=i.userAgent,a=/MSIE\s([0-9]+[.0-9]*)/,c=/Trident.*rv:11\./,p=/Edge\/(\d+)\./,f={firefox:/Firefox\/(\d+)\./,chrome:/Chrome\/(\d+)\./,safari:/Version\/([\d.]+).*Safari\/(\d+)/},h={Microsoft_Internet_Explorer:function(){var t=s.match(a);t?(o.msie=!0,o.version=parseFloat(t[1])):o.others=!0},Netscape:function(){var t=!1;if(c.exec(s))o.msie=!0,o.version=11,t=!0;else if(p.exec(s))o.edge=!0,o.version=s.match(p)[1],t=!0;else for(n in f)if(f.hasOwnProperty(n)&&(r=s.match(f[n]),r&&r.length>1)){o[n]=t=!0,o.version=parseFloat(r[1]||0);break}t||(o.others=!0)}},l=h[u];l&&h[u](),t.exports=o},function(t,e,n){"use strict";function r(){this.openedPopup={},this.closeWithParentPopup={},this.postBridgeUrl=""}var o=n(4),i=n(2),u=n(5),s=n(10),a=n(1),c=0;r.prototype.getPopupList=function(t){var e;return e=i.isExisty(t)?this.openedPopup[t]:this.openedPopup},r.prototype.openPopup=function(t,e){var n,r,o;if(e=a.extend({popupName:"popup_"+c+"_"+Number(new Date),popupOptionStr:"",useReload:!0,closeWithParent:!0,method:"get",param:{}},e||{}),e.method=e.method.toUpperCase(),this.postBridgeUrl=e.postBridgeUrl||this.postBridgeUrl,o="POST"===e.method&&e.param&&s.msie&&11===s.version,!i.isExisty(t))throw new Error("Popup#open() need popup url.");c+=1,e.param&&("GET"===e.method?t=t+(/\?/.test(t)?"&":"?")+this._parameterize(e.param):"POST"===e.method&&(o||(r=this.createForm(t,e.param,e.method,e.popupName),t="about:blank"))),n=this.openedPopup[e.popupName],i.isExisty(n)?n.closed?this.openedPopup[e.popupName]=n=this._open(o,e.param,t,e.popupName,e.popupOptionStr):(e.useReload&&n.location.replace(t),n.focus()):this.openedPopup[e.popupName]=n=this._open(o,e.param,t,e.popupName,e.popupOptionStr),this.closeWithParentPopup[e.popupName]=e.closeWithParent,(!n||n.closed||i.isUndefined(n.closed))&&alert("please enable popup windows for this website"),e.param&&"POST"===e.method&&!o&&(n&&r.submit(),r.parentNode&&r.parentNode.removeChild(r)),window.onunload=u.bind(this.closeAllPopup,this)},r.prototype.close=function(t,e){var n=e||window;t=!!i.isExisty(t)&&t,t&&(window.onunload=null),n.closed||(n.opener=window.location.href,n.close())},r.prototype.closeAllPopup=function(t){var e=i.isExisty(t);o.forEachOwnProperties(this.openedPopup,function(t,n){(e&&this.closeWithParentPopup[n]||!e)&&this.close(!1,t)},this)},r.prototype.focus=function(t){this.getPopupList(t).focus()},r.prototype.parseQuery=function(){var t,e,n={};return t=window.location.search.substr(1),o.forEachArray(t.split("&"),function(t){e=t.split("="),n[decodeURIComponent(e[0])]=decodeURIComponent(e[1])}),n},r.prototype.createForm=function(t,e,n,r,i){var u,s=document.createElement("form");return i=i||document.body,s.method=n||"POST",s.action=t||"",s.target=r||"",s.style.display="none",o.forEachOwnProperties(e,function(t,e){u=document.createElement("input"),u.name=e,u.type="hidden",u.value=t,s.appendChild(u)}),i.appendChild(s),s},r.prototype._parameterize=function(t){var e=[];return o.forEachOwnProperties(t,function(t,n){e.push(encodeURIComponent(n)+"="+encodeURIComponent(t))}),e.join("&")},r.prototype._open=function(t,e,n,r,o){var i;return t?(i=window.open(this.postBridgeUrl,r,o),setTimeout(function(){i.redirect(n,e)},100)):i=window.open(n,r,o),i},t.exports=new r},function(t,e,n){"use strict";function r(t,e,n){var r,o,i,u;return t=Number(t),e=Number(e),n=Number(n),r=t>-1&&t<100||t>1969&&t<2070,o=e>0&&e<13,!(!r||!o)&&(u=c[e],2===e&&t%4===0&&(t%100===0&&t%400!==0||(u=29)),i=n>0&&n<=u)}function o(t,e,n){var o,a,c,f=u.pick(n,"meridiemSet","AM")||"AM",h=u.pick(n,"meridiemSet","PM")||"PM";return a=i.isDate(e)?{year:e.getFullYear(),month:e.getMonth()+1,date:e.getDate(),hour:e.getHours(),minute:e.getMinutes()}:{year:e.year,month:e.month,date:e.date,hour:e.hour,minute:e.minute},!!r(a.year,a.month,a.date)&&(a.meridiem="",/([^\\]|^)[aA]\b/.test(t)&&(o=a.hour>11?h:f,a.hour>12&&(a.hour%=12),0===a.hour&&(a.hour=12),a.meridiem=o),c=t.replace(s,function(t){return t.indexOf("\\")>-1?t.replace(/\\/,""):p[t](a)||""}))}var i=n(2),u=n(1),s=/[\\]*YYYY|[\\]*YY|[\\]*MMMM|[\\]*MMM|[\\]*MM|[\\]*M|[\\]*DD|[\\]*D|[\\]*HH|[\\]*H|[\\]*A/gi,a=["Invalid month","January","February","March","April","May","June","July","August","September","October","November","December"],c=[0,31,28,31,30,31,30,31,31,30,31,30,31],p={M:function(t){return Number(t.month)},MM:function(t){var e=t.month;return Number(e)<10?"0"+e:e},MMM:function(t){return a[Number(t.month)].substr(0,3)},MMMM:function(t){return a[Number(t.month)]},D:function(t){return Number(t.date)},d:function(t){return p.D(t)},DD:function(t){var e=t.date;return Number(e)<10?"0"+e:e},dd:function(t){return p.DD(t)},YY:function(t){return Number(t.year)%100},yy:function(t){return p.YY(t)},YYYY:function(t){var e="20",n=t.year;return n>69&&n<100&&(e="19"),Number(n)<100?e+String(n):n},yyyy:function(t){return p.YYYY(t)},A:function(t){return t.meridiem},a:function(t){return t.meridiem},hh:function(t){var e=t.hour;return Number(e)<10?"0"+e:e},HH:function(t){return p.hh(t)},h:function(t){return String(Number(t.hour))},H:function(t){return p.h(t)},m:function(t){return String(Number(t.minute))},mm:function(t){var e=t.minute;return Number(e)<10?"0"+e:e}};t.exports=o},function(t,e,n){"use strict";function r(t,e){var n;return e||(e=t,t=null),n=e.init||function(){},t&&o(n,t),e.hasOwnProperty("static")&&(i(n,e["static"]),delete e["static"]),i(n.prototype,e),n}var o=n(6).inherit,i=n(1).extend;t.exports=r},function(t,e,n){"use strict";function r(t,e){var n=e||{};return i.isFunction(n[u])&&n[u](),o(t,n)}var o=n(15),i=n(2),u="initialize";t.exports=r},function(t,e,n){"use strict";function r(t,e,n){var r,u,s,a;return r=t.split("."),r.unshift(window),u=o.reduce(r,function(t,e){return t[e]=t[e]||{},t[e]}),n?(a=r.pop(),s=i.pick.apply(null,r),u=s[a]=e):i.extend(u,e),u}var o=n(4),i=n(1);t.exports=r},function(t,e,n){"use strict";function r(){this.events=null,this.contexts=null}var o=n(4),i=n(2),u=n(1),s=/\s+/g;r.mixin=function(t){u.extend(t.prototype,r.prototype)},r.prototype._getHandlerItem=function(t,e){var n={handler:t};return e&&(n.context=e),n},r.prototype._safeEvent=function(t){var e,n=this.events;return n||(n=this.events={}),t&&(e=n[t],e||(e=[],n[t]=e),n=e),n},r.prototype._safeContext=function(){var t=this.contexts;return t||(t=this.contexts=[]),t},r.prototype._indexOfContext=function(t){for(var e=this._safeContext(),n=0;e[n];){if(t===e[n][0])return n;n+=1}return-1},r.prototype._memorizeContext=function(t){var e,n;i.isExisty(t)&&(e=this._safeContext(),n=this._indexOfContext(t),n>-1?e[n][1]+=1:e.push([t,1]))},r.prototype._forgetContext=function(t){var e,n;i.isExisty(t)&&(e=this._safeContext(),n=this._indexOfContext(t),n>-1&&(e[n][1]-=1,e[n][1]<=0&&e.splice(n,1)))},r.prototype._bindEvent=function(t,e,n){var r=this._safeEvent(t);this._memorizeContext(n),r.push(this._getHandlerItem(e,n))},r.prototype.on=function(t,e,n){var r=this;i.isString(t)?(t=t.split(s),o.forEach(t,function(t){r._bindEvent(t,e,n)})):i.isObject(t)&&(n=e,o.forEach(t,function(t,e){r.on(e,t,n)}))},r.prototype.once=function(t,e,n){function r(){e.apply(n,arguments),u.off(t,r,n)}var u=this;return i.isObject(t)?(n=e,void o.forEach(t,function(t,e){u.once(e,t,n)})):void this.on(t,r,n)},r.prototype._spliceMatches=function(t,e){var n,r=0;if(i.isArray(t))for(n=t.length;r0},r.prototype.getListenerLength=function(t){var e=this._safeEvent(t);return e.length},t.exports=r},function(t,e,n){"use strict";function r(t){t&&this.set.apply(this,arguments)}var o=n(4),i=n(2),u=function(){try{return Object.defineProperty({},"x",{}),!0}catch(t){return!1}}(),s=0;r.prototype.set=function(t){var e=this;i.isArray(t)||(t=o.toArray(arguments)),o.forEach(t,function(t){e._addItem(t)})},r.prototype.getName=function(t){var e,n=this;return o.forEach(this,function(r,o){if(n._isEnumItem(o)&&t===r)return e=o,!1}),e},r.prototype._addItem=function(t){var e;this.hasOwnProperty(t)||(e=this._makeEnumValue(),u?Object.defineProperty(this,t,{enumerable:!0,configurable:!1,writable:!1,value:e}):this[t]=e)},r.prototype._makeEnumValue=function(){var t;return t=s,s+=1,t},r.prototype._isEnumItem=function(t){return i.isNumber(this[t])},t.exports=r},function(t,e,n){"use strict";function r(t){this._map=new i(t),this.size=this._map.size}var o=n(4),i=n(19),u=["get","has","forEach","keys","values","entries"],s=["delete","clear"];o.forEachArray(u,function(t){r.prototype[t]=function(){return this._map[t].apply(this._map,arguments)}}),o.forEachArray(s,function(t){r.prototype[t]=function(){var e=this._map[t].apply(this._map,arguments);return this.size=this._map.size,e}}),r.prototype.set=function(){return this._map.set.apply(this._map,arguments),this.size=this._map.size,this},r.prototype.setObject=function(t){o.forEachOwnProperties(t,function(t,e){this.set(e,t)},this)},r.prototype.deleteByKeys=function(t){o.forEachArray(t,function(t){this["delete"](t)},this)},r.prototype.merge=function(t){t.forEach(function(t,e){this.set(e,t)},this)},r.prototype.filter=function(t){var e=new r;return this.forEach(function(n,r){t(n,r)&&e.set(r,n)}),e},t.exports=r},function(t,e,n){"use strict";function r(t,e){this._keys=t,this._valueGetter=e,this._length=this._keys.length,this._index=-1,this._done=!1}function o(t){this._valuesForString={},this._valuesForIndex={},this._keys=[],t&&this._setInitData(t),this.size=0}var i=n(4),u=n(2),s=n(3),a=n(10),c=n(5),p={},f={};r.prototype.next=function(){var t={};do this._index+=1;while(u.isUndefined(this._keys[this._index])&&this._index=this._length?t.done=!0:(t.done=!1,t.value=this._valueGetter(this._keys[this._index],this._index)),t},o.prototype._setInitData=function(t){if(!u.isArray(t))throw new Error("Only Array is supported.");i.forEachArray(t,function(t){this.set(t[0],t[1])},this)},o.prototype._isNaN=function(t){return"number"==typeof t&&t!==t},o.prototype._getKeyIndex=function(t){var e,n=-1;return u.isString(t)?(e=this._valuesForString[t],e&&(n=e.keyIndex)):n=s.inArray(t,this._keys),n},o.prototype._getOriginKey=function(t){var e=t;return t===p?e=void 0:t===f&&(e=NaN),e},o.prototype._getUniqueKey=function(t){var e=t;return u.isUndefined(t)?e=p:this._isNaN(t)&&(e=f),e},o.prototype._getValueObject=function(t,e){return u.isString(t)?this._valuesForString[t]:(u.isUndefined(e)&&(e=this._getKeyIndex(t)),e>=0?this._valuesForIndex[e]:void 0)},o.prototype._getOriginValue=function(t,e){return this._getValueObject(t,e).origin},o.prototype._getKeyValuePair=function(t,e){return[this._getOriginKey(t),this._getOriginValue(t,e)]},o.prototype._createValueObject=function(t,e){return{keyIndex:e,origin:t}},o.prototype.set=function(t,e){var n,r=this._getUniqueKey(t),o=this._getKeyIndex(r);return o<0&&(o=this._keys.push(r)-1,this.size+=1),n=this._createValueObject(e,o),u.isString(t)?this._valuesForString[t]=n:this._valuesForIndex[o]=n,this},o.prototype.get=function(t){var e=this._getUniqueKey(t),n=this._getValueObject(e);return n&&n.origin},o.prototype.keys=function(){return new r(this._keys,c.bind(this._getOriginKey,this))},o.prototype.values=function(){return new r(this._keys,c.bind(this._getOriginValue,this))},o.prototype.entries=function(){return new r(this._keys,c.bind(this._getKeyValuePair,this))},o.prototype.has=function(t){return!!this._getValueObject(t)},o.prototype["delete"]=function(t){var e;u.isString(t)?this._valuesForString[t]&&(e=this._valuesForString[t].keyIndex,delete this._valuesForString[t]):(e=this._getKeyIndex(t),e>=0&&delete this._valuesForIndex[e]),e>=0&&(delete this._keys[e],this.size-=1)},o.prototype.forEach=function(t,e){e=e||this,i.forEachArray(this._keys,function(n){u.isUndefined(n)||t.call(e,this._getValueObject(n).origin,n,this)},this)},o.prototype.clear=function(){o.call(this)},function(){window.Map&&(a.firefox&&a.version>=37||a.chrome&&a.version>=42)&&(o=window.Map)}(),t.exports=o},function(t,e,n){"use strict";function r(t){this.length=0,t&&this.setObject(t)}var o=n(4),i=n(2),u="å";r.prototype.set=function(t,e){2===arguments.length?this.setKeyValue(t,e):this.setObject(t)},r.prototype.setKeyValue=function(t,e){this.has(t)||(this.length+=1),this[this.encodeKey(t)]=e},r.prototype.setObject=function(t){var e=this;o.forEachOwnProperties(t,function(t,n){e.setKeyValue(n,t)})},r.prototype.merge=function(t){var e=this;t.each(function(t,n){e.setKeyValue(n,t)})},r.prototype.encodeKey=function(t){return u+t},r.prototype.decodeKey=function(t){var e=t.split(u);return e[e.length-1]},r.prototype.get=function(t){return this[this.encodeKey(t)]},r.prototype.has=function(t){return this.hasOwnProperty(this.encodeKey(t))},r.prototype.remove=function(t){return arguments.length>1&&(t=o.toArray(arguments)),i.isArray(t)?this.removeByKeyArray(t):this.removeByKey(t)},r.prototype.removeByKey=function(t){var e=this.has(t)?this.get(t):null;return null!==e&&(delete this[this.encodeKey(t)],this.length-=1),e},r.prototype.removeByKeyArray=function(t){var e=[],n=this;return o.forEach(t,function(t){e.push(n.removeByKey(t))}),e},r.prototype.removeAll=function(){var t=this;this.each(function(e,n){t.remove(n)})},r.prototype.each=function(t){var e,n=this;o.forEachOwnProperties(this,function(r,o){if(o.charAt(0)===u&&(e=t(r,n.decodeKey(o))),e===!1)return e})},r.prototype.keys=function(){var t=[],e=this;return this.each(function(n,r){t.push(e.decodeKey(r))}),t},r.prototype.find=function(t){var e=[];return this.each(function(n,r){t(n,r)&&e.push(n)}),e},r.prototype.toArray=function(){var t=[];return this.each(function(e){t.push(e)}),t},t.exports=r}])}); \ No newline at end of file diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-2x.png b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-2x.png new file mode 100644 index 0000000000..557607b4cb Binary files /dev/null and b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-2x.png differ diff --git a/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-Editor-all.js b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-Editor-all.js new file mode 100644 index 0000000000..601a4727e5 --- /dev/null +++ b/samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/tui-editor/tui-editor-Editor-all.js @@ -0,0 +1,40418 @@ +/*! + * tui-editor + * @version 1.3.0 + * @author NHN Ent. FE Development Lab (https://nhnent.github.io/tui.editor/) + * @license MIT + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("jquery"), require("tui-code-snippet"), require("codemirror"), require("to-mark"), require("tui-chart"), require("squire-rte"), require("markdown-it"), require("highlight.js"), require("tui-color-picker"), require("plantuml-encoder")); + else if(typeof define === 'function' && define.amd) + define(["jquery", "tui-code-snippet", "codemirror", "to-mark", "tui-chart", "squire-rte", "markdown-it", "highlight.js", "tui-color-picker", "plantuml-encoder"], factory); + else if(typeof exports === 'object') + exports["Editor"] = factory(require("jquery"), require("tui-code-snippet"), require("codemirror"), require("to-mark"), require("tui-chart"), require("squire-rte"), require("markdown-it"), require("highlight.js"), require("tui-color-picker"), require("plantuml-encoder")); + else + root["tui"] = root["tui"] || {}, root["tui"]["Editor"] = factory(root["$"], (root["tui"] && root["tui"]["util"]), root["CodeMirror"], root["toMark"], (root["tui"] && root["tui"]["chart"]), root["Squire"], root["markdownit"], root["hljs"], (root["tui"] && root["tui"]["colorPicker"]), root["plantumlEncoder"]); +})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_42__, __WEBPACK_EXTERNAL_MODULE_57__, __WEBPACK_EXTERNAL_MODULE_77__, __WEBPACK_EXTERNAL_MODULE_83__, __WEBPACK_EXTERNAL_MODULE_91__, __WEBPACK_EXTERNAL_MODULE_198__, __WEBPACK_EXTERNAL_MODULE_200__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "dist/"; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 55); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_1__; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements CommandManager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _command = __webpack_require__(82); + +var _command2 = _interopRequireDefault(_command); + +var _util = __webpack_require__(38); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var KEYMAP_OS_INDEX = _util.isMac ? 1 : 0; + +/** + * Class CommandManager + */ + +var CommandManager = function () { + /** + * @param {ToastUIEditor} base nedInstance + * @param {object} [options={}] - option object + * @param {boolean} [options.useCommandShortcut=true] - execute command with keyMap + */ + function CommandManager(base) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, CommandManager); + + this._command = new _tuiCodeSnippet2.default.Map(); + this._mdCommand = new _tuiCodeSnippet2.default.Map(); + this._wwCommand = new _tuiCodeSnippet2.default.Map(); + this._options = _jquery2.default.extend({ + 'useCommandShortcut': true + }, options); + + this.base = base; + + this.keyMapCommand = {}; + + this._initEvent(); + } + + /** + * You can change command before command addition by addCommandBefore event. + * @param {object} command - command + * @returns {object} + * @private + */ + + + _createClass(CommandManager, [{ + key: '_addCommandBefore', + value: function _addCommandBefore(command) { + var commandWrapper = { command: command }; + + this.base.eventManager.emit('addCommandBefore', commandWrapper); + + return commandWrapper.command || command; + } + + /** + * Add command + * @memberof CommandManager + * @param {Command} command Command instance + * @returns {Command} Command + */ + + }, { + key: 'addCommand', + value: function addCommand(command) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (args.length) { + command = CommandManager.command.apply(CommandManager, [command].concat(args)); + } + + command = this._addCommandBefore(command); + + var name = command.getName(); + + var commandBase = void 0; + + if (command.isMDType()) { + commandBase = this._mdCommand; + } else if (command.isWWType()) { + commandBase = this._wwCommand; + } else if (command.isGlobalType()) { + commandBase = this._command; + } + + commandBase.set(name, command); + + if (command.keyMap) { + this.keyMapCommand[command.keyMap[KEYMAP_OS_INDEX]] = name; + } + + return command; + } + + /** + * _initEvent + * Bind event handler to eventManager + * @private + * @memberof CommandManager + */ + + }, { + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this.base.eventManager.listen('command', function () { + _this.exec.apply(_this, arguments); + }); + + this.base.eventManager.listen('keyMap', function (ev) { + if (!_this._options.useCommandShortcut) { + return; + } + var command = _this.keyMapCommand[ev.keyMap]; + + if (command) { + ev.data.preventDefault(); + _this.exec(command); + } + }); + } + + /** + * Execute command + * @memberof CommandManager + * @param {String} name Command name + * @param {*} ...args Command argument + * @returns {*} + */ + + }, { + key: 'exec', + value: function exec(name) { + var commandToRun = void 0, + result = void 0; + var context = this.base; + + commandToRun = this._command.get(name); + + if (!commandToRun) { + if (this.base.isMarkdownMode()) { + commandToRun = this._mdCommand.get(name); + context = this.base.mdEditor; + } else { + commandToRun = this._wwCommand.get(name); + context = this.base.wwEditor; + } + } + + if (commandToRun) { + var _commandToRun; + + for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + args.unshift(context); + result = (_commandToRun = commandToRun).exec.apply(_commandToRun, args); + } + + return result; + } + }]); + + return CommandManager; +}(); + +/** + * Create command by given editor type and property object + * @memberof CommandManager + * @param {string} type Command type + * @param {{name: string, keyMap: Array}} props Property + * @returns {*} + */ + + +CommandManager.command = function (type, props) { + var command = _command2.default.factory(type, props.name, props.keyMap); + + _tuiCodeSnippet2.default.extend(command, props); + + return command; +}; + +exports.default = CommandManager; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.I18n = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements i18n + * @author NHN Ent. FE Development Lab + */ + + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var sharedInstance = void 0; + +var DEFAULT_CODE = 'en_US'; + +/** + * Class I18n + */ + +var I18n = function () { + /** + * Creates an instance of I18n. + * @memberof I18n + */ + function I18n() { + _classCallCheck(this, I18n); + + this._code = DEFAULT_CODE; + this._langs = new _tuiCodeSnippet2.default.Map(); + } + + /** + * Set locale code + * @param {string} code locale code + */ + + + _createClass(I18n, [{ + key: 'setCode', + value: function setCode(code) { + this._code = code; + } + + /** + * Set language set + * @param {string|string[]} codes locale code + * @param {object} data language set + */ + + }, { + key: 'setLanguage', + value: function setLanguage(codes, data) { + var _this = this; + + codes = [].concat(codes); + + codes.forEach(function (code) { + if (!_this._langs.has(code)) { + _this._langs.set(code, data); + } else { + var langData = _this._langs.get(code); + _this._langs.set(code, _tuiCodeSnippet2.default.extend(langData, data)); + } + }); + } + + /** + * Get text of key + * @param {string} key key of text + * @param {string} code locale code + * @returns {string} + */ + + }, { + key: 'get', + value: function get(key, code) { + if (!code) { + code = this._code; + } + + var langSet = this._langs.get(code); + + if (!langSet) { + langSet = this._langs.get(DEFAULT_CODE); + } + + var text = langSet[key]; + + if (!text) { + throw new Error('There is no text key "' + key + '" in ' + code); + } + + return text; + } + }], [{ + key: 'getSharedInstance', + value: function getSharedInstance() { + if (!sharedInstance) { + sharedInstance = new I18n(); + } + + return sharedInstance; + } + }]); + + return I18n; +}(); + +exports.I18n = I18n; +exports.default = new I18n(); + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview DOM Utils + * @author NHN Ent. FE Development Lab + */ +var FIND_ZWB = /\u200B/g; + +/** + * isTextNode + * Check if node is text node + * @param {Node} node node to check + * @returns {boolean} result + * @ignore + */ +var isTextNode = function isTextNode(node) { + return node && node.nodeType === Node.TEXT_NODE; +}; + +/** + * isElemNode + * Check if node is element node + * @param {Node} node node to check + * @returns {boolean} result + * @ignore + */ +var isElemNode = function isElemNode(node) { + return node && node.nodeType === Node.ELEMENT_NODE; +}; + +/** + * Check that the node is block node + * @param {Node} node node + * @returns {boolean} + * @ignore + */ +var isBlockNode = function isBlockNode(node) { + return (/^(ADDRESS|ARTICLE|ASIDE|BLOCKQUOTE|DETAILS|DIALOG|DD|DIV|DL|DT|FIELDSET|FIGCAPTION|FIGURE|FOOTER|FORM|H[\d]|HEADER|HGROUP|HR|LI|MAIN|NAV|OL|P|PRE|SECTION|UL)$/ig.test(this.getNodeName(node)) + ); +}; + +/** + * getNodeName + * Get node name of node + * @param {Node} node node + * @returns {string} node name + * @ignore + */ +var getNodeName = function getNodeName(node) { + if (isElemNode(node)) { + return node.tagName; + } + + return 'TEXT'; +}; + +/** + * getTextLength + * Get node offset length of node(for Range API) + * @param {Node} node node + * @returns {number} length + * @ignore + */ +var getTextLength = function getTextLength(node) { + var len = void 0; + + if (isElemNode(node)) { + len = node.textContent.replace(FIND_ZWB, '').length; + } else if (isTextNode(node)) { + len = node.nodeValue.replace(FIND_ZWB, '').length; + } + + return len; +}; + +/** + * getOffsetLength + * Get node offset length of node(for Range API) + * @param {Node} node node + * @returns {number} length + * @ignore + */ +var getOffsetLength = function getOffsetLength(node) { + var len = void 0; + + if (isElemNode(node)) { + len = node.childNodes.length; + } else if (isTextNode(node)) { + len = node.nodeValue.replace(FIND_ZWB, '').length; + } + + return len; +}; + +/** + * getNodeOffsetOfParent + * get node offset between parent's childnodes + * @param {Node} node node + * @returns {number} offset(index) + * @ignore + */ +var getNodeOffsetOfParent = function getNodeOffsetOfParent(node) { + var childNodesOfParent = node.parentNode.childNodes; + var i = void 0, + t = void 0, + found = void 0; + + for (i = 0, t = childNodesOfParent.length; i < t; i += 1) { + if (childNodesOfParent[i] === node) { + found = i; + break; + } + } + + return found; +}; + +/** + * getChildNodeByOffset + * get child node by offset + * @param {Node} node node + * @param {number} index offset index + * @returns {Node} foudned node + * @ignore + */ +var getChildNodeByOffset = function getChildNodeByOffset(node, index) { + var currentNode = void 0; + + if (isTextNode(node)) { + currentNode = node; + } else if (node.childNodes.length && index >= 0) { + currentNode = node.childNodes[index]; + } + + return currentNode; +}; + +/** + * getNodeWithDirectionUntil + * find next node from passed node + * @param {strong} direction previous or next + * @param {Node} node node + * @param {string} untilNodeName parent node name to limit + * @returns {Node} founded node + * @ignore + */ +var getNodeWithDirectionUntil = function getNodeWithDirectionUntil(direction, node, untilNodeName) { + var directionKey = direction + 'Sibling'; + var nodeName = void 0, + foundedNode = void 0; + + while (node && !node[directionKey]) { + nodeName = getNodeName(node.parentNode); + + if (nodeName === untilNodeName || nodeName === 'BODY') { + break; + } + + node = node.parentNode; + } + + if (node[directionKey]) { + foundedNode = node[directionKey]; + } + + return foundedNode; +}; + +/** + * getPrevOffsetNodeUntil + * get prev node of childnode pointed with index + * @param {Node} node node + * @param {number} index offset index + * @param {string} untilNodeName parent node name to limit + * @returns {Node} founded node + * @ignore + */ +var getPrevOffsetNodeUntil = function getPrevOffsetNodeUntil(node, index, untilNodeName) { + var prevNode = void 0; + + if (index > 0) { + prevNode = getChildNodeByOffset(node, index - 1); + } else { + prevNode = getNodeWithDirectionUntil('previous', node, untilNodeName); + } + + return prevNode; +}; + +var getParentUntilBy = function getParentUntilBy(node, matchCondition, stopCondition) { + var foundedNode = void 0; + + while (node.parentNode && !matchCondition(node.parentNode)) { + node = node.parentNode; + + if (stopCondition && stopCondition(node.parentNode)) { + break; + } + } + + if (matchCondition(node.parentNode)) { + foundedNode = node; + } + + return foundedNode; +}; + +/** + * getParentUntil + * get parent node until paseed node name + * @param {Node} node node + * @param {string|HTMLNode} untilNode node name or node to limit + * @returns {Node} founded node + * @ignore + */ +var getParentUntil = function getParentUntil(node, untilNode) { + var foundedNode = void 0; + + if (_tuiCodeSnippet2.default.isString(untilNode)) { + foundedNode = getParentUntilBy(node, function (targetNode) { + return untilNode === getNodeName(targetNode); + }); + } else { + foundedNode = getParentUntilBy(node, function (targetNode) { + return untilNode === targetNode; + }); + } + + return foundedNode; +}; + +/** + * getNodeWithDirectionUnderParent + * get node on the given direction under given parent + * @param {strong} direction previous or next + * @param {Node} node node + * @param {string|Node} underNode parent node name to limit + * @returns {Node} founded node + * @ignore + */ +var getNodeWithDirectionUnderParent = function getNodeWithDirectionUnderParent(direction, node, underNode) { + var directionKey = direction + 'Sibling'; + var foundedNode = void 0; + + node = getParentUntil(node, underNode); + + if (node && node[directionKey]) { + foundedNode = node[directionKey]; + } + + return foundedNode; +}; + +/** + * getTopPrevNodeUnder + * get top previous top level node under given node + * @param {Node} node node + * @param {Node} underNode underNode + * @returns {Node} founded node + * @ignore + */ +var getTopPrevNodeUnder = function getTopPrevNodeUnder(node, underNode) { + return getNodeWithDirectionUnderParent('previous', node, underNode); +}; + +/** + * getNextTopBlockNode + * get next top level block node + * @param {Node} node node + * @param {Node} underNode underNode + * @returns {Node} founded node + * @ignore + */ +var getTopNextNodeUnder = function getTopNextNodeUnder(node, underNode) { + return getNodeWithDirectionUnderParent('next', node, underNode); +}; + +/** + * Get parent element the body element + * @param {Node} node Node for start searching + * @returns {Node} + * @ignore + */ +var getTopBlockNode = function getTopBlockNode(node) { + return getParentUntil(node, 'BODY'); +}; + +/** + * Get previous text node + * @param {Node} node Node for start searching + * @returns {Node} + * @ignore + */ +var getPrevTextNode = function getPrevTextNode(node) { + node = node.previousSibling || node.parentNode; + + while (!isTextNode(node) && getNodeName(node) !== 'BODY') { + if (node.previousSibling) { + node = node.previousSibling; + + while (node.lastChild) { + node = node.lastChild; + } + } else { + node = node.parentNode; + } + } + + if (getNodeName(node) === 'BODY') { + node = null; + } + + return node; +}; + +/** + * test whether root contains the given node + * @param {HTMLNode} root - root node + * @param {HTMLNode} node - node to test + * @returns {Boolean} true if root contains node + */ +var containsNode = function containsNode(root, node) { + var walker = document.createTreeWalker(root, 4, null, false); + var found = root === node; + + while (!found && walker.nextNode()) { + found = walker.currentNode === node; + } + + return found; +}; + +/** + * find node by offset + * @param {HTMLElement} root Root element + * @param {Array.} offsetList offset list + * @param {function} textNodeFilter Text node filter + * @returns {Array} + * @ignore + */ +var findOffsetNode = function findOffsetNode(root, offsetList, textNodeFilter) { + var result = []; + var text = ''; + var walkerOffset = 0; + var newWalkerOffset = void 0; + + if (!offsetList.length) { + return result; + } + + var offset = offsetList.shift(); + var walker = document.createTreeWalker(root, 4, null, false); + + while (walker.nextNode()) { + text = walker.currentNode.nodeValue || ''; + + if (textNodeFilter) { + text = textNodeFilter(text); + } + + newWalkerOffset = walkerOffset + text.length; + + while (newWalkerOffset >= offset) { + result.push({ + container: walker.currentNode, + offsetInContainer: offset - walkerOffset, + offset: offset + }); + + if (!offsetList.length) { + return result; + } + offset = offsetList.shift(); + } + walkerOffset = newWalkerOffset; + } + + // there should be offset left + do { + result.push({ + container: walker.currentNode, + offsetInContainer: text.length, + offset: offset + }); + offset = offsetList.shift(); + } while (!_tuiCodeSnippet2.default.isUndefined(offset)); + + return result; +}; + +var getNodeInfo = function getNodeInfo(node) { + var path = {}; + + path.tagName = node.nodeName; + + if (node.id) { + path.id = node.id; + } + + var className = node.className.trim(); + + if (className) { + path.className = className; + } + + return path; +}; + +var getPath = function getPath(node, root) { + var paths = []; + + while (node && node !== root) { + if (isElemNode(node)) { + paths.unshift(getNodeInfo(node)); + } + + node = node.parentNode; + } + + return paths; +}; + +/** + * Find next, previous TD or TH element by given TE element + * @param {HTMLElement} node TD element + * @param {string} direction 'next' or 'previous' + * @returns {HTMLElement|null} + * @ignore + */ +var getTableCellByDirection = function getTableCellByDirection(node, direction) { + var isForward = true; + var targetElement = null; + + if (_tuiCodeSnippet2.default.isUndefined(direction) || direction !== 'next' && direction !== 'previous') { + return null; + } else if (direction === 'previous') { + isForward = false; + } + + if (isForward) { + targetElement = node.nextElementSibling; + } else { + targetElement = node.previousElementSibling; + } + + return targetElement; +}; + +/** + * Find sibling TR's TD element by given TD and direction + * @param {HTMLElement} node TD element + * @param {string} direction Boolean value for find first TD in next line + * @param {boolean} [needEdgeCell=false] Boolean value for find first TD in next line + * @returns {HTMLElement|null} + * @ignore + */ +var getSiblingRowCellByDirection = function getSiblingRowCellByDirection(node, direction, needEdgeCell) { + var isForward = true; + var tableCellElement = null; + var $node = void 0, + index = void 0, + $targetRowElement = void 0, + $currentContainer = void 0, + $siblingContainer = void 0, + isSiblingContainerExists = void 0; + + if (_tuiCodeSnippet2.default.isUndefined(direction) || direction !== 'next' && direction !== 'previous') { + return null; + } else if (direction === 'previous') { + isForward = false; + } + + if (node) { + $node = (0, _jquery2.default)(node); + + if (isForward) { + $targetRowElement = $node.parent().next(); + $currentContainer = $node.parents('thead'); + $siblingContainer = $currentContainer[0] && $currentContainer.next(); + isSiblingContainerExists = $siblingContainer && getNodeName($siblingContainer[0]) === 'TBODY'; + + index = 0; + } else { + $targetRowElement = $node.parent().prev(); + $currentContainer = $node.parents('tbody'); + $siblingContainer = $currentContainer[0] && $currentContainer.prev(); + isSiblingContainerExists = $siblingContainer && getNodeName($siblingContainer[0]) === 'THEAD'; + + index = node.parentNode.childNodes.length - 1; + } + + if (_tuiCodeSnippet2.default.isUndefined(needEdgeCell) || !needEdgeCell) { + index = getNodeOffsetOfParent(node); + } + + if ($targetRowElement[0]) { + tableCellElement = $targetRowElement.children('td,th')[index]; + } else if ($currentContainer[0] && isSiblingContainerExists) { + tableCellElement = $siblingContainer.find('td,th')[index]; + } + + return tableCellElement; + } + + return null; +}; + +exports.default = { + getNodeName: getNodeName, + isTextNode: isTextNode, + isElemNode: isElemNode, + isBlockNode: isBlockNode, + getTextLength: getTextLength, + getOffsetLength: getOffsetLength, + getPrevOffsetNodeUntil: getPrevOffsetNodeUntil, + getNodeOffsetOfParent: getNodeOffsetOfParent, + getChildNodeByOffset: getChildNodeByOffset, + containsNode: containsNode, + getTopPrevNodeUnder: getTopPrevNodeUnder, + getTopNextNodeUnder: getTopNextNodeUnder, + getParentUntilBy: getParentUntilBy, + getParentUntil: getParentUntil, + getTopBlockNode: getTopBlockNode, + getPrevTextNode: getPrevTextNode, + findOffsetNode: findOffsetNode, + getPath: getPath, + getNodeInfo: getNodeInfo, + getTableCellByDirection: getTableCellByDirection, + getSiblingRowCellByDirection: getSiblingRowCellByDirection +}; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** +* @fileoverview Editor/Viewer proxy for extensions +* @author NHN Ent. FE Development Lab +*/ +/* eslint global-require: 0 no-empty: 0 */ + +var Editor = void 0; +try { + Editor = __webpack_require__(28); +} catch (e) {} +if (!Editor) { + try { + Editor = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"../viewer\""); e.code = 'MODULE_NOT_FOUND'; throw e; }())); + } catch (e) {} +} + +exports.default = Editor; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createTableData = createTableData; +exports.createCellIndexData = createCellIndexData; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Parse cell like td or th. + * @param {HTMLElement} cell - cell element like td or th + * @param {number} rowIndex - row index + * @param {number} colIndex - column index + * @returns {{ + * nodeName: string, + * colspan: number, + * rowspan: number, + * content: string, + * align: ?string + * }} + * @private + */ +/** +* @fileoverview Implements tableDataHandler +* @author NHN Ent. FE Development Lab +*/ +function _parseCell(cell, rowIndex, colIndex) { + var $cell = (0, _jquery2.default)(cell); + var colspan = $cell.attr('colspan'); + var rowspan = $cell.attr('rowspan'); + var nodeName = cell.nodeName; + + + if (nodeName !== 'TH' && nodeName !== 'TD') { + return null; + } + + var cellData = { + nodeName: cell.nodeName, + colspan: colspan ? parseInt(colspan, 10) : 1, + rowspan: rowspan ? parseInt(rowspan, 10) : 1, + content: $cell.html(), + elementIndex: { + rowIndex: rowIndex, + colIndex: colIndex + } + }; + + if (cell.nodeName === 'TH' && cell.align) { + cellData.align = cell.align; + } + + return cellData; +} + +/** + * Add merged cell. + * @param {object} base - base table data + * @param {object} cellData - cell data + * @param {number} startRowIndex - start row index + * @param {number} startCellIndex - start cell index + * @private + */ +function _addMergedCell(base, cellData, startRowIndex, startCellIndex) { + var colspan = cellData.colspan, + rowspan = cellData.rowspan, + nodeName = cellData.nodeName; + + var colMerged = colspan > 1; + var rowMerged = rowspan > 1; + + if (!colMerged && !rowMerged) { + return; + } + + var limitRowIndex = startRowIndex + rowspan; + var limitCellIndex = startCellIndex + colspan; + + _tuiCodeSnippet2.default.range(startRowIndex, limitRowIndex).forEach(function (rowIndex) { + base[rowIndex] = base[rowIndex] || []; + + _tuiCodeSnippet2.default.range(startCellIndex, limitCellIndex).forEach(function (cellIndex) { + var mergedData = { + nodeName: nodeName + }; + + if (rowIndex === startRowIndex && cellIndex === startCellIndex) { + return; + } + + if (colMerged) { + mergedData.colMergeWith = startCellIndex; + } + + if (rowMerged) { + mergedData.rowMergeWith = startRowIndex; + } + + base[rowIndex][cellIndex] = mergedData; + }); + }); +} + +/** + * Create table data from jQuery table Element. + * @param {jQuery} $table - jQuery table element + * @returns {Array.>} + * @ignore + */ +function createTableData($table) { + var tableData = []; + + $table.find('tr').each(function (rowIndex, tr) { + var stackedColCount = 0; + + tableData[rowIndex] = tableData[rowIndex] || []; + + (0, _jquery2.default)(tr).children().each(function (colIndex, cell) { + var cellData = _parseCell(cell, rowIndex, colIndex); + + if (!cellData) { + return; + } + var dataColIndex = colIndex + stackedColCount; + + while (tableData[rowIndex][dataColIndex]) { + dataColIndex += 1; + stackedColCount += 1; + } + + tableData[rowIndex][dataColIndex] = cellData; + _addMergedCell(tableData, cellData, rowIndex, dataColIndex); + }); + }); + + if ($table[0].className) { + tableData.className = $table[0].className; + } + + return tableData; +} + +/** + * Create cell index data of table data. + * @param {Array.>} tableData - table data + * @returns {Array.>} + * @ignore + */ +function createCellIndexData(tableData) { + var mappingData = []; + + tableData.forEach(function (row, rowIndex) { + var mappingRow = []; + + row.forEach(function (cell, colIndex) { + if (_tuiCodeSnippet2.default.isUndefined(cell.colMergeWith) && _tuiCodeSnippet2.default.isUndefined(cell.rowMergeWith)) { + mappingRow.push({ + rowIndex: rowIndex, + colIndex: colIndex + }); + } + }); + mappingData.push(mappingRow); + }); + + return mappingData; +} + +/** + * Get header aligns. + * @param {Array.>} tableData - table data + * @returns {Array.} + * @private + */ +function _getHeaderAligns(tableData) { + var headRowData = tableData[0]; + + + return headRowData.map(function (cellData) { + var align = void 0; + + if (_tuiCodeSnippet2.default.isExisty(cellData.colMergeWith)) { + align = headRowData[cellData.colMergeWith].align; + } else { + align = cellData.align; + } + + return align; + }); +} + +/** + * Create render data. + * @param {Array.} tableData - table data + * @param {Array.} cellIndexData - cell index data + * @returns {Array.>} + * @ignore + */ +function createRenderData(tableData, cellIndexData) { + var headerAligns = _getHeaderAligns(tableData); + var renderData = cellIndexData.map(function (row) { + return row.map(function (_ref) { + var rowIndex = _ref.rowIndex, + colIndex = _ref.colIndex; + return _tuiCodeSnippet2.default.extend({ + align: headerAligns[colIndex] + }, tableData[rowIndex][colIndex]); + }); + }); + + if (tableData.className) { + renderData.className = tableData.className; + } + + return renderData; +} + +var BASIC_CELL_CONTENT = _tuiCodeSnippet2.default.browser.msie ? '' : '
    '; + +/** + * Create basic cell data. + * @param {number} rowIndex - row index + * @param {number} colIndex - column index + * @param {string} nodeName - node name + * @returns {{ + * nodeName: string, + * colspan: number, + * rowspan: number, + * content: string + * }} + * @ignore + */ +function createBasicCell(rowIndex, colIndex, nodeName) { + return { + nodeName: nodeName || 'TD', + colspan: 1, + rowspan: 1, + content: BASIC_CELL_CONTENT, + elementIndex: { + rowIndex: rowIndex, + colIndex: colIndex + } + }; +} + +/** + * Find element row index. + * @param {jQuery} $cell - cell jQuery element like td or th + * @returns {number} + * @ignore + */ +function findElementRowIndex($cell) { + var $tr = $cell.closest('tr'); + var rowIndex = $tr.prevAll().length; + + if ($tr.parent()[0].nodeName === 'TBODY') { + rowIndex += 1; + } + + return rowIndex; +} + +/** + * Find element col index. + * @param {jQuery} $cell - cell jQuery element like td or th + * @returns {number} + * @ignore + */ +function findElementColIndex($cell) { + return $cell.closest('td, th').prevAll().length; +} + +/** + * Find indexes of base table data from mappin data. + * @param {Array.>} cellIndexData - cell index data + * @param {jQuery} $cell - cell jQuery element like td or th + * @returns {{rowIndex: number, cellIndex: number}} + * @ignore + */ +function findCellIndex(cellIndexData, $cell) { + var elementRowIndex = findElementRowIndex($cell); + var elementColIndex = findElementColIndex($cell); + + return cellIndexData[elementRowIndex][elementColIndex]; +} + +/** + * Find last index of col merged cells. + * @param {Array.>} tableData - tableData data + * @param {number} rowIndex - row index of base data + * @param {number} colIndex - column index of tabld data + * @returns {number} + * @ignore + */ +function findRowMergedLastIndex(tableData, rowIndex, colIndex) { + var cellData = tableData[rowIndex][colIndex]; + var foundRowIndex = rowIndex; + + if (cellData.rowspan > 1) { + foundRowIndex += cellData.rowspan - 1; + } + + return foundRowIndex; +} + +/** + * Find last index of col merged cells. + * @param {Array.>} tableData - tableData data + * @param {number} rowIndex - row index of base data + * @param {number} colIndex - column index of tabld data + * @returns {number} + * @ignore + */ +function findColMergedLastIndex(tableData, rowIndex, colIndex) { + var cellData = tableData[rowIndex][colIndex]; + var foundColIndex = colIndex; + + if (cellData.colspan > 1) { + foundColIndex += cellData.colspan - 1; + } + + return foundColIndex; +} + +/** + * Find cell element index. + * @param {Array.>} tableData - tableData data + * @param {number} rowIndex - row index of base data + * @param {number} colIndex - col index of base data + * @returns {{rowIndex: number, colIndex: number}} + * @ignore + */ +function findElementIndex(tableData, rowIndex, colIndex) { + var cellData = tableData[rowIndex][colIndex]; + + rowIndex = _tuiCodeSnippet2.default.isExisty(cellData.rowMergeWith) ? cellData.rowMergeWith : rowIndex; + colIndex = _tuiCodeSnippet2.default.isExisty(cellData.colMergeWith) ? cellData.colMergeWith : colIndex; + + return tableData[rowIndex][colIndex].elementIndex; +} + +/** + * Stuff cells into incomplete row. + * @param {Array.>} tableData - table data + * @param {number} limitIndex - limit index + * @ignore + */ +function stuffCellsIntoIncompleteRow(tableData, limitIndex) { + tableData.forEach(function (rowData, rowIndex) { + var startIndex = rowData.length; + var nodeName = rowData[0].nodeName; + + + _tuiCodeSnippet2.default.range(startIndex, limitIndex).forEach(function (colIndex) { + rowData.push(createBasicCell(rowIndex, colIndex, nodeName)); + }); + }); +} + +/** + * Add tbody or thead of table data if need. + * @param {Array.>} tableData - table data + * @returns {boolean} + * @ignore + */ +function addTbodyOrTheadIfNeed(tableData) { + var header = tableData[0]; + + var cellCount = header.length; + var added = true; + + if (!cellCount && tableData[1]) { + _tuiCodeSnippet2.default.range(0, tableData[1].length).forEach(function (colIndex) { + header.push(createBasicCell(0, colIndex, 'TH')); + }); + } else if (tableData[0][0].nodeName !== 'TH') { + var _ref2; + + var newHeader = _tuiCodeSnippet2.default.range(0, cellCount).map(function (colIndex) { + return createBasicCell(0, colIndex, 'TH'); + }); + + (_ref2 = []).concat.apply(_ref2, tableData).forEach(function (cellData) { + if (cellData.elementIndex) { + cellData.elementIndex.rowIndex += 1; + } + }); + + tableData.unshift(newHeader); + } else if (tableData.length === 1) { + var newRow = _tuiCodeSnippet2.default.range(0, cellCount).map(function (colIndex) { + return createBasicCell(1, colIndex, 'TD'); + }); + + tableData.push(newRow); + } else { + added = false; + } + + return added; +} + +exports.default = { + createTableData: createTableData, + createCellIndexData: createCellIndexData, + createRenderData: createRenderData, + findElementRowIndex: findElementRowIndex, + findElementColIndex: findElementColIndex, + findCellIndex: findCellIndex, + createBasicCell: createBasicCell, + findRowMergedLastIndex: findRowMergedLastIndex, + findColMergedLastIndex: findColMergedLastIndex, + findElementIndex: findElementIndex, + stuffCellsIntoIncompleteRow: stuffCellsIntoIncompleteRow, + addTbodyOrTheadIfNeed: addTbodyOrTheadIfNeed +}; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _uicontroller = __webpack_require__(14); + +var _uicontroller2 = _interopRequireDefault(_uicontroller); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements LayerPopup + * @author NHN Ent. FE Development Lab + */ + + +var CLASS_PREFIX = 'tui-popup-'; +var CLASS_FIT_WINDOW = 'fit-window'; + +var LAYOUT_TEMPLATE_MODELESS = '
    \n \n
    \n \n
    \n
    \n
    '; + +var LAYOUT_TEMPLATE_MODAL = '
    \n
    \n \n
    \n \n
    \n
    \n
    \n
    '; + +/** + * A number, or a string containing a number. + * @typedef {Object} LayerPopupOption + * @property {string[]} [openerCssQuery] - Css Query list to bind clickevent that open popup + * @property {string[]} [closerCssQuery] - Css Query list to bind clickevent that close popup + * @property {jQuery} $el - popup root element + * @property {jQuery|string} [content] - popup content that html string or jQuery element + * @property {string} [textContent] - popup text content + * @property {string} title - popup title + * @property {boolean} [header] - whether to draw header + * @property {jQuery} [$target] - element to append popup + * @property {boolean} modal - true: modal, false: modeless + * @property {string} [headerButtons] - replace header(close) button + */ + +/** + * Class LayerPopup + * @extends {UIController} + */ + +var LayerPopup = function (_UIController) { + _inherits(LayerPopup, _UIController); + + /** + * Creates an instance of LayerPopup. + * @param {LayerPopupOption} options - popup option + * @memberof LayerPopup + */ + function LayerPopup(options) { + _classCallCheck(this, LayerPopup); + + options = _tuiCodeSnippet2.default.extend({ + header: true, + $target: (0, _jquery2.default)('body'), + textContent: '' + }, options); + + var _this = _possibleConstructorReturn(this, (LayerPopup.__proto__ || Object.getPrototypeOf(LayerPopup)).call(this, { + tagName: 'div', + className: options.modal ? CLASS_PREFIX + 'modal-background' : CLASS_PREFIX + 'wrapper', + rootElement: options.$el + })); + + _this._initInstance(options); + _this._initDOM(options); + _this._initDOMEvent(options); + _this._initEditorEvent(options); + return _this; + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof LayerPopup + * @protected + */ + + + _createClass(LayerPopup, [{ + key: '_initInstance', + value: function _initInstance(options) { + this._$target = options.$target; + + if (options.$el) { + this.$el = options.$el; + this._isExternalHtmlUse = true; + } + + if (options.content) { + this.$content = (0, _jquery2.default)(options.content); + } else { + this.$content = options.textContent; + } + + this.options = options; + } + + /** + * initialize DOM, render popup + * @memberof LayerPopup + * @protected + */ + + }, { + key: '_initDOM', + value: function _initDOM() { + this._initLayout(); + + if (!this._isExternalHtmlUse) { + if (_tuiCodeSnippet2.default.isExisty(this.options.title)) { + this.setTitle(this.options.title); + } + this.setContent(this.$content); + } + + var buttons = this.options.headerButtons; + if (buttons) { + this.$el.find('.' + CLASS_PREFIX + 'close-button').remove(); + + var $buttonWrapper = this.$el.find('.' + CLASS_PREFIX + 'header-buttons'); + $buttonWrapper.empty(); + $buttonWrapper.append((0, _jquery2.default)(buttons)); + } + + if (this.options.css) { + this.$el.css(this.options.css); + } + } + + /** + * bind DOM events + * @memberof LayerPopup + * @protected + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + var _options = this.options, + openerCssQuery = _options.openerCssQuery, + closerCssQuery = _options.closerCssQuery; + + if (openerCssQuery) { + (0, _jquery2.default)(openerCssQuery).on('click.' + this._id, function () { + return _this2.show(); + }); + } + if (closerCssQuery) { + (0, _jquery2.default)(closerCssQuery).on('click.' + this._id, function () { + return _this2.hide(); + }); + } + + this.on('click .' + CLASS_PREFIX + 'close-button', function () { + return _this2.hide(); + }); + } + + /** + * bind editor events + * @memberof LayerPopup + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() {} + }, { + key: '_initLayout', + value: function _initLayout() { + var options = this.options; + + + if (!this._isExternalHtmlUse) { + var layout = options.modal ? LAYOUT_TEMPLATE_MODAL : LAYOUT_TEMPLATE_MODELESS; + this.$el.html(layout); + this.$el.addClass(options.className); + this.hide(); + this._$target.append(this.$el); + this.$body = this.$el.find('.' + CLASS_PREFIX + 'body'); + + if (!options.header) { + this.$el.find('.' + CLASS_PREFIX + 'header').remove(); + } + } else { + this.hide(); + this._$target.append(this.$el); + } + } + + /** + * set popup content + * @param {jQuery|HTMLElement|string} $content - content + * @memberof LayerPopup + */ + + }, { + key: 'setContent', + value: function setContent($content) { + this.$body.empty(); + this.$body.append($content); + } + + /** + * set title + * @param {string} title - title text + * @memberof LayerPopup + */ + + }, { + key: 'setTitle', + value: function setTitle(title) { + var $title = this.$el.find('.' + CLASS_PREFIX + 'title'); + + $title.empty(); + $title.append(title); + } + + /** + * get title element + * @memberof LayerPopup + * @returns {HTMLElement} - title html element + */ + + }, { + key: 'getTitleElement', + value: function getTitleElement() { + return this.$el.find('.' + CLASS_PREFIX + 'title').get(0); + } + + /** + * hide popup + * @memberof LayerPopup + */ + + }, { + key: 'hide', + value: function hide() { + this.$el.css('display', 'none'); + this._isShow = false; + this.trigger('hidden', this); + } + + /** + * show popup + * @memberof LayerPopup + */ + + }, { + key: 'show', + value: function show() { + this.$el.css('display', 'block'); + this._isShow = true; + this.trigger('shown', this); + } + + /** + * whether this popup is visible + * @returns {boolean} - true: shown, false: hidden + * @memberof LayerPopup + */ + + }, { + key: 'isShow', + value: function isShow() { + return this._isShow; + } + + /** + * remove popup content + * @memberof LayerPopup + */ + + }, { + key: 'remove', + value: function remove() { + var _options2 = this.options, + openerCssQuery = _options2.openerCssQuery, + closerCssQuery = _options2.closerCssQuery; + + + this.trigger('remove', this); + this.off(); + + if (openerCssQuery) { + (0, _jquery2.default)(openerCssQuery).off('.' + this._id); + } + if (closerCssQuery) { + (0, _jquery2.default)(closerCssQuery).off('.' + this._id); + } + + this.$el.remove(); + } + + /** + * make popup size fit to window + * @param {boolean} fit - true to make popup fit to window + * @memberof LayerPopup + * @protected + */ + + }, { + key: 'setFitToWindow', + value: function setFitToWindow(fit) { + this.$el.toggleClass(CLASS_FIT_WINDOW, fit); + } + + /** + * make popup size fit to window + * @memberof LayerPopup + * @protected + * @returns {boolean} - true for fit to window + */ + + }, { + key: 'isFitToWindow', + value: function isFitToWindow() { + return this.$el.hasClass(CLASS_FIT_WINDOW); + } + + /** + * toggle size fit to window + * @memberof LayerPopup + * @protected + * @returns {boolean} - true for fit to window + */ + + }, { + key: 'toggleFitToWindow', + value: function toggleFitToWindow() { + var fitToWindow = !this.isFitToWindow(); + this.setFitToWindow(fitToWindow); + + return fitToWindow; + } + }]); + + return LayerPopup; +}(_uicontroller2.default); + +exports.default = LayerPopup; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tableDataHandler = __webpack_require__(6); + +var _tableDataHandler2 = _interopRequireDefault(_tableDataHandler); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Create cell html. + * @param {object} cell - cell data of table base data + * @returns {string} + * @private + */ +/** +* @fileoverview Implements tableRenderer +* @author NHN Ent. FE Development Lab +*/ +function _createCellHtml(cell) { + var attrs = cell.colspan > 1 ? ' colspan="' + cell.colspan + '"' : ''; + attrs += cell.rowspan > 1 ? ' rowspan="' + cell.rowspan + '"' : ''; + attrs += cell.align ? ' align="' + cell.align + '"' : ''; + + return '<' + cell.nodeName + attrs + '>' + cell.content + ''; +} + +/** + * Create html for thead or tbody. + * @param {Array.>} trs - tr list + * @param {string} wrapperNodeName - wrapper node name like THEAD, TBODY + * @returns {string} + * @private + */ +function _createTheadOrTbodyHtml(trs, wrapperNodeName) { + var html = ''; + + if (trs.length) { + html = trs.map(function (tr) { + var tdHtml = tr.map(_createCellHtml).join(''); + + return '' + tdHtml + ''; + }).join(''); + html = '<' + wrapperNodeName + '>' + html + ''; + } + + return html; +} + +/** + * Create table html. + * @param {Array.>} renderData - table data for render + * @returns {string} + * @private + */ +function createTableHtml(renderData) { + var thead = [renderData[0]]; + var tbody = renderData.slice(1); + var theadHtml = _createTheadOrTbodyHtml(thead, 'THEAD'); + var tbodyHtml = _createTheadOrTbodyHtml(tbody, 'TBODY'); + var className = renderData.className ? ' class="' + renderData.className + '"' : ''; + + return '' + (theadHtml + tbodyHtml) + ''; +} + +/** + * Replace table. + * @param {jQuery} $table - table jQuery element + * @param {Array.>} tableData - table data + * @returns {jQuery} + * @ignore + */ +function replaceTable($table, tableData) { + var cellIndexData = _tableDataHandler2.default.createCellIndexData(tableData); + var renderData = _tableDataHandler2.default.createRenderData(tableData, cellIndexData); + var $newTable = (0, _jquery2.default)(createTableHtml(renderData)); + + $table.replaceWith($newTable); + + return $newTable; +} + +/** + * Focus to cell. + * @param {squireext} sq - squire instance + * @param {range} range - range object + * @param {HTMLElement} targetCell - cell element for focus + * @ignore + */ +function focusToCell(sq, range, targetCell) { + range.selectNodeContents(targetCell); + range.collapse(true); + sq.setSelection(range); +} + +exports.default = { + createTableHtml: createTableHtml, + replaceTable: replaceTable, + focusToCell: focusToCell +}; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _tableDataHandler = __webpack_require__(6); + +var _tableDataHandler2 = _interopRequireDefault(_tableDataHandler); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Find unmerged table range. + * @param {Array.>} tableData - table data + * @param {jQuery} $start - start talbe cell jQuery element + * @param {jQuery} $end - end table cell jQuery element + * @returns {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} + * @private + */ +function _findUnmergedRange(tableData, $start, $end) { + var cellIndexData = _tableDataHandler2.default.createCellIndexData(tableData); + var startCellIndex = _tableDataHandler2.default.findCellIndex(cellIndexData, $start); + var endCellIndex = _tableDataHandler2.default.findCellIndex(cellIndexData, $end); + var startRowIndex = void 0, + endRowIndex = void 0, + startColIndex = void 0, + endColIndex = void 0; + + if (startCellIndex.rowIndex > endCellIndex.rowIndex) { + startRowIndex = endCellIndex.rowIndex; + endRowIndex = startCellIndex.rowIndex; + } else { + startRowIndex = startCellIndex.rowIndex; + endRowIndex = endCellIndex.rowIndex; + } + + if (startCellIndex.colIndex > endCellIndex.colIndex) { + startColIndex = endCellIndex.colIndex; + endColIndex = startCellIndex.colIndex; + } else { + startColIndex = startCellIndex.colIndex; + endColIndex = endCellIndex.colIndex; + } + + return { + start: { + rowIndex: startRowIndex, + colIndex: startColIndex + }, + end: { + rowIndex: endRowIndex, + colIndex: endColIndex + } + }; +} + +/** + * Expand table range by row merge properties like rowspan, rowMergeWith. + * @param {Array.>} tableData - table data + * @param {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} tableRange - table range + * @param {string} rangeType - range type like start, end + * @private + */ +/** +* @fileoverview Implements tableRangeHandler +* @author NHN Ent. FE Development Lab +*/ +function _expandRowMergedRange(tableData, tableRange, rangeType) { + var rowIndex = tableRange[rangeType].rowIndex; + + var rowData = tableData[rowIndex]; + + _tuiCodeSnippet2.default.range(tableRange.start.colIndex, tableRange.end.colIndex + 1).forEach(function (colIndex) { + var cellData = rowData[colIndex]; + var rowMergeWith = cellData.rowMergeWith; + + var lastRowMergedIndex = -1; + + if (_tuiCodeSnippet2.default.isExisty(rowMergeWith)) { + if (rowMergeWith < tableRange.start.rowIndex) { + tableRange.start.rowIndex = rowMergeWith; + } + + lastRowMergedIndex = rowMergeWith + tableData[rowMergeWith][colIndex].rowspan - 1; + } else if (cellData.rowspan > 1) { + lastRowMergedIndex = rowIndex + cellData.rowspan - 1; + } + + if (lastRowMergedIndex > tableRange.end.rowIndex) { + tableRange.end.rowIndex = lastRowMergedIndex; + } + }); +} + +/** + * Expand table range by column merge properties like colspan, colMergeWith. + * @param {Array.>} tableData - table data + * @param {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} tableRange - table range + * @param {number} rowIndex - row index + * @param {number} colIndex - column index + * @private + */ +function _expandColMergedRange(tableData, tableRange, rowIndex, colIndex) { + var rowData = tableData[rowIndex]; + var cellData = rowData[colIndex]; + var colMergeWith = cellData.colMergeWith; + + var lastColMergedIndex = -1; + + if (_tuiCodeSnippet2.default.isExisty(colMergeWith)) { + if (colMergeWith < tableRange.start.colIndex) { + tableRange.start.colIndex = colMergeWith; + } + + lastColMergedIndex = colMergeWith + rowData[colMergeWith].colspan - 1; + } else if (cellData.colspan > 1) { + lastColMergedIndex = colIndex + cellData.colspan - 1; + } + + if (lastColMergedIndex > tableRange.end.colIndex) { + tableRange.end.colIndex = lastColMergedIndex; + } +} + +/** + * Expand table range by merge properties like colspan, rowspan. + * @param {Array.>} tableData - table data + * @param {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} tableRange - table range + * @returns {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} + * @private + */ +function _expandMergedRange(tableData, tableRange) { + var rangeStr = ''; + + while (rangeStr !== JSON.stringify(tableRange)) { + rangeStr = JSON.stringify(tableRange); + + _expandRowMergedRange(tableData, tableRange, 'start'); + _expandRowMergedRange(tableData, tableRange, 'end'); + + _tuiCodeSnippet2.default.range(tableRange.start.rowIndex, tableRange.end.rowIndex + 1).forEach(function (rowIndex) { + _expandColMergedRange(tableData, tableRange, rowIndex, tableRange.start.colIndex); + _expandColMergedRange(tableData, tableRange, rowIndex, tableRange.end.colIndex); + }); + } + + return tableRange; +} + +/** + * Find table range for selection. + * @param {Array.>} tableData - table data + * @param {jQuery} $start - start jQuery element + * @param {jQuery} $end - end jQuery element + * @returns {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + * }} + * @ignore + */ +function findSelectionRange(tableData, $start, $end) { + var unmergedRange = _findUnmergedRange(tableData, $start, $end); + + return _expandMergedRange(tableData, unmergedRange); +} + +/** + * Get table selection range. + * @param {Array.>} tableData - table data + * @param {jQuery} $selectedCells - selected cells jQuery elements + * @param {jQuery} $startContainer - start container jQuery element of text range + * @returns {{ + * start: {rowIndex: number, colIndex: number}, + * end: {rowIndex: number, colIndex: number} + *}} + * @ignore + */ +function getTableSelectionRange(tableData, $selectedCells, $startContainer) { + var cellIndexData = _tableDataHandler2.default.createCellIndexData(tableData); + var tableRange = {}; + + if ($selectedCells.length) { + var startRange = _tableDataHandler2.default.findCellIndex(cellIndexData, $selectedCells.first()); + var endRange = _tuiCodeSnippet2.default.extend({}, startRange); + + $selectedCells.each(function (index, cell) { + var cellIndex = _tableDataHandler2.default.findCellIndex(cellIndexData, (0, _jquery2.default)(cell)); + var cellData = tableData[cellIndex.rowIndex][cellIndex.colIndex]; + var lastRowMergedIndex = cellIndex.rowIndex + cellData.rowspan - 1; + var lastColMergedIndex = cellIndex.colIndex + cellData.colspan - 1; + + endRange.rowIndex = Math.max(endRange.rowIndex, lastRowMergedIndex); + endRange.colIndex = Math.max(endRange.colIndex, lastColMergedIndex); + }); + + tableRange.start = startRange; + tableRange.end = endRange; + } else { + var cellIndex = _tableDataHandler2.default.findCellIndex(cellIndexData, $startContainer); + + tableRange.start = cellIndex; + tableRange.end = _tuiCodeSnippet2.default.extend({}, cellIndex); + } + + return tableRange; +} + +exports.default = { + findSelectionRange: findSelectionRange, + getTableSelectionRange: getTableSelectionRange +}; + +/***/ }), +/* 10 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_10__; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + + + +/**/ + +var processNextTick = __webpack_require__(19); +/**/ + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +module.exports = Duplex; + +/**/ +var util = __webpack_require__(16); +util.inherits = __webpack_require__(13); +/**/ + +var Readable = __webpack_require__(48); +var Writable = __webpack_require__(27); + +util.inherits(Duplex, Readable); + +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +Object.defineProperty(Duplex.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } +}); + +Duplex.prototype._destroy = function (err, cb) { + this.push(null); + this.end(); + + processNextTick(cb, err); +}; + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +/***/ }), +/* 12 */ +/***/ (function(module, exports) { + +var g; + +// This works in non-strict mode +g = (function() { + return this; +})(); + +try { + // This works if eval is allowed (see CSP) + g = g || Function("return this")() || (1,eval)("this"); +} catch(e) { + // This works if the window reference is available + if(typeof window === "object") + g = window; +} + +// g can still be undefined, but nothing to do about it... +// We return undefined, instead of nothing here, so it's +// easier to handle this case. if(!global) { ...} + +module.exports = g; + + +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements ui controller + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var _uiInstanceId = -1; + +/** + * get ui instance id + * @returns {number} - new instance id + * @ignore + */ +function makeUIInstanceId() { + _uiInstanceId += 1; + + return _uiInstanceId; +} + +/** + * Class UIController + */ + +var UIController = function () { + + /** + * Creates an instance of UIController. + * @param {Object} [options] - options + * @param {jQuery} [options.rootElement] - root element + * @param {string} [options.tagName] - tag name + * @param {string} [options.className] - class name + * @memberof UIController + */ + + + /** + * UI jQuery element + * @type {Object} + * @memberof UIController + */ + + /** + * tag name + * @type {string} + * @memberof UIController + */ + function UIController() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, UIController); + + options = _tuiCodeSnippet2.default.extend({ + tagName: 'div' + }, options); + + this.tagName = options.tagName; + + this.className = options.className; + + this._id = makeUIInstanceId(); + + this._setRootElement(options.rootElement); + } + + /** + * @param {string|object} aType - event name and selector string + * @param {function} aFn - event handler + * @memberof UIController + */ + + + /** + * UI Id + * @type {number} + * @private + * @memberof UIController + */ + + + /** + * ui controller class name + * @type {string} + * @memberof UIController + */ + + + _createClass(UIController, [{ + key: 'on', + value: function on(aType, aFn) { + var _this = this; + + if (_tuiCodeSnippet2.default.isObject(aType)) { + _tuiCodeSnippet2.default.forEach(aType, function (fn, type) { + _this._addEvent(type, fn); + }); + } else { + this._addEvent(aType, aFn); + } + } + + /** + * bind event + * @param {string} type - event name and selector + * @param {function} fn - handler function + * @memberof UIController + * @private + */ + + }, { + key: '_addEvent', + value: function _addEvent(type, fn) { + var _parseEventType2 = this._parseEventType(type), + event = _parseEventType2.event, + selector = _parseEventType2.selector; + + if (selector) { + this.$el.on(event, selector, fn); + } else { + this.$el.on(event, fn); + } + } + + /** + * unbind event handler + * @param {string} type - event name and selector + * @param {function} fn - handler function + * @memberof UIController + */ + + }, { + key: 'off', + value: function off(type, fn) { + if (type) { + var _parseEventType3 = this._parseEventType(type), + event = _parseEventType3.event, + selector = _parseEventType3.selector; + + if (selector) { + this.$el.off(event, selector, fn); + } else { + this.$el.off(event, fn); + } + } else { + this.$el.off(); + } + } + + /** + * parse string into event name & selector + * 'click td' => ['click', 'td] + * @param {string} type - string to be parsed + * @returns {Object} event, selector + * @private + */ + + }, { + key: '_parseEventType', + value: function _parseEventType(type) { + var splitType = type.split(' '); + var event = splitType.shift(); + var selector = splitType.join(' '); + + return { + event: event, + selector: selector + }; + } + + /** + * set root element + * @param {jQuery} $el - root jQuery element + * @private + */ + + }, { + key: '_setRootElement', + value: function _setRootElement($el) { + var tagName = this.tagName; + var className = this.className; + + + if (!$el) { + className = className || 'uic' + this._id; + $el = (0, _jquery2.default)('<' + tagName + ' class="' + className + '"/>'); + } + this.$el = $el; + } + + /** + * trigger event + * @param {...object} args - event name & extra params + * @memberof UIController + */ + + }, { + key: 'trigger', + value: function trigger() { + var _$el; + + (_$el = this.$el).trigger.apply(_$el, arguments); + } + }, { + key: '_getEventNameWithNamespace', + value: function _getEventNameWithNamespace(event) { + var eventSplited = event.split(' '); + eventSplited[0] += '.uicEvent' + this._id; + + return eventSplited.join(' '); + } + + /** + * remove + * @memberof UIController + */ + + }, { + key: 'remove', + value: function remove() { + if (this.$el) { + this.$el.remove(); + } + } + + /** + * destroy + * @memberof UIController + */ + + }, { + key: 'destroy', + value: function destroy() { + var _this2 = this; + + this.remove(); + + _tuiCodeSnippet2.default.forEachOwnProperties(this, function (value, key) { + _this2[key] = null; + }); + } + }]); + + return UIController; +}(); + +exports.default = UIController; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implement Module for managing import external data such as image + * @author NHN Ent. FE Development Lab + */ + + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var URLRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})(\/([^\s]*))?$/g; + +/** + * Class ImportManager + */ + +var ImportManager = function () { + /** + * Creates an instance of ImportManager. + * @param {EventManager} eventManager - eventManager + * @memberof ImportManager + */ + function ImportManager(eventManager) { + _classCallCheck(this, ImportManager); + + this.eventManager = eventManager; + + this._initEvent(); + this._initDefaultImageImporter(); + } + + /** + * graceful decode uri component + * @param {string} originalURI - string to be decoded + * @returns {string} decoded string + * @memberof ImportManager + * @static + */ + + + _createClass(ImportManager, [{ + key: '_initEvent', + + + /** + * Initialize event handler + * @memberof ImportManager + * @private + */ + value: function _initEvent() { + var _this = this; + + this.eventManager.listen('drop', function (ev) { + var items = ev.data.dataTransfer && ev.data.dataTransfer.files; + _this._processBlobItems(items, ev.data); + }); + + this.eventManager.listen('willPaste', function (ev) { + // IE has no interface to handle clipboard image. #976 + var fragment = ev.data.fragment; + var descendant = fragment.querySelectorAll('*'); + // only if paste event data has one img element and the element has base64 encoded image + if (descendant.length !== 1 || descendant[0].tagName !== 'IMG' || !/^data:image/.test(descendant[0].src)) { + return; + } + ev.data.preventDefault(); + + var blob = dataURItoBlob(descendant[0].src); + _this._emitAddImageBlobHook(blob, 'paste'); + }); + + this.eventManager.listen('paste', function (ev) { + _this._processClipboard(ev.data); + }); + + this.eventManager.listen('pasteBefore', function (ev) { + _this._decodeURL(ev); + }); + } + + /** + * Initialize default image importer + * @memberof ImportManager + * @private + */ + + }, { + key: '_initDefaultImageImporter', + value: function _initDefaultImageImporter() { + this.eventManager.listen('addImageBlobHook', function (blob, callback) { + var reader = new FileReader(); + + reader.onload = function (event) { + callback(event.target.result); + }; + + reader.readAsDataURL(blob); + }); + } + + /** + * Emit add image blob hook + * @memberof ImportManager + * @param {object} blob - blob or file + * @param {string} type - type of an event the item belongs to. paste or drop + * @private + */ + + }, { + key: '_emitAddImageBlobHook', + value: function _emitAddImageBlobHook(blob, type) { + var _this2 = this; + + this.eventManager.emit('addImageBlobHook', blob, function (imageUrl, altText) { + _this2.eventManager.emit('command', 'AddImage', { + imageUrl: imageUrl, + altText: altText || blob.name || 'image' + }); + }, type); + } + + /** + * Decode url when paste link + * @param {object} ev - event object + * @private + */ + + }, { + key: '_decodeURL', + value: function _decodeURL(ev) { + var decodeURIGraceful = ImportManager.decodeURIGraceful, + encodeMarkdownCharacters = ImportManager.encodeMarkdownCharacters; + + + if (ev.source === 'markdown' && ev.data.text) { + var texts = ev.data.text; + var text = texts[0]; + if (texts.length === 1 && text.match(URLRegex)) { + text = decodeURIGraceful(text); + text = encodeMarkdownCharacters(text); + ev.data.update(null, null, [text]); + } + } else if (ev.source === 'wysiwyg') { + var container = ev.$clipboardContainer.get(0); + var firstChild = container.childNodes[0]; + var _text = firstChild.innerText; + if (container.childNodes.length === 1 && firstChild.tagName === 'A' && _text.match(URLRegex)) { + firstChild.innerText = decodeURIGraceful(_text); + firstChild.href = encodeMarkdownCharacters(firstChild.href); + } + } + } + + /** + * Get blob or excel data from clipboard + * @memberof ImportManager + * @param {object} evData Clipboard data + * @private + */ + + }, { + key: '_processClipboard', + value: function _processClipboard(evData) { + var cbData = evData.clipboardData || window.clipboardData; + var blobItems = cbData && cbData.items; + var types = cbData.types; + + + if (blobItems && types && types.length === 1 && _tuiCodeSnippet2.default.inArray('Files', [].slice.call(types)) !== -1) { + this._processBlobItems(blobItems, evData); + } + } + + /** + * Process for blob item + * @memberof ImportManager + * @param {Array.} items Item array + * @param {object} evData Event data + * @private + */ + + }, { + key: '_processBlobItems', + value: function _processBlobItems(items, evData) { + var _this3 = this; + + if (items) { + _tuiCodeSnippet2.default.forEachArray(items, function (item) { + if (item.type.indexOf('image') !== -1) { + evData.preventDefault(); + evData.stopPropagation(); + evData.codemirrorIgnore = true; + + var blob = item.name ? item : item.getAsFile(); // Blob or File + _this3._emitAddImageBlobHook(blob, evData.type); + + return false; + } + + return true; + }); + } + } + }], [{ + key: 'decodeURIGraceful', + value: function decodeURIGraceful(originalURI) { + var uris = originalURI.split(' '); + var decodedURIs = []; + var decodedURI = void 0; + + _tuiCodeSnippet2.default.forEachArray(uris, function (uri) { + try { + decodedURI = decodeURIComponent(uri); + decodedURI = decodedURI.replace(/ /g, '%20'); + } catch (e) { + decodedURI = uri; + } + + return decodedURIs.push(decodedURI); + }); + + return decodedURIs.join(' '); + } + + /** + * encode markdown critical characters + * @static + * @param {string} text - string to encode + * @returns {string} - markdown character encoded string + * @memberof ImportManager + */ + + }, { + key: 'encodeMarkdownCharacters', + value: function encodeMarkdownCharacters(text) { + return text.replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\[/g, '%5B').replace(/\]/g, '%5D').replace(//g, '%3E'); + } + + /** + * escape markdown critical characters + * @static + * @param {string} text - string to escape + * @returns {string} - markdown character escaped string + * @memberof ImportManager + */ + + }, { + key: 'escapeMarkdownCharacters', + value: function escapeMarkdownCharacters(text) { + return text.replace(/\(/g, '\\(').replace(/\)/g, '\\)').replace(/\[/g, '\\[').replace(/\]/g, '\\]').replace(//g, '\\>'); + } + }]); + + return ImportManager; +}(); + +/** + * data URI to Blob + * @param {string} dataURI - data URI string + * @returns {Blob} - blob data + * @ignore + */ + + +function dataURItoBlob(dataURI) { + var byteString = atob(dataURI.split(',')[1]); + var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i += 1) { + ia[i] = byteString.charCodeAt(i); + } + var blob = new Blob([ab], { type: mimeString }); + + return blob; +} + +exports.default = ImportManager; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51).Buffer)) + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _uicontroller = __webpack_require__(14); + +var _uicontroller2 = _interopRequireDefault(_uicontroller); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements Toolbar Item + * @author NHN Ent. FE Development Lab + */ + + +/** + * Toolbar Item + * @extends {UIController} + */ +var ToolbarItem = function (_UIController) { + _inherits(ToolbarItem, _UIController); + + /** + * toolbar item constructor + * @memberof ToolbarItem + * @param {Object} [options={name: 'toolbar-item'}] [description] + */ + + /** + * item name + * @memberof ToolbarDivider + * @type {String} + * @static + */ + function ToolbarItem() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + name: ToolbarItem.name + }; + + _classCallCheck(this, ToolbarItem); + + var _this = _possibleConstructorReturn(this, (ToolbarItem.__proto__ || Object.getPrototypeOf(ToolbarItem)).call(this, _tuiCodeSnippet2.default.extend({ + className: ToolbarItem.className + }, options))); + + _this._name = options.name; + return _this; + } + + /** + * get the name of the toolbar item + * @memberof ToolbarItem + * @returns {string} - the name of the toolbar item + */ + + + /** + * toolbar item class name + * @memberof ToolbarItem + * @type {String} + */ + + + _createClass(ToolbarItem, [{ + key: 'getName', + value: function getName() { + return this._name; + } + }]); + + return ToolbarItem; +}(_uicontroller2.default); + +Object.defineProperty(ToolbarItem, 'name', { + enumerable: true, + writable: true, + value: 'item' +}); +Object.defineProperty(ToolbarItem, 'className', { + enumerable: true, + writable: true, + value: 'tui-toolbar-item' +}); +exports.default = ToolbarItem; + +/***/ }), +/* 18 */ +/***/ (function(module, exports) { + +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) { + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = nextTick; +} else { + module.exports = process.nextTick; +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-disable node/no-deprecated-api */ +var buffer = __webpack_require__(51) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} + + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _toolbarItem = __webpack_require__(17); + +var _toolbarItem2 = _interopRequireDefault(_toolbarItem); + +var _tooltip = __webpack_require__(29); + +var _tooltip2 = _interopRequireDefault(_tooltip); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements UI Button + * @author NHN Ent. FE Development Lab + */ + + +/** + * Class Button UI + * @extends {ToolbarItem} + * @deprecated + */ +var Button = function (_ToolbarItem) { + _inherits(Button, _ToolbarItem); + + /** + * Creates an instance of Button. + * @param {object} options - button options + * @param {jquery} $el - button rootElement + * @param {string} options.className - button class name + * @param {string} options.command - command name to execute on click + * @param {string} options.event - event name to trigger on click + * @param {string} options.text - text on button + * @param {string} options.tooltip - text on tooltip + * @param {string} options.style - button style + * @param {string} options.state - button state + * @memberof Button + */ + + /** + * item name + * @memberof Button + * @type {String} + * @static + */ + function Button() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + tagName: 'button', + name: Button.name + }; + + _classCallCheck(this, Button); + + var _this = _possibleConstructorReturn(this, (Button.__proto__ || Object.getPrototypeOf(Button)).call(this, { + name: options.name, + tagName: 'button', + className: options.className + ' ' + Button.className, + rootElement: options.$el + })); + + _this._setOptions(options); + + _this._render(); + _this.on('click', _this._onClick.bind(_this)); + if (options.tooltip) { + _this.on('mouseover', _this._onOver.bind(_this)); + _this.on('mouseout', _this._onOut.bind(_this)); + } + return _this; + } + + /** + * set tooltip text + * @param {string} text - tooltip text to show + * @memberof Button + */ + + + /** + * ToolbarItem className + * @type {String} + * @memberof Button + * @static + */ + + + _createClass(Button, [{ + key: 'setTooltip', + value: function setTooltip(text) { + this._tooltip = text; + } + }, { + key: '_setOptions', + value: function _setOptions(options) { + this._command = options.command; + this._event = options.event; + this._text = options.text; + this._tooltip = options.tooltip; + this._style = options.style; + this._state = options.state; + } + }, { + key: '_render', + value: function _render() { + this.$el.text(this._text); + this.$el.attr('type', 'button'); + + if (this._style) { + this.$el.attr('style', this._style); + } + } + }, { + key: '_onClick', + value: function _onClick() { + if (!this.isEnabled()) { + return; + } + + if (this._command) { + this.trigger('command', this._command); + } else if (this._event) { + this.trigger('event', this._event); + } + + this.trigger('clicked'); + } + }, { + key: '_onOver', + value: function _onOver() { + if (!this.isEnabled()) { + return; + } + + _tooltip2.default.show(this.$el, this._tooltip); + } + }, { + key: '_onOut', + value: function _onOut() { + _tooltip2.default.hide(); + } + + /** + * enable button + * @memberof Button + */ + + }, { + key: 'enable', + value: function enable() { + this.$el.attr('disabled', false); + } + + /** + * disable button + * @memberof Button + */ + + }, { + key: 'disable', + value: function disable() { + this.$el.attr('disabled', true); + } + + /** + * check whether this button is enabled + * @returns {Boolean} - true for enabled + * @memberof Button + */ + + }, { + key: 'isEnabled', + value: function isEnabled() { + return !this.$el.attr('disabled'); + } + }]); + + return Button; +}(_toolbarItem2.default); + +Object.defineProperty(Button, 'name', { + enumerable: true, + writable: true, + value: 'button' +}); +Object.defineProperty(Button, 'className', { + enumerable: true, + writable: true, + value: 'tui-toolbar-icons' +}); +exports.default = Button; + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @fileoverview Implements KeyMapper + * @author NHN Ent. FE Development Lab + */ + +/** + * Constant of key mapping + * @type {string[]} + * @ignore + */ +var KEYBOARD_MAP = ['', // [0] +'', // [1] +'', // [2] +'CANCEL', // [3] +'', // [4] +'', // [5] +'HELP', // [6] +'', // [7] +'BACK_SPACE', // [8] +'TAB', // [9] +'', // [10] +'', // [11] +'CLEAR', // [12] +'ENTER', // [13] +'ENTER_SPECIAL', // [14] +'', // [15] +'', // [16] SHIFT +'', // [17] CONTROL +'', // [18] ALT +'PAUSE', // [19] +'CAPS_LOCK', // [20] +'KANA', // [21] +'EISU', // [22] +'JUNJA', // [23] +'FINAL', // [24] +'HANJA', // [25] +'', // [26] +'ESCAPE', // [27] +'CONVERT', // [28] +'NONCONVERT', // [29] +'ACCEPT', // [30] +'MODECHANGE', // [31] +'SPACE', // [32] +'PAGE_UP', // [33] +'PAGE_DOWN', // [34] +'END', // [35] +'HOME', // [36] +'LEFT', // [37] +'UP', // [38] +'RIGHT', // [39] +'DOWN', // [40] +'SELECT', // [41] +'PRINT', // [42] +'EXECUTE', // [43] +'PRINTSCREEN', // [44] +'INSERT', // [45] +'DELETE', // [46] +'', // [47] +'0', // [48] +'1', // [49] +'2', // [50] +'3', // [51] +'4', // [52] +'5', // [53] +'6', // [54] +'7', // [55] +'8', // [56] +'9', // [57] +':', // [58] +';', // [59] +'<', // [60] +'=', // [61] +'>', // [62] +'?', // [63] +'AT', // [64] +'A', // [65] +'B', // [66] +'C', // [67] +'D', // [68] +'E', // [69] +'F', // [70] +'G', // [71] +'H', // [72] +'I', // [73] +'J', // [74] +'K', // [75] +'L', // [76] +'M', // [77] +'N', // [78] +'O', // [79] +'P', // [80] +'Q', // [81] +'R', // [82] +'S', // [83] +'T', // [84] +'U', // [85] +'V', // [86] +'W', // [87] +'X', // [88] +'Y', // [89] +'Z', // [90] +'', // [91] META +'', // [92] +'CONTEXT_MENU', // [93] +'', // [94] +'SLEEP', // [95] +'NUMPAD0', // [96] +'NUMPAD1', // [97] +'NUMPAD2', // [98] +'NUMPAD3', // [99] +'NUMPAD4', // [100] +'NUMPAD5', // [101] +'NUMPAD6', // [102] +'NUMPAD7', // [103] +'NUMPAD8', // [104] +'NUMPAD9', // [105] +'MULTIPLY', // [106] +'ADD', // [107] +'SEPARATOR', // [108] +'SUBTRACT', // [109] +'DECIMAL', // [110] +'DIVIDE', // [111] +'F1', // [112] +'F2', // [113] +'F3', // [114] +'F4', // [115] +'F5', // [116] +'F6', // [117] +'F7', // [118] +'F8', // [119] +'F9', // [120] +'F10', // [121] +'F11', // [122] +'F12', // [123] +'F13', // [124] +'F14', // [125] +'F15', // [126] +'F16', // [127] +'F17', // [128] +'F18', // [129] +'F19', // [130] +'F20', // [131] +'F21', // [132] +'F22', // [133] +'F23', // [134] +'F24', // [135] +'', // [136] +'', // [137] +'', // [138] +'', // [139] +'', // [140] +'', // [141] +'', // [142] +'', // [143] +'NUM_LOCK', // [144] +'SCROLL_LOCK', // [145] +'WIN_OEM_FJ_JISHO', // [146] +'WIN_OEM_FJ_MASSHOU', // [147] +'WIN_OEM_FJ_TOUROKU', // [148] +'WIN_OEM_FJ_LOYA', // [149] +'WIN_OEM_FJ_ROYA', // [150] +'', // [151] +'', // [152] +'', // [153] +'', // [154] +'', // [155] +'', // [156] +'', // [157] +'', // [158] +'', // [159] +'@', // [160] +'!', // [161] +'"', // [162] +'#', // [163] +'$', // [164] +'%', // [165] +'&', // [166] +'_', // [167] +'(', // [168] +')', // [169] +'*', // [170] +'+', // [171] +'|', // [172] +'-', // [173] +'{', // [174] +'}', // [175] +'~', // [176] +'', // [177] +'', // [178] +'', // [179] +'', // [180] +'VOLUME_MUTE', // [181] +'VOLUME_DOWN', // [182] +'VOLUME_UP', // [183] +'', // [184] +'', // [185] +';', // [186] +'=', // [187] +',', // [188] +'-', // [189] +'.', // [190] +'/', // [191] +'`', // [192] +'', // [193] +'', // [194] +'', // [195] +'', // [196] +'', // [197] +'', // [198] +'', // [199] +'', // [200] +'', // [201] +'', // [202] +'', // [203] +'', // [204] +'', // [205] +'', // [206] +'', // [207] +'', // [208] +'', // [209] +'', // [210] +'', // [211] +'', // [212] +'', // [213] +'', // [214] +'', // [215] +'', // [216] +'', // [217] +'', // [218] +'[', // [219] +'\\', // [220] +']', // [221] +'\'', // [222] +'', // [223] +'META', // [224] +'ALTGR', // [225] +'', // [226] +'WIN_ICO_HELP', // [227] +'WIN_ICO_00', // [228] +'', // [229] +'WIN_ICO_CLEAR', // [230] +'', // [231] +'', // [232] +'WIN_OEM_RESET', // [233] +'WIN_OEM_JUMP', // [234] +'WIN_OEM_PA1', // [235] +'WIN_OEM_PA2', // [236] +'WIN_OEM_PA3', // [237] +'WIN_OEM_WSCTRL', // [238] +'WIN_OEM_CUSEL', // [239] +'WIN_OEM_ATTN', // [240] +'WIN_OEM_FINISH', // [241] +'WIN_OEM_COPY', // [242] +'WIN_OEM_AUTO', // [243] +'WIN_OEM_ENLW', // [244] +'WIN_OEM_BACKTAB', // [245] +'ATTN', // [246] +'CRSEL', // [247] +'EXSEL', // [248] +'EREOF', // [249] +'PLAY', // [250] +'ZOOM', // [251] +'', // [252] +'PA1', // [253] +'WIN_OEM_CLEAR', // [254] +'' // [255] +]; + +var sharedInstance = void 0; + +/** + * Class KeyMapper + */ + +var KeyMapper = function () { + /** + * Creates an instance of KeyMapper. + * @param {object} [options] options + * @param {string} options.splitter splitter string default is + + * @memberof KeyMapper + */ + function KeyMapper(options) { + _classCallCheck(this, KeyMapper); + + this._setSplitter(options); + } + + /** + * Set key splitter + * @param {object} options Option object + * @memberof KeyMapper + * @private + */ + + + _createClass(KeyMapper, [{ + key: '_setSplitter', + value: function _setSplitter(options) { + var splitter = options ? options.splitter : '+'; + this._splitter = splitter; + } + + /** + * Convert event to keyMap + * @memberof KeyMapper + * @param {event} event Event object + * @returns {string} + */ + + }, { + key: 'convert', + value: function convert(event) { + var keyMap = []; + + if (event.shiftKey) { + keyMap.push('SHIFT'); + } + + if (event.ctrlKey) { + keyMap.push('CTRL'); + } + + if (event.metaKey) { + keyMap.push('META'); + } + + if (event.altKey) { + keyMap.push('ALT'); + } + + var keyChar = this._getKeyCodeChar(event.keyCode); + + if (keyChar) { + keyMap.push(keyChar); + } + + return keyMap.join(this._splitter); + } + + /** + * Get character from key code + * @memberof KeyMapper + * @param {number} keyCode Key code + * @returns {string} + * @private + */ + + }, { + key: '_getKeyCodeChar', + value: function _getKeyCodeChar(keyCode) { + var keyCodeCharacter = KEYBOARD_MAP[keyCode]; + + return keyCodeCharacter; + } + + /** + * Get sharedInstance + * @memberof KeyMapper + * @returns {KeyMapper} + */ + + }], [{ + key: 'getSharedInstance', + value: function getSharedInstance() { + if (!sharedInstance) { + sharedInstance = new KeyMapper(); + } + + return sharedInstance; + } + + /** + * get key code for a character + * @static + * @param {string} char - a character to be converted + * @returns {number} key code for the char + * @memberof KeyMapper + */ + + }, { + key: 'keyCode', + value: function keyCode(char) { + return KEYBOARD_MAP.indexOf(char); + } + }]); + + return KeyMapper; +}(); + +exports.default = KeyMapper; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeBlockManager = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements CodeBlockManager + * @author NHN Ent. FE Development Lab + */ + + +var _highlight = __webpack_require__(91); + +var _highlight2 = _interopRequireDefault(_highlight); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class Code Block Manager + */ +var CodeBlockManager = function () { + /** + * Creates an instance of CodeBlockManager. + * @memberof CodeBlockManager + */ + function CodeBlockManager() { + _classCallCheck(this, CodeBlockManager); + + this._replacers = {}; + } + + /** + * Set replacer for code block + * @param {string} language - code block language + * @param {function} replacer - replacer function to code block element + */ + + + _createClass(CodeBlockManager, [{ + key: 'setReplacer', + value: function setReplacer(language, replacer) { + this._replacers[language] = replacer; + } + + /** + * get replacer for code block + * @param {string} language - code block type + * @returns {function} - replacer function + * @memberof CodeBlockManager + */ + + }, { + key: 'getReplacer', + value: function getReplacer(language) { + return this._replacers[language]; + } + + /** + * Create code block html. + * @param {string} language - code block language + * @param {string} codeText - code text + * @returns {string} + */ + + }, { + key: 'createCodeBlockHtml', + value: function createCodeBlockHtml(language, codeText) { + var replacer = this.getReplacer(language); + var html = void 0; + + if (replacer) { + html = replacer(codeText, language); + } else { + html = _highlight2.default.getLanguage(language) ? _highlight2.default.highlight(language, codeText).value : escape(codeText, false); + } + + return html; + } + + /** + * get supported languages by highlight-js + * @returns {Array} - supported languages by highlight-js + * @static + */ + + }], [{ + key: 'getHighlightJSLanguages', + value: function getHighlightJSLanguages() { + return _highlight2.default.listLanguages(); + } + }]); + + return CodeBlockManager; +}(); + +/** + * escape code from markdown-it + * @param {string} html HTML string + * @param {string} encode Boolean value of whether encode or not + * @returns {string} + * @ignore + */ + + +function escape(html, encode) { + return html.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, '''); +} + +exports.CodeBlockManager = CodeBlockManager; +exports.default = new CodeBlockManager(); + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var FIND_MD_OL_RX = exports.FIND_MD_OL_RX = /^[ \t]*[\d]+\. .*/; +var FIND_MD_UL_RX = exports.FIND_MD_UL_RX = /^[ \t]*[-*] .*/; +var FIND_MD_TASK_RX = exports.FIND_MD_TASK_RX = /^[ \t]*([*-] |[\d]+\. )(\[[ xX]] ).*/; +var FIND_MD_UL_TASK_RX = exports.FIND_MD_UL_TASK_RX = /^[ \t]*[*-] (\[[ xX]] ).*/; + +/***/ }), +/* 25 */ +/***/ (function(module, exports) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__(48); +exports.Stream = exports; +exports.Readable = exports; +exports.Writable = __webpack_require__(27); +exports.Duplex = __webpack_require__(11); +exports.Transform = __webpack_require__(54); +exports.PassThrough = __webpack_require__(173); + + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + + + +/**/ + +var processNextTick = __webpack_require__(19); +/**/ + +module.exports = Writable; + +/* */ +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + this.finish = function () { + onCorkedFinish(_this, state); + }; +} +/* */ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ + +/**/ +var Duplex; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = __webpack_require__(16); +util.inherits = __webpack_require__(13); +/**/ + +/**/ +var internalUtil = { + deprecate: __webpack_require__(172) +}; +/**/ + +/**/ +var Stream = __webpack_require__(50); +/**/ + +/**/ +var Buffer = __webpack_require__(20).Buffer; +var OurUint8Array = global.Uint8Array || function () {}; +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} +/**/ + +var destroyImpl = __webpack_require__(52); + +util.inherits(Writable, Stream); + +function nop() {} + +function WritableState(options, stream) { + Duplex = Duplex || __webpack_require__(11); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // if _final has been called + this.finalCalled = false; + + // drain event flag. + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // has it been destroyed + this.destroyed = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); +} + +WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') + }); + } catch (_) {} +})(); + +// Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. +var realHasInstance; +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function (object) { + return object instanceof this; + }; +} + +function Writable(options) { + Duplex = Duplex || __webpack_require__(11); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { + return new Writable(options); + } + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + + if (typeof options.final === 'function') this._final = options.final; + } + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe, not readable')); +}; + +function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + processNextTick(cb, er); +} + +// Checks that a user-supplied chunk is valid, especially for the particular +// mode the stream is in. Currently this means that `null` is never accepted +// and undefined/non-string values are only allowed in object mode. +function validChunk(stream, state, chunk, cb) { + var valid = true; + var er = false; + + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + processNextTick(cb, er); + valid = false; + } + return valid; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + var isBuf = _isUint8Array(chunk) && !state.objectMode; + + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } +}; + +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; + return this; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } + } + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + processNextTick(cb, er); + // this can emit finish, and it will always happen + // after error + processNextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + // this can emit finish, but finish must + // always follow error + finishMaybe(stream, state); + } +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /**/ + asyncWrite(afterWrite, stream, state, finished, cb); + /**/ + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + var allBuffers = true; + while (entry) { + buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; + entry = entry.next; + count += 1; + } + buffer.allBuffers = allBuffers; + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequestCount = 0; + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('_write() is not implemented')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} +function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + if (err) { + stream.emit('error', err); + } + state.prefinished = true; + stream.emit('prefinish'); + finishMaybe(stream, state); + }); +} +function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function') { + state.pendingcb++; + state.finalCalled = true; + processNextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } + } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + prefinish(stream, state); + if (state.pendingcb === 0) { + state.finished = true; + stream.emit('finish'); + } + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) processNextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; +} + +function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = corkReq; + } else { + state.corkedRequestsFree = corkReq; + } +} + +Object.defineProperty(Writable.prototype, 'destroyed', { + get: function () { + if (this._writableState === undefined) { + return false; + } + return this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } +}); + +Writable.prototype.destroy = destroyImpl.destroy; +Writable.prototype._undestroy = destroyImpl.undestroy; +Writable.prototype._destroy = function (err, cb) { + this.end(); + cb(err); +}; +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18), __webpack_require__(170).setImmediate, __webpack_require__(12))) + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implemtents Editor + * @author NHN Ent. FE Development Lab + */ + + +// markdown commands + + +// wysiwyg Commands + + +// langs + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _button = __webpack_require__(21); + +var _button2 = _interopRequireDefault(_button); + +var _markdownEditor = __webpack_require__(58); + +var _markdownEditor2 = _interopRequireDefault(_markdownEditor); + +var _mdPreview = __webpack_require__(32); + +var _mdPreview2 = _interopRequireDefault(_mdPreview); + +var _wysiwygEditor = __webpack_require__(68); + +var _wysiwygEditor2 = _interopRequireDefault(_wysiwygEditor); + +var _layout = __webpack_require__(81); + +var _layout2 = _interopRequireDefault(_layout); + +var _eventManager = __webpack_require__(39); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _commandManager2 = __webpack_require__(2); + +var _commandManager3 = _interopRequireDefault(_commandManager2); + +var _extManager = __webpack_require__(40); + +var _extManager2 = _interopRequireDefault(_extManager); + +var _importManager = __webpack_require__(15); + +var _importManager2 = _interopRequireDefault(_importManager); + +var _wwCodeBlockManager = __webpack_require__(37); + +var _wwCodeBlockManager2 = _interopRequireDefault(_wwCodeBlockManager); + +var _convertor = __webpack_require__(41); + +var _convertor2 = _interopRequireDefault(_convertor); + +var _viewer = __webpack_require__(92); + +var _viewer2 = _interopRequireDefault(_viewer); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +var _defaultUI = __webpack_require__(93); + +var _defaultUI2 = _interopRequireDefault(_defaultUI); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _wwTableManager = __webpack_require__(35); + +var _wwTableManager2 = _interopRequireDefault(_wwTableManager); + +var _wwTableSelectionManager = __webpack_require__(36); + +var _wwTableSelectionManager2 = _interopRequireDefault(_wwTableSelectionManager); + +var _codeBlockManager = __webpack_require__(23); + +var _codeBlockManager2 = _interopRequireDefault(_codeBlockManager); + +var _bold = __webpack_require__(110); + +var _bold2 = _interopRequireDefault(_bold); + +var _italic = __webpack_require__(111); + +var _italic2 = _interopRequireDefault(_italic); + +var _strike = __webpack_require__(112); + +var _strike2 = _interopRequireDefault(_strike); + +var _blockquote = __webpack_require__(113); + +var _blockquote2 = _interopRequireDefault(_blockquote); + +var _heading = __webpack_require__(114); + +var _heading2 = _interopRequireDefault(_heading); + +var _paragraph = __webpack_require__(115); + +var _paragraph2 = _interopRequireDefault(_paragraph); + +var _hr = __webpack_require__(116); + +var _hr2 = _interopRequireDefault(_hr); + +var _addLink = __webpack_require__(117); + +var _addLink2 = _interopRequireDefault(_addLink); + +var _addImage = __webpack_require__(118); + +var _addImage2 = _interopRequireDefault(_addImage); + +var _ul = __webpack_require__(119); + +var _ul2 = _interopRequireDefault(_ul); + +var _ol = __webpack_require__(120); + +var _ol2 = _interopRequireDefault(_ol); + +var _indent = __webpack_require__(121); + +var _indent2 = _interopRequireDefault(_indent); + +var _outdent = __webpack_require__(122); + +var _outdent2 = _interopRequireDefault(_outdent); + +var _table = __webpack_require__(123); + +var _table2 = _interopRequireDefault(_table); + +var _task = __webpack_require__(124); + +var _task2 = _interopRequireDefault(_task); + +var _code = __webpack_require__(125); + +var _code2 = _interopRequireDefault(_code); + +var _codeBlock = __webpack_require__(126); + +var _codeBlock2 = _interopRequireDefault(_codeBlock); + +var _bold3 = __webpack_require__(127); + +var _bold4 = _interopRequireDefault(_bold3); + +var _italic3 = __webpack_require__(128); + +var _italic4 = _interopRequireDefault(_italic3); + +var _strike3 = __webpack_require__(129); + +var _strike4 = _interopRequireDefault(_strike3); + +var _blockquote3 = __webpack_require__(130); + +var _blockquote4 = _interopRequireDefault(_blockquote3); + +var _addImage3 = __webpack_require__(131); + +var _addImage4 = _interopRequireDefault(_addImage3); + +var _addLink3 = __webpack_require__(132); + +var _addLink4 = _interopRequireDefault(_addLink3); + +var _hr3 = __webpack_require__(133); + +var _hr4 = _interopRequireDefault(_hr3); + +var _heading3 = __webpack_require__(134); + +var _heading4 = _interopRequireDefault(_heading3); + +var _paragraph3 = __webpack_require__(135); + +var _paragraph4 = _interopRequireDefault(_paragraph3); + +var _ul3 = __webpack_require__(136); + +var _ul4 = _interopRequireDefault(_ul3); + +var _ol3 = __webpack_require__(137); + +var _ol4 = _interopRequireDefault(_ol3); + +var _table3 = __webpack_require__(138); + +var _table4 = _interopRequireDefault(_table3); + +var _tableAddRow = __webpack_require__(139); + +var _tableAddRow2 = _interopRequireDefault(_tableAddRow); + +var _tableAddCol = __webpack_require__(140); + +var _tableAddCol2 = _interopRequireDefault(_tableAddCol); + +var _tableRemoveRow = __webpack_require__(141); + +var _tableRemoveRow2 = _interopRequireDefault(_tableRemoveRow); + +var _tableRemoveCol = __webpack_require__(142); + +var _tableRemoveCol2 = _interopRequireDefault(_tableRemoveCol); + +var _tableAlignCol = __webpack_require__(143); + +var _tableAlignCol2 = _interopRequireDefault(_tableAlignCol); + +var _tableRemove = __webpack_require__(144); + +var _tableRemove2 = _interopRequireDefault(_tableRemove); + +var _indent3 = __webpack_require__(145); + +var _indent4 = _interopRequireDefault(_indent3); + +var _outdent3 = __webpack_require__(146); + +var _outdent4 = _interopRequireDefault(_outdent3); + +var _task3 = __webpack_require__(147); + +var _task4 = _interopRequireDefault(_task3); + +var _code3 = __webpack_require__(148); + +var _code4 = _interopRequireDefault(_code3); + +var _codeBlock3 = __webpack_require__(149); + +var _codeBlock4 = _interopRequireDefault(_codeBlock3); + +__webpack_require__(150); + +__webpack_require__(151); + +__webpack_require__(152); + +__webpack_require__(153); + +__webpack_require__(154); + +__webpack_require__(155); + +__webpack_require__(156); + +__webpack_require__(157); + +__webpack_require__(158); + +__webpack_require__(159); + +__webpack_require__(160); + +__webpack_require__(161); + +__webpack_require__(162); + +__webpack_require__(163); + +__webpack_require__(164); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var __nedInstance = []; +var gaTrackingId = 'UA-129966929-1'; + +/** + * @callback addImageBlobHook + * @param {File|Blob} fileOrBlob - image blob + * @param {callback} callback - callback function to be called after + * @param {string} source - source of an event the item belongs to. 'paste', 'drop', 'ui' + */ + +/** + * Class ToastUIEditor + */ + +var ToastUIEditor = function () { + /** + * ToastUI Editor + * @param {object} options Option object + * @param {HTMLElement} options.el - container element + * @param {string} [options.height='300px'] - Editor's height style value. Height is applied as border-box ex) '300px', '100%', 'auto' + * @param {string} [options.minHeight='200px'] - Editor's min-height style value in pixel ex) '300px' + * @param {string} [options.initialValue] - Editor's initial value + * @param {string} [options.previewStyle] - Markdown editor's preview style (tab, vertical) + * @param {string} [options.initialEditType] - Initial editor type (markdown, wysiwyg) + * @param {object[]} [options.events] - eventlist Event list + * @param {function} options.events.load - It would be emitted when editor fully load + * @param {function} options.events.change - It would be emitted when content changed + * @param {function} options.events.stateChange - It would be emitted when format change by cursor position + * @param {function} options.events.focus - It would be emitted when editor get focus + * @param {function} options.events.blur - It would be emitted when editor loose focus + * @param {object[]} [options.hooks] - Hook list + * @param {function} options.hooks.previewBeforeHook - Submit preview to hook URL before preview be shown + * @param {addImageBlobHook} options.hooks.addImageBlobHook - hook for image upload. + * @param {string} [options.language='en_US'] - language + * @param {boolean} [options.useCommandShortcut=true] - whether use keyboard shortcuts to perform commands + * @param {boolean} [options.useDefaultHTMLSanitizer=true] - use default htmlSanitizer + * @param {string[]} [options.codeBlockLanguages] - supported code block languages to be listed. default is what highlight.js supports + * @param {boolean} [options.usageStatistics=true] - send hostname to google analytics + * @param {string[]} [options.toolbarItems] - toolbar items. + * @param {boolean} [options.hideModeSwitch=false] - hide mode switch tab bar + * @param {string[]} [options.exts] - extensions + * @param {object} [options.customConvertor] - convertor extention + */ + function ToastUIEditor(options) { + var _this = this; + + _classCallCheck(this, ToastUIEditor); + + this.initialHtml = options.el.innerHTML; + options.el.innerHTML = ''; + + this.options = _jquery2.default.extend({ + previewStyle: 'tab', + initialEditType: 'markdown', + height: '300px', + minHeight: '200px', + language: 'en_US', + useDefaultHTMLSanitizer: true, + useCommandShortcut: true, + codeBlockLanguages: _codeBlockManager.CodeBlockManager.getHighlightJSLanguages(), + usageStatistics: true, + toolbarItems: ['heading', 'bold', 'italic', 'strike', 'divider', 'hr', 'quote', 'divider', 'ul', 'ol', 'task', 'indent', 'outdent', 'divider', 'table', 'image', 'link', 'divider', 'code', 'codeblock'], + hideModeSwitch: false, + customConvertor: null + }, options); + + this.eventManager = new _eventManager2.default(); + + this.importManager = new _importManager2.default(this.eventManager); + + this.commandManager = new _commandManager3.default(this, { + useCommandShortcut: this.options.useCommandShortcut + }); + + if (this.options.customConvertor) { + // eslint-disable-next-line new-cap + this.convertor = new this.options.customConvertor(this.eventManager); + } else { + this.convertor = new _convertor2.default(this.eventManager); + } + + if (this.options.useDefaultHTMLSanitizer) { + this.convertor.initHtmlSanitizer(); + } + + if (this.options.hooks) { + _tuiCodeSnippet2.default.forEach(this.options.hooks, function (fn, key) { + return _this.addHook(key, fn); + }); + } + + if (this.options.events) { + _tuiCodeSnippet2.default.forEach(this.options.events, function (fn, key) { + return _this.on(key, fn); + }); + } + + this.layout = new _layout2.default(options, this.eventManager); + + this.i18n = _i18n2.default; + this.i18n.setCode(this.options.language); + + this.setUI(this.options.UI || new _defaultUI2.default(this)); + + this.mdEditor = _markdownEditor2.default.factory(this.layout.getMdEditorContainerEl(), this.eventManager); + this.preview = new _mdPreview2.default(this.layout.getPreviewEl(), this.eventManager, this.convertor); + this.wwEditor = _wysiwygEditor2.default.factory(this.layout.getWwEditorContainerEl(), this.eventManager); + this.toMarkOptions = null; + + this.changePreviewStyle(this.options.previewStyle); + + this.changeMode(this.options.initialEditType, true); + + this.minHeight(this.options.minHeight); + + this.height(this.options.height); + + this.setValue(this.options.initialValue, false); + + if (!this.options.initialValue) { + this.setHtml(this.initialHtml, false); + } + + _extManager2.default.applyExtension(this, this.options.exts); + + this.eventManager.emit('load', this); + + __nedInstance.push(this); + + this._addDefaultCommands(); + + if (this.options.usageStatistics) { + _tuiCodeSnippet2.default.sendHostname('editor', gaTrackingId); + } + } + + /** + * change preview style + * @memberof ToastUIEditor + * @param {string} style - 'tab'|'vertical' + */ + + + _createClass(ToastUIEditor, [{ + key: 'changePreviewStyle', + value: function changePreviewStyle(style) { + this.layout.changePreviewStyle(style); + this.mdPreviewStyle = style; + this.eventManager.emit('changePreviewStyle', style); + this.eventManager.emit('previewNeedsRefresh'); + } + + /** + * call commandManager's exec method + * @memberof ToastUIEditor + * @param {*} ...args Command argument + */ + + }, { + key: 'exec', + value: function exec() { + var _commandManager; + + (_commandManager = this.commandManager).exec.apply(_commandManager, arguments); + } + + /** + * add default commands + * @memberof ToastUIEditor + * @private + */ + + }, { + key: '_addDefaultCommands', + value: function _addDefaultCommands() { + this.addCommand(_bold2.default); + this.addCommand(_italic2.default); + this.addCommand(_blockquote2.default); + this.addCommand(_heading2.default); + this.addCommand(_paragraph2.default); + this.addCommand(_hr2.default); + this.addCommand(_addLink2.default); + this.addCommand(_addImage2.default); + this.addCommand(_ul2.default); + this.addCommand(_ol2.default); + this.addCommand(_indent2.default); + this.addCommand(_outdent2.default); + this.addCommand(_table2.default); + this.addCommand(_task2.default); + this.addCommand(_code2.default); + this.addCommand(_codeBlock2.default); + this.addCommand(_strike2.default); + + this.addCommand(_bold4.default); + this.addCommand(_italic4.default); + this.addCommand(_blockquote4.default); + this.addCommand(_ul4.default); + this.addCommand(_ol4.default); + this.addCommand(_addImage4.default); + this.addCommand(_addLink4.default); + this.addCommand(_hr4.default); + this.addCommand(_heading4.default); + this.addCommand(_paragraph4.default); + this.addCommand(_indent4.default); + this.addCommand(_outdent4.default); + this.addCommand(_task4.default); + this.addCommand(_table4.default); + this.addCommand(_tableAddRow2.default); + this.addCommand(_tableAddCol2.default); + this.addCommand(_tableRemoveRow2.default); + this.addCommand(_tableRemoveCol2.default); + this.addCommand(_tableAlignCol2.default); + this.addCommand(_tableRemove2.default); + this.addCommand(_code4.default); + this.addCommand(_codeBlock4.default); + this.addCommand(_strike4.default); + } + }, { + key: 'addCommand', + value: function addCommand(type, props) { + if (!props) { + this.commandManager.addCommand(type); + } else { + this.commandManager.addCommand(_commandManager3.default.command(type, props)); + } + } + + /** + * After added command. + */ + + }, { + key: 'afterAddedCommand', + value: function afterAddedCommand() { + this.eventManager.emit('afterAddedCommand', this); + } + + /** + * Bind eventHandler to event type + * @memberof ToastUIEditor + * @param {string} type Event type + * @param {function} handler Event handler + */ + + }, { + key: 'on', + value: function on(type, handler) { + this.eventManager.listen(type, handler); + } + + /** + * Unbind eventHandler from event type + * @memberof ToastUIEditor + * @param {string} type Event type + */ + + }, { + key: 'off', + value: function off(type) { + this.eventManager.removeEventHandler(type); + } + + /** + * Add hook to TUIEditor event + * @memberof ToastUIEditor + * @param {string} type Event type + * @param {function} handler Event handler + */ + + }, { + key: 'addHook', + value: function addHook(type, handler) { + this.eventManager.removeEventHandler(type); + this.eventManager.listen(type, handler); + } + + /** + * Remove hook from TUIEditor event + * @memberof ToastUIEditor + * @param {string} type Event type + */ + + }, { + key: 'removeHook', + value: function removeHook(type) { + this.eventManager.removeEventHandler(type); + } + + /** + * Get CodeMirror instance + * @memberof ToastUIEditor + * @returns {CodeMirror} + */ + + }, { + key: 'getCodeMirror', + value: function getCodeMirror() { + return this.mdEditor.getEditor(); + } + + /** + * Get SquireExt instance + * @memberof ToastUIEditor + * @returns {SquireExt} + */ + + }, { + key: 'getSquire', + value: function getSquire() { + return this.wwEditor.getEditor(); + } + + /** + * Set focus to current Editor + * @memberof ToastUIEditor + */ + + }, { + key: 'focus', + value: function focus() { + this.getCurrentModeEditor().focus(); + } + + /** + * Remove focus of current Editor + * @memberof ToastUIEditor + */ + + }, { + key: 'blur', + value: function blur() { + this.getCurrentModeEditor().blur(); + } + + /** + * Set cursor position to end + * @memberof ToastUIEditor + */ + + }, { + key: 'moveCursorToEnd', + value: function moveCursorToEnd() { + this.getCurrentModeEditor().moveCursorToEnd(); + } + + /** + * Set cursor position to start + * @memberof ToastUIEditor + */ + + }, { + key: 'moveCursorToStart', + value: function moveCursorToStart() { + this.getCurrentModeEditor().moveCursorToStart(); + } + + /** + * Set markdown syntax text. + * @memberof ToastUIEditor + * @param {string} markdown - markdown syntax text. + * @param {boolean} [cursorToEnd=true] - move cursor to contents end + */ + + }, { + key: 'setMarkdown', + value: function setMarkdown(markdown) { + var cursorToEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + markdown = markdown || ''; + + if (this.isMarkdownMode()) { + this.mdEditor.setValue(markdown, cursorToEnd); + } else { + this.wwEditor.setValue(this.convertor.toHTML(markdown), cursorToEnd); + } + + this.eventManager.emit('setMarkdownAfter', markdown); + } + + /** + * Set html value. + * @memberof ToastUIEditor + * @param {string} html - html syntax text + * @param {boolean} [cursorToEnd=true] - move cursor to contents end + */ + + }, { + key: 'setHtml', + value: function setHtml(html) { + var cursorToEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + html = html || ''; + this.wwEditor.setValue(html, cursorToEnd); + + if (this.isMarkdownMode()) { + var markdown = this.convertor.toMarkdown(this.wwEditor.getValue(), this.toMarkOptions); + this.mdEditor.setValue(markdown, cursorToEnd); + this.eventManager.emit('setMarkdownAfter', markdown); + } + } + + /** + * Set markdown syntax text. + * @memberof ToastUIEditor + * @param {string} value - markdown syntax text + * @param {boolean} [cursorToEnd=true] - move cursor to contents end + * @deprecated + */ + + }, { + key: 'setValue', + value: function setValue(value) { + var cursorToEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + this.setMarkdown(value, cursorToEnd); + } + + /** + * Get markdown syntax text. + * @memberof ToastUIEditor + * @returns {string} + */ + + }, { + key: 'getMarkdown', + value: function getMarkdown() { + var markdown = void 0; + + if (this.isMarkdownMode()) { + markdown = this.mdEditor.getValue(); + } else { + markdown = this.convertor.toMarkdown(this.wwEditor.getValue(), this.toMarkOptions); + } + + return markdown; + } + + /** + * Get html syntax text. + * @memberof ToastUIEditor + * @returns {string} + */ + + }, { + key: 'getHtml', + value: function getHtml() { + if (this.isWysiwygMode()) { + this.mdEditor.setValue(this.convertor.toMarkdown(this.wwEditor.getValue(), this.toMarkOptions)); + } + + return this.convertor.toHTML(this.mdEditor.getValue()); + } + + /** + * Get editor value. + * @memberof ToastUIEditor + * @returns {string} + * @deprecated + */ + + }, { + key: 'getValue', + value: function getValue() { + return this.getMarkdown(); + } + + /** + * insert text + * @param {string} text - text string to insert + * @memberof ToastUIEditor + */ + + }, { + key: 'insertText', + value: function insertText(text) { + if (this.isMarkdownMode()) { + this.mdEditor.replaceSelection(text); + } else { + this.wwEditor.insertText(text); + } + } + + /** + * Add widget to selection + * @memberof ToastUIEditor + * @param {Range} selection Current selection + * @param {Node} node widget node + * @param {string} style Adding style "over" or "bottom" + * @param {number} [offset] Offset for adjust position + */ + + }, { + key: 'addWidget', + value: function addWidget(selection, node, style, offset) { + this.getCurrentModeEditor().addWidget(selection, node, style, offset); + } + + /** + * Set and return edithr height + * @memberof ToastUIEditor + * @param {string} height - editor height + * @returns {string} editor height + */ + + }, { + key: 'height', + value: function height(_height) { + if (_tuiCodeSnippet2.default.isExisty(_height)) { + if (_height === 'auto') { + (0, _jquery2.default)(this.options.el).addClass('auto-height'); + this.minHeight(this.minHeight()); + } else { + (0, _jquery2.default)(this.options.el).removeClass('auto-height'); + this.minHeight(_height); + } + if (_tuiCodeSnippet2.default.isNumber(_height)) { + _height = _height + 'px'; + } + + this.options.el.style.height = _height; + this._height = _height; + } + + return this._height; + } + + /** + * Set / Get min content height + * @param {string} minHeight - min content height in pixel + * @memberof ToastUIEditor + * @returns {string} - min height in pixel + */ + + }, { + key: 'minHeight', + value: function minHeight(_minHeight) { + if (_tuiCodeSnippet2.default.isExisty(_minHeight)) { + var editorHeight = this._ui.getEditorHeight(); + var editorSectionHeight = this._ui.getEditorSectionHeight(); + var diffHeight = editorHeight - editorSectionHeight; + this._minHeight = _minHeight; + + _minHeight = parseInt(_minHeight, 10); + _minHeight = Math.max(_minHeight - diffHeight, 0); + + this.wwEditor.setMinHeight(_minHeight); + this.mdEditor.setMinHeight(_minHeight); + this.preview.setMinHeight(_minHeight); + } + + return this._minHeight; + } + + /** + * Get current editor mode name + * @memberof ToastUIEditor + * @returns {Object} mdEditor or wwEditor + */ + + }, { + key: 'getCurrentModeEditor', + value: function getCurrentModeEditor() { + var editor = void 0; + + if (this.isMarkdownMode()) { + editor = this.mdEditor; + } else { + editor = this.wwEditor; + } + + return editor; + } + + /** + * Return true if current editor mode is Markdown + * @memberof ToastUIEditor + * @returns {boolean} + */ + + }, { + key: 'isMarkdownMode', + value: function isMarkdownMode() { + return this.currentMode === 'markdown'; + } + + /** + * Return true if current editor mode is WYSIWYG + * @memberof ToastUIEditor + * @returns {boolean} + */ + + }, { + key: 'isWysiwygMode', + value: function isWysiwygMode() { + return this.currentMode === 'wysiwyg'; + } + + /** + * Return false + * @memberof ToastUIEditor + * @returns {boolean} + */ + + }, { + key: 'isViewer', + value: function isViewer() { + return false; + } + + /** + * Get current Markdown editor's preview style + * @memberof ToastUIEditor + * @returns {string} + */ + + }, { + key: 'getCurrentPreviewStyle', + value: function getCurrentPreviewStyle() { + return this.mdPreviewStyle; + } + + /** + * Change editor's mode to given mode string + * @memberof ToastUIEditor + * @param {string} mode - Editor mode name of want to change + * @param {boolean} [isWithoutFocus] - Change mode without focus + */ + + }, { + key: 'changeMode', + value: function changeMode(mode, isWithoutFocus) { + if (this.currentMode === mode) { + return; + } + + this.eventManager.emit('changeModeBefore', this.currentMode); + + this.currentMode = mode; + + if (this.isWysiwygMode()) { + this.layout.switchToWYSIWYG(); + this.wwEditor.setValue(this.convertor.toHTML(this.mdEditor.getValue()), !isWithoutFocus); + this.eventManager.emit('changeModeToWysiwyg'); + } else { + this.layout.switchToMarkdown(); + this.mdEditor.resetState(); + this.mdEditor.setValue(this.convertor.toMarkdown(this.wwEditor.getValue(), this.toMarkOptions), !isWithoutFocus); + this.getCodeMirror().refresh(); + this.eventManager.emit('changeModeToMarkdown'); + } + + this.eventManager.emit('changeMode', mode); + + if (!isWithoutFocus) { + this.focus(); + } + } + + /** + * Remove TUIEditor from document + * @memberof ToastUIEditor + */ + + }, { + key: 'remove', + value: function remove() { + var self = this; + var i = __nedInstance.length - 1; + this.wwEditor.remove(); + this.mdEditor.remove(); + this.layout.remove(); + + if (this.getUI()) { + this.getUI().remove(); + } + + this.eventManager.emit('removeEditor'); + this.eventManager.events.forEach(function (value, key) { + self.off(key); + }); + this.eventManager = null; + + for (; i >= 0; i -= 1) { + if (__nedInstance[i] === this) { + __nedInstance.splice(i, 1); + } + } + } + + /** + * Hide TUIEditor + * @memberof ToastUIEditor + */ + + }, { + key: 'hide', + value: function hide() { + this.eventManager.emit('hide', this); + } + + /** + * Show TUIEditor + * @memberof ToastUIEditor + */ + + }, { + key: 'show', + value: function show() { + this.eventManager.emit('show', this); + this.getCodeMirror().refresh(); + } + + /** + * Scroll Editor content to Top + * @memberof ToastUIEditor + * @param {number} value Scroll amount + * @returns {number} + */ + + }, { + key: 'scrollTop', + value: function scrollTop(value) { + return this.getCurrentModeEditor().scrollTop(value); + } + + /** + * Set UI to private UI property + * @memberof ToastUIEditor + * @param {UI} UI UI instance + */ + + }, { + key: 'setUI', + value: function setUI(UI) { + this._ui = UI; + } + + /** + * Get _ui property + * @memberof ToastUIEditor + * @returns {UI} + */ + + }, { + key: 'getUI', + value: function getUI() { + return this._ui; + } + + /** + * Reset TUIEditor + * @memberof ToastUIEditor + */ + + }, { + key: 'reset', + value: function reset() { + this.wwEditor.reset(); + this.mdEditor.reset(); + } + + /** + * Get current range + * @memberof ToastUIEditor + * @returns {{start, end}|Range} + */ + + }, { + key: 'getRange', + value: function getRange() { + return this.getCurrentModeEditor().getRange(); + } + + /** + * Get text object of current range + * @memberof ToastUIEditor + * @param {{start, end}|Range} range Range object of each editor + * @returns {object} TextObject class + */ + + }, { + key: 'getTextObject', + value: function getTextObject(range) { + return this.getCurrentModeEditor().getTextObject(range); + } + + /** + * get selected text + * @returns {string} - selected text + * @memberof ToastUIEditor + */ + + }, { + key: 'getSelectedText', + value: function getSelectedText() { + var range = this.getRange(); + var textObject = this.getTextObject(range); + + return textObject.getTextContent() || ''; + } + + /** + * Get instance of TUIEditor + * @memberof ToastUIEditor + * @returns {Array} + */ + + }], [{ + key: 'getInstances', + value: function getInstances() { + return __nedInstance; + } + + /** + * Define extension + * @memberof ToastUIEditor + * @param {string} name Extension name + * @param {ExtManager~extension} ext extension + */ + + }, { + key: 'defineExtension', + value: function defineExtension(name, ext) { + _extManager2.default.defineExtension(name, ext); + } + + /** + * Factory method for Editor + * @memberof ToastUIEditor + * @param {object} options Option for initialize TUIEditor + * @returns {object} ToastUIEditor or ToastUIEditorViewer + */ + + }, { + key: 'factory', + value: function factory(options) { + var tuiEditor = void 0; + + if (options.viewer) { + tuiEditor = new _viewer2.default(options); + } else { + tuiEditor = new ToastUIEditor(options); + } + + return tuiEditor; + } + }]); + + return ToastUIEditor; +}(); + +/** + * check whther is viewer + * @type {boolean} + */ + + +ToastUIEditor.isViewer = false; + +/** + * I18n instance + * @type {I18n} + */ +ToastUIEditor.i18n = _i18n2.default; + +/** + * domUtil instance + * @type {DomUtil} + */ +ToastUIEditor.domUtils = _domUtils2.default; + +/** + * CodeBlockManager instance + * @type {CodeBlockManager} + */ +ToastUIEditor.codeBlockManager = _codeBlockManager2.default; + +/** + * Button class + * @type {Class.'); + } + this.$el.html(tabButtons.join('')); + this.activate(initName); + } + + /** + * activate + * Activate Section & Button + * @param {string} name button name to activate + */ + + }, { + key: 'activate', + value: function activate(name) { + var $button = this.$el.find('button:contains("' + name + '")'); + this._activateTabByButton($button); + } + }, { + key: '_onTabButton', + value: function _onTabButton(ev) { + var $button = (0, _jquery2.default)(ev.target); + this._activateTabByButton($button); + this.trigger('itemClick', $button.text()); + } + }, { + key: '_activateTabByButton', + value: function _activateTabByButton($button) { + if (this._isActivatedButton($button)) { + return; + } + + this._updateClassByButton($button); + } + }, { + key: '_updateClassByButton', + value: function _updateClassByButton($activeButton) { + // deactivate previously activated button + if (this._$activeButton) { + var sectionIndex = this._$activeButton.attr('data-index'); + this._$activeButton.removeClass(CLASS_TAB_ACTIVE); + if (this.sections) { + this.sections[sectionIndex].removeClass(CLASS_TAB_ACTIVE); + } + } + + // activate new button + $activeButton.addClass(CLASS_TAB_ACTIVE); + this._$activeButton = $activeButton; + var index = $activeButton.attr('data-index'); + if (this.sections) { + this.sections[index].addClass(CLASS_TAB_ACTIVE); + } + } + }, { + key: '_isActivatedButton', + value: function _isActivatedButton($button) { + return this._$activeButton && this._$activeButton.text() === $button.text(); + } + }]); + + return Tab; +}(_uicontroller2.default); + +exports.default = Tab; + +/***/ }), +/* 47 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Stream; + +var EE = __webpack_require__(25).EventEmitter; +var inherits = __webpack_require__(13); + +inherits(Stream, EE); +Stream.Readable = __webpack_require__(26); +Stream.Writable = __webpack_require__(174); +Stream.Duplex = __webpack_require__(175); +Stream.Transform = __webpack_require__(176); +Stream.PassThrough = __webpack_require__(177); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + + +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + + + +/**/ + +var processNextTick = __webpack_require__(19); +/**/ + +module.exports = Readable; + +/**/ +var isArray = __webpack_require__(49); +/**/ + +/**/ +var Duplex; +/**/ + +Readable.ReadableState = ReadableState; + +/**/ +var EE = __webpack_require__(25).EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream = __webpack_require__(50); +/**/ + +// TODO(bmeurer): Change this back to const once hole checks are +// properly optimized away early in Ignition+TurboFan. +/**/ +var Buffer = __webpack_require__(20).Buffer; +var OurUint8Array = global.Uint8Array || function () {}; +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} +/**/ + +/**/ +var util = __webpack_require__(16); +util.inherits = __webpack_require__(13); +/**/ + +/**/ +var debugUtil = __webpack_require__(168); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var BufferList = __webpack_require__(169); +var destroyImpl = __webpack_require__(52); +var StringDecoder; + +util.inherits(Readable, Stream); + +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } +} + +function ReadableState(options, stream) { + Duplex = Duplex || __webpack_require__(11); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // has it been destroyed + this.destroyed = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = __webpack_require__(53).StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + Duplex = Duplex || __webpack_require__(11); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options) { + if (typeof options.read === 'function') this._read = options.read; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } + + Stream.call(this); +} + +Object.defineProperty(Readable.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined) { + return false; + } + return this._readableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + } +}); + +Readable.prototype.destroy = destroyImpl.destroy; +Readable.prototype._undestroy = destroyImpl.undestroy; +Readable.prototype._destroy = function (err, cb) { + this.push(null); + cb(err); +}; + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + var skipChunkCheck; + + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + skipChunkCheck = true; + } + } else { + skipChunkCheck = true; + } + + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + return readableAddChunk(this, chunk, null, true, false); +}; + +function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + var state = stream._readableState; + if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (addToFront) { + if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); + } else if (state.ended) { + stream.emit('error', new Error('stream.push() after EOF')); + } else { + state.reading = false; + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); + } else { + addChunk(stream, state, chunk, false); + } + } + } else if (!addToFront) { + state.reading = false; + } + } + + return needMoreData(state); +} + +function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + maybeReadMore(stream, state); +} + +function chunkInvalid(state, chunk) { + var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); +} + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = __webpack_require__(53).StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + processNextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('_read() is not implemented')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : unpipe; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable, unpipeInfo) { + debug('onunpipe'); + if (readable === src) { + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', unpipe); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + var unpipeInfo = { hasUnpiped: false }; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this, unpipeInfo); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this, unpipeInfo); + }return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this, unpipeInfo); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + processNextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = Buffer.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12), __webpack_require__(18))) + +/***/ }), +/* 49 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + + +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(25).EventEmitter; + + +/***/ }), +/* 51 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + + + +var base64 = __webpack_require__(166) +var ieee754 = __webpack_require__(167) +var isArray = __webpack_require__(49) + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() + +function typedArraySupport () { + try { + var arr = new Uint8Array(1) + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) + } + that.length = length + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192 // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} + +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0 + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + var actual = that.write(string, encoding) + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual) + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + that = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array) + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array) + } + return that +} + +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len) + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } + } + + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length + } + return buffer +} + +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +function slowToString (encoding, start, end) { + var loweredCase = false + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true + +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) + } + return this +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +} + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start] + } + } + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12))) + +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/**/ + +var processNextTick = __webpack_require__(19); +/**/ + +// undocumented cb() API, needed for core, not for public API +function destroy(err, cb) { + var _this = this; + + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { + processNextTick(emitErrorNT, this, err); + } + return; + } + + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + if (this._readableState) { + this._readableState.destroyed = true; + } + + // if this is a duplex stream mark the writable part as destroyed as well + if (this._writableState) { + this._writableState.destroyed = true; + } + + this._destroy(err || null, function (err) { + if (!cb && err) { + processNextTick(emitErrorNT, _this, err); + if (_this._writableState) { + _this._writableState.errorEmitted = true; + } + } else if (cb) { + cb(err); + } + }); +} + +function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } +} + +function emitErrorNT(self, err) { + self.emit('error', err); +} + +module.exports = { + destroy: destroy, + undestroy: undestroy +}; + +/***/ }), +/* 53 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var Buffer = __webpack_require__(20).Buffer; + +var isEncoding = Buffer.isEncoding || function (encoding) { + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': + return true; + default: + return false; + } +}; + +function _normalizeEncoding(enc) { + if (!enc) return 'utf8'; + var retried; + while (true) { + switch (enc) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return enc; + default: + if (retried) return; // undefined + enc = ('' + enc).toLowerCase(); + retried = true; + } + } +}; + +// Do not cache `Buffer.isEncoding` when checking encoding names as some +// modules monkey-patch it to support additional encodings +function normalizeEncoding(enc) { + var nenc = _normalizeEncoding(enc); + if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); + return nenc || enc; +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. +exports.StringDecoder = StringDecoder; +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + var nb; + switch (this.encoding) { + case 'utf16le': + this.text = utf16Text; + this.end = utf16End; + nb = 4; + break; + case 'utf8': + this.fillLast = utf8FillLast; + nb = 4; + break; + case 'base64': + this.text = base64Text; + this.end = base64End; + nb = 3; + break; + default: + this.write = simpleWrite; + this.end = simpleEnd; + return; + } + this.lastNeed = 0; + this.lastTotal = 0; + this.lastChar = Buffer.allocUnsafe(nb); +} + +StringDecoder.prototype.write = function (buf) { + if (buf.length === 0) return ''; + var r; + var i; + if (this.lastNeed) { + r = this.fillLast(buf); + if (r === undefined) return ''; + i = this.lastNeed; + this.lastNeed = 0; + } else { + i = 0; + } + if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); + return r || ''; +}; + +StringDecoder.prototype.end = utf8End; + +// Returns only complete characters in a Buffer +StringDecoder.prototype.text = utf8Text; + +// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer +StringDecoder.prototype.fillLast = function (buf) { + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); + this.lastNeed -= buf.length; +}; + +// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a +// continuation byte. +function utf8CheckByte(byte) { + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; + return -1; +} + +// Checks at most 3 bytes at the end of a Buffer in order to detect an +// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) +// needed to complete the UTF-8 character (if applicable) are returned. +function utf8CheckIncomplete(self, buf, i) { + var j = buf.length - 1; + if (j < i) return 0; + var nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 1; + return nb; + } + if (--j < i) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 2; + return nb; + } + if (--j < i) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) { + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; + } + return nb; + } + return 0; +} + +// Validates as many continuation bytes for a multi-byte UTF-8 character as +// needed or are available. If we see a non-continuation byte where we expect +// one, we "replace" the validated continuation bytes we've seen so far with +// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding +// behavior. The continuation byte check is included three times in the case +// where all of the continuation bytes for a character exist in the same buffer. +// It is also done this way as a slight performance increase instead of using a +// loop. +function utf8CheckExtraBytes(self, buf, p) { + if ((buf[0] & 0xC0) !== 0x80) { + self.lastNeed = 0; + return '\ufffd'.repeat(p); + } + if (self.lastNeed > 1 && buf.length > 1) { + if ((buf[1] & 0xC0) !== 0x80) { + self.lastNeed = 1; + return '\ufffd'.repeat(p + 1); + } + if (self.lastNeed > 2 && buf.length > 2) { + if ((buf[2] & 0xC0) !== 0x80) { + self.lastNeed = 2; + return '\ufffd'.repeat(p + 2); + } + } + } +} + +// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. +function utf8FillLast(buf) { + var p = this.lastTotal - this.lastNeed; + var r = utf8CheckExtraBytes(this, buf, p); + if (r !== undefined) return r; + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, p, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, p, 0, buf.length); + this.lastNeed -= buf.length; +} + +// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a +// partial character, the character's bytes are buffered until the required +// number of bytes are available. +function utf8Text(buf, i) { + var total = utf8CheckIncomplete(this, buf, i); + if (!this.lastNeed) return buf.toString('utf8', i); + this.lastTotal = total; + var end = buf.length - (total - this.lastNeed); + buf.copy(this.lastChar, 0, end); + return buf.toString('utf8', i, end); +} + +// For UTF-8, a replacement character for each buffered byte of a (partial) +// character needs to be added to the output. +function utf8End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); + return r; +} + +// UTF-16LE typically needs two bytes per character, but even if we have an even +// number of bytes available, we need to check if we end on a leading/high +// surrogate. In that case, we need to wait for the next two bytes in order to +// decode the last character properly. +function utf16Text(buf, i) { + if ((buf.length - i) % 2 === 0) { + var r = buf.toString('utf16le', i); + if (r) { + var c = r.charCodeAt(r.length - 1); + if (c >= 0xD800 && c <= 0xDBFF) { + this.lastNeed = 2; + this.lastTotal = 4; + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + return r.slice(0, -1); + } + } + return r; + } + this.lastNeed = 1; + this.lastTotal = 2; + this.lastChar[0] = buf[buf.length - 1]; + return buf.toString('utf16le', i, buf.length - 1); +} + +// For UTF-16LE we do not explicitly append special replacement characters if we +// end on a partial character, we simply let v8 handle that. +function utf16End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) { + var end = this.lastTotal - this.lastNeed; + return r + this.lastChar.toString('utf16le', 0, end); + } + return r; +} + +function base64Text(buf, i) { + var n = (buf.length - i) % 3; + if (n === 0) return buf.toString('base64', i); + this.lastNeed = 3 - n; + this.lastTotal = 3; + if (n === 1) { + this.lastChar[0] = buf[buf.length - 1]; + } else { + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + } + return buf.toString('base64', i, buf.length - n); +} + +function base64End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); + return r; +} + +// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) +function simpleWrite(buf) { + return buf.toString(this.encoding); +} + +function simpleEnd(buf) { + return buf && buf.length ? this.write(buf) : ''; +} + +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + + + +module.exports = Transform; + +var Duplex = __webpack_require__(11); + +/**/ +var util = __webpack_require__(16); +util.inherits = __webpack_require__(13); +/**/ + +util.inherits(Transform, Duplex); + +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) { + return stream.emit('error', new Error('write callback called multiple times')); + } + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) stream.push(data); + + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(this); + + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); + });else done(stream); + }); +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('_transform() is not implemented'); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +Transform.prototype._destroy = function (err, cb) { + var _this = this; + + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + _this.emit('close'); + }); +}; + +function done(stream, er, data) { + if (er) return stream.emit('error', er); + + if (data !== null && data !== undefined) stream.push(data); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) throw new Error('Calling transform done when ws.length != 0'); + + if (ts.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); +} + +/***/ }), +/* 55 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +__webpack_require__(56); + +__webpack_require__(179); + +__webpack_require__(182); + +__webpack_require__(197); + +__webpack_require__(199); + +/** + * @fileoverview entry point for editor with all extension included + * @author NHN Ent. FE Development Lab + */ +var Editor = __webpack_require__(201); + +module.exports = Editor; + +/***/ }), +/* 56 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setDefaultOptions = exports.detectDelimiter = exports.parseDSV2ChartData = exports.parseCode2ChartOption = exports.parseURL2ChartData = exports.parseCode2DataAndOptions = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _tuiChart = __webpack_require__(57); + +var _tuiChart2 = _interopRequireDefault(_tuiChart); + +var _editorProxy = __webpack_require__(5); + +var _editorProxy2 = _interopRequireDefault(_editorProxy); + +var _csv = __webpack_require__(165); + +var _csv2 = _interopRequireDefault(_csv); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview tsv, csv format chart plugin + * consumes tab separated values and make data/options for tui chart + * @author NHN Ent. FE Development Lab + */ + +/** + * @example + * tsv, csv format chart plugin + * consumes tab separated values and make data/options for tui-chart + * + * ```chart + * \tcat1\tcat2 => tsv, csv format chart data + * jan\t21\t23 + * feb\t351\t45 + * => space required as a separator + * type: area => tui.chart.areaChart() + * url: http://url.to/csv => fetch data from the url + * width: 700 => chart.width + * height: 300 => chart.height + * title: Monthly Revenue => chart.title + * format: 1000 => chart.format + * x.title: Amount => xAxis.title + * x.min: 0 => xAxis.min + * x.max 9000 => xAxis.max + * x.suffix: $ => xAxis.suffix + * y.title: Month => yAxis.title + * ``` + */ + + +var WwCodeBlockManager = _editorProxy2.default.WwCodeBlockManager, + codeBlockManager = _editorProxy2.default.codeBlockManager; + +var LANG = 'chart'; + +// csv configuration +_csv2.default.IGNORE_QUOTE_WHITESPACE = false; +_csv2.default.IGNORE_RECORD_LENGTH = true; +_csv2.default.DETECT_TYPES = false; + +var REGEX_LINE_ENDING = /[\n\r]/; +var DSV_DELIMITERS = [',', '\t', /\s+/]; +var OPTION_DELIMITER = ':'; +var SUPPORTED_CHART_TYPES = ['barChart', 'columnChart', 'lineChart', 'areaChart', 'pieChart']; +var CATEGORY_CHART_TYPES = ['lineChart', 'areaChart']; +var DEFAULT_CHART_OPTIONS = { + minWidth: 0, + maxWidth: Infinity, + minHeight: 0, + maxHeight: Infinity, + height: 'auto', + width: 'auto' +}; + +/** + * parse data and options for tui.chart + * data format can be csv, tsv + * options format is colon separated keys & values + * @param {string} code - plain text format data & options + * @param {Function} callback - callback which provides json format data & options + * @ignore + */ +function parseCode2DataAndOptions(code, callback) { + code = trimKeepingTabs(code); + + var _code$split = code.split(/\n{2,}/), + firstCode = _code$split[0], + secondCode = _code$split[1]; + + // try to parse first code block as `options` + + + var options = parseCode2ChartOption(firstCode); + var url = options && options.editorChart && options.editorChart.url; + + // if first code block is `options` and has `url` option, fetch data from url + var dataAndOptions = void 0; + if (_tuiCodeSnippet2.default.isString(url)) { + // url option provided + // fetch data from url + var success = function success(dataCode) { + dataAndOptions = _parseCode2DataAndOptions(dataCode, firstCode); + callback(dataAndOptions); + }; + var fail = function fail() { + return callback(null); + }; + + _jquery2.default.get(url).done(success).fail(fail); + } else { + // else first block is `data` + dataAndOptions = _parseCode2DataAndOptions(firstCode, secondCode); + callback(dataAndOptions); + } +} + +/** + * parse codes to chart data & options Object + * @param {string} dataCode - code block containing chart data + * @param {string} optionCode - code block containing chart options + * @returns {Object} - tui.chart data & options + * @see https://nhnent.github.io/tui.chart/latest/tui.chart.html + * @ignore + */ +function _parseCode2DataAndOptions(dataCode, optionCode) { + var data = parseDSV2ChartData(dataCode); + var options = parseCode2ChartOption(optionCode); + + return { + data: data, + options: options + }; +} + +/** + * detect delimiter the comma, tab, regex + * @param {string} code - code to detect delimiter + * @returns {string|RegExp} - detected delimiter + * @ignore + */ +function detectDelimiter(code) { + code = trimKeepingTabs(code); + + // chunk first max 10 lines to detect + var chunk = code.split(REGEX_LINE_ENDING).slice(0, 10).join('\n'); + + // calc delta for each delimiters + // then pick a delimiter having the minimum value delta + return DSV_DELIMITERS.map(function (delimiter) { + return { + delimiter: delimiter, + delta: calcDSVDelta(chunk, delimiter) + }; + }).sort(function (a, b) { + return a.delta - b.delta; + })[0].delimiter; +} + +/** + * calculate delta(sum of length difference of rows) values of given DSV + * @param {string} code - code to be test + * @param {string|RegExp} delimiter - delimiter to test + * @returns {number} delta value for code + * @ignore + */ +function calcDSVDelta(code, delimiter) { + var rows = void 0, + delta = void 0; + + try { + _csv2.default.COLUMN_SEPARATOR = delimiter; + rows = _csv2.default.parse(code); + + if (rows[0].length < 2) { + // parsing completely failed + throw new Error('parser fail'); + } + + // sum of all length difference of all rows + delta = rows.map(function (row) { + return row.length; + }).reduce(function (a, b) { + return { + deltaSum: a.deltaSum + Math.abs(a.length - b), + length: b + }; + }, { + deltaSum: 0, + length: rows[0].length + }).deltaSum; + } catch (e) { + delta = Infinity; + } + + return delta; +} + +/** + * parse csv, tsv to chart data + * @param {string} code - data code + * @param {string|RegExp} delimiter - delimiter + * @returns {Object} - tui.chart data + * @see https://nhnent.github.io/tui.chart/latest/tui.chart.html + * @ignore + */ +function parseDSV2ChartData(code, delimiter) { + // trim all heading/trailing blank lines + code = trimKeepingTabs(code); + + _csv2.default.COLUMN_SEPARATOR = delimiter || detectDelimiter(code); + var dsv = _csv2.default.parse(code); + + // trim all values in 2D array + dsv = dsv.map(function (arr) { + return arr.map(function (val) { + return val.trim(); + }); + }); + + // test a first row for legends. ['anything', '1', '2', '3'] === false, ['anything', 't1', '2', 't3'] === true + var hasLegends = dsv[0].filter(function (v, i) { + return i > 0; + }).reduce(function (hasNaN, item) { + return hasNaN || !isNumeric(item); + }, false); + var legends = hasLegends ? dsv.shift() : []; + + // test a first column for categories + var hasCategories = dsv.slice(1).reduce(function (hasNaN, row) { + return hasNaN || !isNumeric(row[0]); + }, false); + var categories = hasCategories ? dsv.map(function (arr) { + return arr.shift(); + }) : []; + if (hasCategories) { + legends.shift(); + } + + // transpose dsv, parse number + // [['1','2','3'] [[1,4,7] + // ['4','5','6'] => [2,5,8] + // ['7','8','9']] [3,6,9]] + dsv = dsv[0].map(function (t, i) { + return dsv.map(function (x) { + return parseFloat(x[i]); + }); + }); + + // make series + var series = dsv.map(function (data, i) { + return hasLegends ? { + name: legends[i], + data: data + } : { + data: data + }; + }); + + return { + categories: categories, + series: series + }; +} + +/** + * parse code from url + * @param {string} url - remote csv/tsv file url + * @param {Function} callback - callback function + * @ignore + */ +function parseURL2ChartData(url, callback) { + var success = function success(code) { + var chartData = parseDSV2ChartData(code); + + callback(chartData); + }; + var fail = function fail() { + return callback(null); + }; + + _jquery2.default.get(url).done(success).fail(fail); +} + +/** + * parse option code + * @param {string} optionCode - option code + * @returns {Object} - tui.chart option string + * @see https://nhnent.github.io/tui.chart/latest/tui.chart.html + * @ignore + */ +function parseCode2ChartOption(optionCode) { + var reservedKeys = ['type', 'url']; + var options = {}; + if (_tuiCodeSnippet2.default.isUndefined(optionCode)) { + return options; + } + + var optionLines = optionCode.split(REGEX_LINE_ENDING); + optionLines.forEach(function (line) { + var _line$split = line.split(OPTION_DELIMITER), + keyString = _line$split[0], + values = _line$split.slice(1); + + var value = values.join(OPTION_DELIMITER); + keyString = keyString.trim(); + if (value.length === 0) { + return; + } + + try { + value = JSON.parse(value.trim()); + } catch (e) { + value = value.trim(); + } + + // parse keys + + var _keyString$split = keyString.split('.'), + keys = _keyString$split.slice(0); + + var topKey = keys[0]; + if (_tuiCodeSnippet2.default.inArray(topKey, reservedKeys) >= 0) { + // reserved keys for chart plugin option + keys.unshift('editorChart'); + } else if (keys.length === 1) { + // short names for `chart` + keys.unshift('chart'); + } else if (topKey === 'x' || topKey === 'y') { + // short-handed keys + keys[0] = topKey + 'Axis'; + } + + var option = options; + for (var i = 0; i < keys.length; i += 1) { + var key = keys[i]; + option[key] = option[key] || (keys.length - 1 === i ? value : {}); + option = option[key]; + } + }); + + return options; +} + +/** + * trim whitespace and newlines at head/tail + * it should not trim \t in tsv + * @param {string} code - code to trim + * @returns {string} - trimmed code + * @ignore + */ +function trimKeepingTabs(code) { + return code.replace(/(^(\s*[\n\r])+)|([\n\r]+\s*$)/g, ''); +} + +/** + * test given string is numeric + * @param {string} str - string to be tested + * @returns {boolean} - true for numeric string + * @ignore + */ +function isNumeric(str) { + return !isNaN(str) && isFinite(str); +} + +/** + * set default options + * @param {Object} chartOptions - tui.chart options + * @param {Object} extensionOptions - extension options + * @param {HTMLElement} chartContainer - chart container + * @returns {Object} - options + * @see https://nhnent.github.io/tui.chart/latest/tui.chart.html + * @ignore + */ +function setDefaultOptions(chartOptions, extensionOptions, chartContainer) { + // chart options scaffolding + chartOptions = _tuiCodeSnippet2.default.extend({ + editorChart: {}, + chart: {}, + chartExportMenu: {}, + usageStatistics: extensionOptions.usageStatistics + }, chartOptions); + + // set default extension options + extensionOptions = _tuiCodeSnippet2.default.extend(DEFAULT_CHART_OPTIONS, extensionOptions); + + // determine width, height + var _chartOptions$chart = chartOptions.chart, + width = _chartOptions$chart.width, + height = _chartOptions$chart.height; + + var isWidthUndefined = _tuiCodeSnippet2.default.isUndefined(width); + var isHeightUndefined = _tuiCodeSnippet2.default.isUndefined(height); + if (isWidthUndefined || isHeightUndefined) { + // if no width or height specified, set width and height to container width + var _chartContainer$getBo = chartContainer.getBoundingClientRect(), + containerWidth = _chartContainer$getBo.width; + + width = isWidthUndefined ? extensionOptions.width : width; + height = isHeightUndefined ? extensionOptions.height : height; + width = width === 'auto' ? containerWidth : width; + height = height === 'auto' ? containerWidth : height; + } + width = Math.min(extensionOptions.maxWidth, width); + height = Math.min(extensionOptions.maxHeight, height); + chartOptions.chart.width = Math.max(extensionOptions.minWidth, width); + chartOptions.chart.height = Math.max(extensionOptions.minHeight, height); + + // default chart type + chartOptions.editorChart.type = chartOptions.editorChart.type ? chartOptions.editorChart.type + 'Chart' : 'columnChart'; + // default visibility of export menu + chartOptions.chartExportMenu.visible = chartOptions.chartExportMenu.visible || false; + + return chartOptions; +} + +/** + * replace html from chart data + * @param {string} codeBlockChartDataAndOptions - chart data text + * @param {Object} extensionOptions - chart extension options + * @returns {string} - rendered html + * @ignore + */ +function chartReplacer(codeBlockChartDataAndOptions, extensionOptions) { + var randomId = 'chart-' + Math.random().toString(36).substr(2, 10); + var renderedHTML = '
    '; + + setTimeout(function () { + var chartContainer = document.querySelector('#' + randomId); + try { + parseCode2DataAndOptions(codeBlockChartDataAndOptions, function (_ref) { + var data = _ref.data, + chartOptions = _ref.options; + + chartOptions = setDefaultOptions(chartOptions, extensionOptions, chartContainer); + + var chartType = chartOptions.editorChart.type; + if (SUPPORTED_CHART_TYPES.indexOf(chartType) < 0) { + chartContainer.innerHTML = 'invalid chart type. type: bar, column, line, area, pie'; + } else if (CATEGORY_CHART_TYPES.indexOf(chartType) > -1 && data.categories.length !== data.series[0].data.length) { + chartContainer.innerHTML = 'invalid chart data'; + } else { + _tuiChart2.default[chartType](chartContainer, data, chartOptions); + } + }); + } catch (e) { + chartContainer.innerHTML = 'invalid chart data'; + } + }, 0); + + return renderedHTML; +} + +/** + * reduce 2D array to TSV rows + * @param {Array.>} arr - 2d array + * @returns {Array.} - TSV row array + * @ignore + */ +function _reduceToTSV(arr) { + // 2D array => quoted TSV row array + // [['a', 'b b'], [1, 2]] => ['a\t"b b"', '1\t2'] + return arr.reduce(function (acc, row) { + // ['a', 'b b', 'c c'] => ['a', '"b b"', '"c c"'] + var quoted = row.map(function (text) { + if (!isNumeric(text) && text.indexOf(' ') >= 0) { + text = '"' + text + '"'; + } + + return text; + }); + // ['a', '"b b"', '"c c"'] => 'a\t"b b"\t"c c"' + acc.push(quoted.join('\t')); + + return acc; + }, []); +} + +/** + * override WwCodeBlockManager to enclose pasting data strings from wysiwyg in quotes + * @param {Editor} editor - editor + * @ignore + */ +function _setWwCodeBlockManagerForChart(editor) { + var componentManager = editor.wwEditor.componentManager; + componentManager.removeManager('codeblock'); + componentManager.addManager(function (_WwCodeBlockManager) { + _inherits(_class, _WwCodeBlockManager); + + function _class() { + _classCallCheck(this, _class); + + return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); + } + + _createClass(_class, [{ + key: 'convertNodesToText', + + /** + * Convert table nodes into code block as TSV + * @memberof WwCodeBlockManager + * @param {Array.} nodes Node array + * @returns {HTMLElement} Code block element + */ + value: function convertNodesToText(nodes) { + if (nodes.length !== 1 || nodes[0].tagName !== 'TABLE') { + return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'convertNodesToText', this).call(this, nodes); + } + + var node = nodes.shift(); + var str = ''; + + // convert table to 2-dim array + var cells = [].slice.call(node.rows).map(function (row) { + return [].slice.call(row.cells).map(function (cell) { + return cell.innerText.trim(); + }); + }); + + var tsvRows = _reduceToTSV(cells); + str += tsvRows.reduce(function (acc, row) { + return acc + (row + '\n'); + }, []); + + return str; + } + }]); + + return _class; + }(WwCodeBlockManager)); +} + +/** + * determine the event is from codeblock in markdown/codeblock editor + * @param {CodeMirror} cm - markdown codemirror editor + * @param {string} source - event source + * @param {Object} eventData - event data + * @returns {boolean} - true for the event from codeblock in markdown/codeblock editor + * @ignore + */ +function _isFromCodeBlockInCodeMirror(cm, source, eventData) { + // cursor in codeblock in markdown editor + var fromCodeBlockInCodeMirror = source === 'markdown' && cm.getTokenAt(eventData.from).state.overlay.codeBlock; + // or codeblock editor + fromCodeBlockInCodeMirror = fromCodeBlockInCodeMirror || source === 'codeblock'; + // but not from wysiwyg + fromCodeBlockInCodeMirror = fromCodeBlockInCodeMirror && source !== 'wysiwyg'; + + return fromCodeBlockInCodeMirror; +} + +/** + * enclose pasting data strings from markdown in quotes + * wysiwyg event should be treated separately. + * because pasteBefore event from wysiwyg has been already processed table data to string, + * on the other hand we need a table element + * @param {CodeMirror} cm - markdown codemirror editor + * @param {string} source - event source + * @param {Object} data - event data + * @ignore + */ +function _onMDPasteBefore(cm, _ref2) { + var source = _ref2.source, + eventData = _ref2.data; + + if (!_isFromCodeBlockInCodeMirror(cm, source, eventData)) { + return; + } + + var code = eventData.text.join('\n'); + var delta = calcDSVDelta(code, '\t'); + + if (delta === 0) { + _csv2.default.COLUMN_SEPARATOR = '\t'; + var parsed = _reduceToTSV(_csv2.default.parse(code)); + eventData.update(eventData.from, eventData.to, parsed); + } +} + +/** + * chart plugin + * @param {Editor} editor - editor + * @param {Object} options - chart options + * @param {number} [options.minWidth=0] - minimum width + * @param {number} [options.maxWidth=0] - maximum width + * @param {number} [options.minHeight=Infinity] - minimum height + * @param {number} [options.maxHeight=Infinity] - maximum height + * @param {number|string} [options.width='auto'] - default height + * @param {number|string} [options.height='auto'] - default height + * @ignore + */ +function chartExtension(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var optionLanguages = editor.options.codeBlockLanguages; + if (optionLanguages && optionLanguages.indexOf(LANG) < 0) { + optionLanguages.push(LANG); + } + + options = _tuiCodeSnippet2.default.extend({ + usageStatistics: editor.options.usageStatistics + }, options); + + codeBlockManager.setReplacer(LANG, function (codeBlockChartDataAndOptions) { + return chartReplacer(codeBlockChartDataAndOptions, options); + }); + + if (!editor.isViewer()) { + // treat wysiwyg paste event + _setWwCodeBlockManagerForChart(editor); + + // treat markdown paste event + editor.eventManager.listen('pasteBefore', function (ev) { + return _onMDPasteBefore(editor.mdEditor.cm, ev); + }); + } +} + +_editorProxy2.default.defineExtension('chart', chartExtension); + +exports.parseCode2DataAndOptions = parseCode2DataAndOptions; +exports.parseURL2ChartData = parseURL2ChartData; +exports.parseCode2ChartOption = parseCode2ChartOption; +exports.parseDSV2ChartData = parseDSV2ChartData; +exports.detectDelimiter = detectDelimiter; +exports.setDefaultOptions = setDefaultOptions; + +/***/ }), +/* 57 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_57__; + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _codeMirrorExt = __webpack_require__(30); + +var _codeMirrorExt2 = _interopRequireDefault(_codeMirrorExt); + +var _keyMapper = __webpack_require__(22); + +var _keyMapper2 = _interopRequireDefault(_keyMapper); + +var _mdListManager = __webpack_require__(65); + +var _mdListManager2 = _interopRequireDefault(_mdListManager); + +var _componentManager = __webpack_require__(31); + +var _componentManager2 = _interopRequireDefault(_componentManager); + +var _mdTextObject = __webpack_require__(66); + +var _mdTextObject2 = _interopRequireDefault(_mdTextObject); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements markdown editor + * @author NHN Ent. FE Development Lab + */ + + +var keyMapper = _keyMapper2.default.getSharedInstance(); + +/** + * Class MarkdownEditor + */ + +var MarkdownEditor = function (_CodeMirrorExt) { + _inherits(MarkdownEditor, _CodeMirrorExt); + + /** + * Creates an instance of MarkdownEditor. + * @param {jQuery} $el - container jquery element + * @param {EventManager} eventManager - event manager + * @memberof MarkdownEditor + */ + function MarkdownEditor($el, eventManager) { + _classCallCheck(this, MarkdownEditor); + + var _this = _possibleConstructorReturn(this, (MarkdownEditor.__proto__ || Object.getPrototypeOf(MarkdownEditor)).call(this, $el.get(0), { + mode: 'gfm', + dragDrop: true, + allowDropFileTypes: ['image'], + extraKeys: { + 'Enter': 'newlineAndIndentContinueMarkdownList', + 'Tab': 'indentOrderedList', + 'Shift-Tab': 'indentLessOrderedList' + } + })); + + _this.eventManager = eventManager; + _this.componentManager = new _componentManager2.default(_this); + _this.componentManager.addManager(_mdListManager2.default); + + /** + * latest state info + * @type {object} + * @private + */ + _this._latestState = null; + + _this._initEvent(); + return _this; + } + + /** + * _initEvent + * Initialize EventManager event handler + * @memberof MarkdownEditor + * @private + */ + + + _createClass(MarkdownEditor, [{ + key: '_initEvent', + value: function _initEvent() { + var _this2 = this; + + this.cm.getWrapperElement().addEventListener('click', function () { + _this2.eventManager.emit('click', { + source: 'markdown' + }); + }); + + this.cm.on('beforeChange', function (cm, ev) { + if (ev.origin === 'paste') { + _this2.eventManager.emit('pasteBefore', { + source: 'markdown', + data: ev + }); + } + }); + + this.cm.on('change', function (cm, cmEvent) { + _this2._emitMarkdownEditorContentChangedEvent(); + _this2._emitMarkdownEditorChangeEvent(cmEvent); + }); + + this.cm.on('focus', function () { + _this2.eventManager.emit('focus', { + source: 'markdown' + }); + _this2.getEditor().refresh(); + }); + + this.cm.on('blur', function () { + _this2.eventManager.emit('blur', { + source: 'markdown' + }); + }); + + this.cm.on('scroll', function (cm, eventData) { + _this2.eventManager.emit('scroll', { + source: 'markdown', + data: eventData + }); + }); + + this.cm.on('keydown', function (cm, keyboardEvent) { + _this2.eventManager.emit('keydown', { + source: 'markdown', + data: keyboardEvent + }); + + _this2.eventManager.emit('keyMap', { + source: 'markdown', + keyMap: keyMapper.convert(keyboardEvent), + data: keyboardEvent + }); + }); + + this.cm.on('keyup', function (cm, keyboardEvent) { + _this2.eventManager.emit('keyup', { + source: 'markdown', + data: keyboardEvent + }); + }); + + this.cm.on('copy', function (cm, ev) { + _this2.eventManager.emit('copy', { + source: 'markdown', + data: ev + }); + }); + + this.cm.on('cut', function (cm, ev) { + _this2.eventManager.emit('cut', { + source: 'markdown', + data: ev + }); + }); + + this.cm.on('paste', function (cm, clipboardEvent) { + _this2.eventManager.emit('paste', { + source: 'markdown', + data: clipboardEvent + }); + }); + + this.cm.on('drop', function (cm, eventData) { + eventData.preventDefault(); + + _this2.eventManager.emit('drop', { + source: 'markdown', + data: eventData + }); + }); + + this.cm.on('cursorActivity', function () { + var token = _this2.cm.getTokenAt(_this2.cm.getCursor()); + var base = token.state.base; + + var state = { + bold: !!base.strong, + italic: !!base.em, + strike: !!base.strikethrough, + code: base.code > 0, + codeBlock: base.code === -1, + quote: !!base.quote, + list: !!base.list, + task: !!base.taskList, + source: 'markdown' + }; + + if (!_this2._latestState || _this2._isStateChanged(_this2._latestState, state)) { + _this2.eventManager.emit('stateChange', state); + _this2._latestState = state; + } + }); + } + + /** + * Set Editor value + * @memberof MarkdownEditor + * @override + * @param {string} markdown - Markdown syntax text + * @param {boolean} [cursorToEnd=true] - move cursor to contents end + */ + + }, { + key: 'setValue', + value: function setValue(markdown, cursorToEnd) { + _get(MarkdownEditor.prototype.__proto__ || Object.getPrototypeOf(MarkdownEditor.prototype), 'setValue', this).call(this, markdown, cursorToEnd); + this._emitMarkdownEditorContentChangedEvent(); + } + + /** + * Get text object of current range + * @memberof MarkdownEditor + * @param {{start, end}} range Range object of each editor + * @returns {MdTextObject} + */ + + }, { + key: 'getTextObject', + value: function getTextObject(range) { + return new _mdTextObject2.default(this, range); + } + + /** + * Emit contentChangedFromMarkdown event + * @memberof MarkdownEditor + * @private + */ + + }, { + key: '_emitMarkdownEditorContentChangedEvent', + value: function _emitMarkdownEditorContentChangedEvent() { + this.eventManager.emit('contentChangedFromMarkdown', this); + } + + /** + * Emit changeEvent + * @memberof MarkdownEditor + * @param {event} e - Event object + * @private + */ + + }, { + key: '_emitMarkdownEditorChangeEvent', + value: function _emitMarkdownEditorChangeEvent(e) { + if (e.origin !== 'setValue') { + var eventObj = { + source: 'markdown' + }; + + this.eventManager.emit('changeFromMarkdown', eventObj); + this.eventManager.emit('change', eventObj); + } + } + + /** + * Return whether state changed or not + * @memberof MarkdownEditor + * @param {object} previousState - Previous state + * @param {object} currentState - Current state + * @returns {boolean} - changed state + * @private + */ + + }, { + key: '_isStateChanged', + value: function _isStateChanged(previousState, currentState) { + var result = false; + + _tuiCodeSnippet2.default.forEach(currentState, function (currentStateTypeValue, stateType) { + result = previousState[stateType] !== currentStateTypeValue; + + return !result; + }); + + return result; + } + + /** + * latestState reset + * @memberof MarkdownEditor + */ + + }, { + key: 'resetState', + value: function resetState() { + this._latestState = null; + } + + /** + * MarkdownEditor factory method + * @memberof MarkdownEditor + * @param {jQuery} $el - Container element for editor + * @param {EventManager} eventManager - EventManager instance + * @returns {MarkdownEditor} - MarkdownEditor + */ + + }], [{ + key: 'factory', + value: function factory($el, eventManager) { + var mde = new MarkdownEditor($el, eventManager); + + return mde; + } + }]); + + return MarkdownEditor; +}(_codeMirrorExt2.default); + +exports.default = MarkdownEditor; + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var listRE = /^(\s*)((\d+)([.)]\s(?:\[(?:x|\s)\]\s)?))(.*)/; + +/** + * simple wrapper for indentLess command + * to run fixOrderedListNumber on Shift-Tab + * @param {CodeMirror} cm - CodeMirror instance + * @returns {CodeMirror.Pass|null} - next command + * @ignore + */ +/** +* @fileoverview codemirror extension for fix ordered list number +* @author NHN Ent. FE Development Lab +*/ + +_codemirror2.default.commands.indentLessOrderedList = function (cm) { + if (cm.getOption('disableInput')) { + return _codemirror2.default.Pass; + } + cm.execCommand('indentLess'); + cm.execCommand('fixOrderedListNumber'); + + return null; +}; + +/** + * fix ordered list number + * @param {CodeMirror} cm - CodeMirror instance + * @returns {CodeMirror.Pass|null} - next command + * @ignore + */ +_codemirror2.default.commands.fixOrderedListNumber = function (cm) { + if (cm.getOption('disableInput')) { + return _codemirror2.default.Pass; + } + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i += 1) { + var pos = ranges[i].head; + var lineNumber = findFirstListItem(pos.line, cm); + + if (lineNumber >= 0) { + var lineText = cm.getLine(lineNumber); + + var _listRE$exec = listRE.exec(lineText), + indent = _listRE$exec[1], + index = _listRE$exec[3]; + + fixNumber(lineNumber, indent.length, parseInt(index, 10), cm); + } + } + + return null; +}; + +/** + * fix list numbers + * @param {number} lineNumber - line number of list item to be normalized + * @param {number} prevIndentLength - previous indent length + * @param {number} startIndex - start index + * @param {CodeMirror} cm - CodeMirror instance + * @returns {number} - next line number + * @ignore + */ +function fixNumber(lineNumber, prevIndentLength, startIndex, cm) { + var indent = void 0, + delimiter = void 0, + text = void 0, + indentLength = void 0; + var index = startIndex; + var lineText = cm.getLine(lineNumber); + + do { + var _listRE$exec2 = listRE.exec(lineText); + + indent = _listRE$exec2[1]; + delimiter = _listRE$exec2[4]; + text = _listRE$exec2[5]; + + indentLength = indent.length; + + if (indentLength === prevIndentLength) { + // fix number + cm.replaceRange('' + indent + index + delimiter + text, { + line: lineNumber, + ch: 0 + }, { + line: lineNumber, + ch: lineText.length + }); + index += 1; + lineNumber += 1; + } else if (indentLength > prevIndentLength) { + // nested list start + lineNumber = fixNumber(lineNumber, indentLength, 1, cm); + } else { + // nested list end + return lineNumber; + } + + lineText = cm.getLine(lineNumber); + } while (listRE.test(lineText)); + + return lineNumber; +} + +/** + * find line number of list item which contains given lineNumber + * @param {number} lineNumber - line number of list item + * @param {CodeMirror} cm - CodeMirror instance + * @returns {number} - line number of first list item + * @ignore + */ +function findFirstListItem(lineNumber, cm) { + var nextLineNumber = lineNumber; + var lineText = cm.getLine(lineNumber); + + while (listRE.test(lineText)) { + nextLineNumber -= 1; + lineText = cm.getLine(nextLineNumber); + } + + if (lineNumber === nextLineNumber) { + nextLineNumber = -1; + } else { + nextLineNumber += 1; + } + + return nextLineNumber; +} + +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint-disable */ +_codemirror2.default.overlayMode = function (base, overlay, combine) { + return { + startState: function startState() { + return { + base: _codemirror2.default.startState(base), + overlay: _codemirror2.default.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null, + streamSeen: null + }; + }, + copyState: function copyState(state) { + return { + base: _codemirror2.default.copyState(base, state.base), + overlay: _codemirror2.default.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function token(stream, state) { + if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) { + state.streamSeen = stream; + state.basePos = state.overlayPos = stream.start; + } + + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + + // state.overlay.combineTokens always takes precedence over combine, + // unless set to null + if (state.overlayCur == null) return state.baseCur;else if (state.baseCur != null && state.overlay.combineTokens || combine && state.overlay.combineTokens == null) return state.baseCur + " " + state.overlayCur;else return state.overlayCur; + }, + + indent: base.indent && function (state, textAfter) { + return base.indent(state.base, textAfter); + }, + electricChars: base.electricChars, + + innerMode: function innerMode(state) { + return { state: state.base, mode: base }; + }, + + blankLine: function blankLine(state) { + if (base.blankLine) base.blankLine(state.base); + if (overlay.blankLine) overlay.blankLine(state.overlay); + } + }; +}; // CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Utility function that allows modes to be combined. The mode given +// as the base argument takes care of most of the normal mode +// functionality, but a second (typically simple) mode is used, which +// can override the style of text. Both modes get to parse all of the +// text, but when both assign a non-null style to a piece of code, the +// overlay wins, unless the combine argument was true and not overridden, +// or state.overlay.combineTokens was true, in which case the styles are +// combined. +/** + * @modifier NHN Ent. FE Development Lab + */ + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint-disable */ +_codemirror2.default.defineMode("markdown", function (cmCfg, modeCfg) { + + var htmlMode = _codemirror2.default.getMode(cmCfg, "text/html"); + var htmlModeMissing = htmlMode.name == "null"; + + function getMode(name) { + if (_codemirror2.default.findModeByName) { + var found = _codemirror2.default.findModeByName(name); + if (found) name = found.mime || found.mimes[0]; + } + var mode = _codemirror2.default.getMode(cmCfg, name); + return mode.name == "null" ? null : mode; + } + + // Should characters that affect highlighting be highlighted separate? + // Does not include characters that will be output (such as `1.` and `-` for lists) + if (modeCfg.highlightFormatting === undefined) modeCfg.highlightFormatting = false; + + // Maximum number of nested blockquotes. Set to 0 for infinite nesting. + // Excess `>` will emit `error` token. + if (modeCfg.maxBlockquoteDepth === undefined) modeCfg.maxBlockquoteDepth = 0; + + // Turn on task lists? ("- [ ] " and "- [x] ") + if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; + + // Turn on strikethrough syntax + if (modeCfg.strikethrough === undefined) modeCfg.strikethrough = false; + + if (modeCfg.emoji === undefined) modeCfg.emoji = false; + + if (modeCfg.fencedCodeBlockHighlighting === undefined) modeCfg.fencedCodeBlockHighlighting = true; + + if (modeCfg.xml === undefined) modeCfg.xml = true; + + // Allow token types to be overridden by user-provided token types. + if (modeCfg.tokenTypeOverrides === undefined) modeCfg.tokenTypeOverrides = {}; + + var tokenTypes = { + header: "header", + code: "comment", + quote: "quote", + list1: "variable-2", + list2: "variable-3", + list3: "keyword", + hr: "hr", + image: "image", + imageAltText: "image-alt-text", + imageMarker: "image-marker", + formatting: "formatting", + linkInline: "link", + linkEmail: "link", + linkText: "link", + linkHref: "string", + em: "em", + strong: "strong", + strikethrough: "strikethrough", + emoji: "builtin" + }; + + for (var tokenType in tokenTypes) { + if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { + tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; + } + } + + var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/, + listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/, + taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE + , + atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/, + setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/, + textRE = /^[^#!\[\]*_\\<>` "'(~:]+/, + fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/, + linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition + , + punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~]/, + expandedTab = " "; // CommonMark specifies tab as 4 spaces + + function switchInline(stream, state, f) { + state.f = state.inline = f; + return f(stream, state); + } + + function switchBlock(stream, state, f) { + state.f = state.block = f; + return f(stream, state); + } + + function lineIsEmpty(line) { + return !line || !/\S/.test(line.string); + } + + // Blocks + + function blankLine(state) { + // Reset linkTitle state + state.linkTitle = false; + state.linkHref = false; + state.linkText = false; + // Reset EM state + state.em = false; + // Reset STRONG state + state.strong = false; + // Reset strikethrough state + state.strikethrough = false; + // Reset state.quote + state.quote = 0; + // Reset state.indentedCode + state.indentedCode = false; + if (state.f == htmlBlock) { + var exit = htmlModeMissing; + if (!exit) { + var inner = _codemirror2.default.innerMode(htmlMode, state.htmlState); + exit = inner.mode.name == "xml" && inner.state.tagStart === null && !inner.state.context && inner.state.tokenize.isInText; + } + if (exit) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + // Mark this line as blank + state.prevLine = state.thisLine; + state.thisLine = { stream: null }; + return null; + } + + function blockNormal(stream, state) { + var firstTokenOnLine = stream.column() === state.indentation; + var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream); + var prevLineIsIndentedCode = state.indentedCode; + var prevLineIsHr = state.prevLine.hr; + var prevLineIsList = state.list !== false; + var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3; + + state.indentedCode = false; + + var lineIndentation = state.indentation; + // compute once per line (on first token) + if (state.indentationDiff === null) { + state.indentationDiff = state.indentation; + if (prevLineIsList) { + // Reset inline styles which shouldn't propagate aross list items + state.em = false; + state.strong = false; + state.code = false; + state.strikethrough = false; + + state.list = null; + // While this list item's marker's indentation is less than the deepest + // list item's content's indentation,pop the deepest list item + // indentation off the stack, and update block indentation state + while (lineIndentation < state.listStack[state.listStack.length - 1]) { + state.listStack.pop(); + if (state.listStack.length) { + state.indentation = state.listStack[state.listStack.length - 1]; + // less than the first list's indent -> the line is no longer a list + } else { + state.list = false; + } + } + if (state.list !== false) { + state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]; + } + } + } + + // not comprehensive (currently only for setext detection purposes) + var allowsInlineContinuation = !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header && (!prevLineIsList || !prevLineIsIndentedCode) && !state.prevLine.fencedCodeEnd; + + var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) && state.indentation <= maxNonCodeIndentation && stream.match(hrRE); + + var match = null; + if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd || state.prevLine.header || prevLineLineIsEmpty)) { + stream.skipToEnd(); + state.indentedCode = true; + return tokenTypes.code; + } else if (stream.eatSpace()) { + return null; + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) { + state.quote = 0; + state.header = match[1].length; + state.thisLine.header = true; + if (modeCfg.highlightFormatting) state.formatting = "header"; + state.f = state.inline; + return getType(state); + } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) { + state.quote = firstTokenOnLine ? 1 : state.quote + 1; + if (modeCfg.highlightFormatting) state.formatting = "quote"; + stream.eatSpace(); + return getType(state); + } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) { + var listType = match[1] ? "ol" : "ul"; + + state.indentation = lineIndentation + stream.current().length; + state.list = true; + state.quote = 0; + + // Add this list item's content's indentation to the stack + state.listStack.push(state.indentation); + + if (modeCfg.taskLists && stream.match(taskListRE, false)) { + state.taskList = true; + } + state.f = state.inline; + if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; + return getType(state); + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) { + state.quote = 0; + state.fencedEndRE = new RegExp(match[1] + "+ *$"); + // try switching mode + state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]); + if (state.localMode) state.localState = _codemirror2.default.startState(state.localMode); + state.f = state.block = local; + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + state.code = -1; + return getType(state); + // SETEXT has lowest block-scope precedence after HR, so check it after + // the others (code, blockquote, list...) + } else if ( + // if setext set, indicates line after ---/=== + state.setext || + // line before ---/=== + (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false && !state.code && !isHr && !linkDefRE.test(stream.string) && (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE))) { + if (!state.setext) { + state.header = match[0].charAt(0) == '=' ? 1 : 2; + state.setext = state.header; + } else { + state.header = state.setext; + // has no effect on type so we can reset it now + state.setext = 0; + stream.skipToEnd(); + if (modeCfg.highlightFormatting) state.formatting = "header"; + } + state.thisLine.header = true; + state.f = state.inline; + return getType(state); + } else if (isHr) { + stream.skipToEnd(); + state.hr = true; + state.thisLine.hr = true; + return tokenTypes.hr; + } else if (stream.peek() === '[') { + return switchInline(stream, state, footnoteLink); + } + + return switchInline(stream, state, state.inline); + } + + function htmlBlock(stream, state) { + var style = htmlMode.token(stream, state.htmlState); + if (!htmlModeMissing) { + var inner = _codemirror2.default.innerMode(htmlMode, state.htmlState); + if (inner.mode.name == "xml" && inner.state.tagStart === null && !inner.state.context && inner.state.tokenize.isInText || state.md_inside && stream.current().indexOf(">") > -1) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + return style; + } + + function local(stream, state) { + var currListInd = state.listStack[state.listStack.length - 1] || 0; + var hasExitedList = state.indentation < currListInd; + var maxFencedEndInd = currListInd + 3; + if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) { + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + var returnType; + if (!hasExitedList) returnType = getType(state); + state.localMode = state.localState = null; + state.block = blockNormal; + state.f = inlineNormal; + state.fencedEndRE = null; + state.code = 0; + state.thisLine.fencedCodeEnd = true; + if (hasExitedList) return switchBlock(stream, state, state.block); + return returnType; + } else if (state.localMode) { + return state.localMode.token(stream, state.localState); + } else { + stream.skipToEnd(); + return tokenTypes.code; + } + } + + // Inline + function getType(state) { + var styles = []; + + if (state.formatting) { + styles.push(tokenTypes.formatting); + + if (typeof state.formatting === "string") state.formatting = [state.formatting]; + + for (var i = 0; i < state.formatting.length; i++) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i]); + + if (state.formatting[i] === "header") { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); + } + + // Add `formatting-quote` and `formatting-quote-#` for blockquotes + // Add `error` instead if the maximum blockquote nesting depth is passed + if (state.formatting[i] === "quote") { + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); + } else { + styles.push("error"); + } + } + } + } + + if (state.taskOpen) { + styles.push("meta"); + return styles.length ? styles.join(' ') : null; + } + if (state.taskClosed) { + styles.push("property"); + return styles.length ? styles.join(' ') : null; + } + + if (state.linkHref) { + styles.push(tokenTypes.linkHref, "url"); + } else { + // Only apply inline styles to non-url text + if (state.strong) { + styles.push(tokenTypes.strong); + } + if (state.em) { + styles.push(tokenTypes.em); + } + if (state.strikethrough) { + styles.push(tokenTypes.strikethrough); + } + if (state.emoji) { + styles.push(tokenTypes.emoji); + } + if (state.linkText) { + styles.push(tokenTypes.linkText); + } + if (state.code) { + styles.push(tokenTypes.code); + } + if (state.image) { + styles.push(tokenTypes.image); + } + if (state.imageAltText) { + styles.push(tokenTypes.imageAltText, "link"); + } + if (state.imageMarker) { + styles.push(tokenTypes.imageMarker); + } + } + + if (state.header) { + styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); + } + + if (state.quote) { + styles.push(tokenTypes.quote); + + // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.quote + "-" + state.quote); + } else { + styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); + } + } + + if (state.list !== false) { + var listMod = (state.listStack.length - 1) % 3; + if (!listMod) { + styles.push(tokenTypes.list1); + } else if (listMod === 1) { + styles.push(tokenTypes.list2); + } else { + styles.push(tokenTypes.list3); + } + } + + if (state.trailingSpaceNewLine) { + styles.push("trailing-space-new-line"); + } else if (state.trailingSpace) { + styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); + } + + return styles.length ? styles.join(' ') : null; + } + + function handleText(stream, state) { + if (stream.match(textRE, true)) { + return getType(state); + } + return undefined; + } + + function inlineNormal(stream, state) { + var style = state.text(stream, state); + if (typeof style !== 'undefined') return style; + + if (state.list) { + // List marker (*, +, -, 1., etc) + state.list = null; + return getType(state); + } + + if (state.taskList) { + var taskOpen = stream.match(taskListRE, true)[1] === " "; + if (taskOpen) state.taskOpen = true;else state.taskClosed = true; + if (modeCfg.highlightFormatting) state.formatting = "task"; + state.taskList = false; + return getType(state); + } + + state.taskOpen = false; + state.taskClosed = false; + + if (state.header && stream.match(/^#+$/, true)) { + if (modeCfg.highlightFormatting) state.formatting = "header"; + return getType(state); + } + + var ch = stream.next(); + + // Matches link titles present on next line + if (state.linkTitle) { + state.linkTitle = false; + var matchCh = ch; + if (ch === '(') { + matchCh = ')'; + } + matchCh = (matchCh + '').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1"); + var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; + if (stream.match(new RegExp(regex), true)) { + return tokenTypes.linkHref; + } + } + + // If this block is changed, it may need to be updated in GFM mode + if (ch === '`') { + var previousFormatting = state.formatting; + if (modeCfg.highlightFormatting) state.formatting = "code"; + stream.eatWhile('`'); + var count = stream.current().length; + if (state.code == 0 && (!state.quote || count == 1)) { + state.code = count; + return getType(state); + } else if (count == state.code) { + // Must be exact + var t = getType(state); + state.code = 0; + return t; + } else { + state.formatting = previousFormatting; + return getType(state); + } + } else if (state.code) { + return getType(state); + } + + if (ch === '\\') { + stream.next(); + if (modeCfg.highlightFormatting) { + var type = getType(state); + var formattingEscape = tokenTypes.formatting + "-escape"; + return type ? type + " " + formattingEscape : formattingEscape; + } + } + + if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { + state.imageMarker = true; + state.image = true; + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) { + state.imageMarker = false; + state.imageAltText = true; + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === ']' && state.imageAltText) { + if (modeCfg.highlightFormatting) state.formatting = "image"; + var type = getType(state); + state.imageAltText = false; + state.image = false; + state.inline = state.f = linkHref; + return type; + } + + if (ch === '[' && !state.image) { + if (state.linkText && stream.match(/^.*?\]/)) return getType(state); + state.linkText = true; + if (modeCfg.highlightFormatting) state.formatting = "link"; + return getType(state); + } + + if (ch === ']' && state.linkText) { + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + state.linkText = false; + state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal; + return type; + } + + if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type) { + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type) { + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkEmail; + } + + if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) { + var end = stream.string.indexOf(">", stream.pos); + if (end != -1) { + var atts = stream.string.substring(stream.start, end); + if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; + } + stream.backUp(1); + state.htmlState = _codemirror2.default.startState(htmlMode); + return switchBlock(stream, state, htmlBlock); + } + + if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) { + state.md_inside = false; + return "tag"; + } else if (ch === "*" || ch === "_") { + var len = 1, + before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2); + while (len < 3 && stream.eat(ch)) { + len++; + }var after = stream.peek() || " "; + // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis + var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before)); + var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after)); + var setEm = null, + setStrong = null; + if (len % 2) { + // Em + if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) setEm = true;else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) setEm = false; + } + if (len > 1) { + // Strong + if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) setStrong = true;else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) setStrong = false; + } + if (setStrong != null || setEm != null) { + if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"; + if (setEm === true) state.em = ch; + if (setStrong === true) state.strong = ch; + var t = getType(state); + if (setEm === false) state.em = false; + if (setStrong === false) state.strong = false; + return t; + } + } else if (ch === ' ') { + if (stream.eat('*') || stream.eat('_')) { + // Probably surrounded by spaces + if (stream.peek() === ' ') { + // Surrounded by spaces, ignore + return getType(state); + } else { + // Not surrounded by spaces, back up pointer + stream.backUp(1); + } + } + } + + if (modeCfg.strikethrough) { + if (ch === '~' && stream.eatWhile(ch)) { + if (state.strikethrough) { + // Remove strikethrough + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + var t = getType(state); + state.strikethrough = false; + return t; + } else if (stream.match(/^[^\s]/, false)) { + // Add strikethrough + state.strikethrough = true; + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.match(/^~~/, true)) { + // Probably surrounded by space + if (stream.peek() === ' ') { + // Surrounded by spaces, ignore + return getType(state); + } else { + // Not surrounded by spaces, back up pointer + stream.backUp(2); + } + } + } + } + + if (modeCfg.emoji && ch === ":" && stream.match(/^[a-z_\d+-]+:/)) { + state.emoji = true; + if (modeCfg.highlightFormatting) state.formatting = "emoji"; + var retType = getType(state); + state.emoji = false; + return retType; + } + + if (ch === ' ') { + if (stream.match(/^ +$/, false)) { + state.trailingSpace++; + } else if (state.trailingSpace) { + state.trailingSpaceNewLine = true; + } + } + + return getType(state); + } + + function linkInline(stream, state) { + var ch = stream.next(); + + if (ch === ">") { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type) { + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + stream.match(/^[^>]+/, true); + + return tokenTypes.linkInline; + } + + function linkHref(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if (stream.eatSpace()) { + return null; + } + var ch = stream.next(); + if (ch === '(' || ch === '[') { + state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + state.linkHref = true; + return getType(state); + } + return 'error'; + } + + var linkRE = { + ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, + "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/ + }; + + function getLinkHrefInside(endChar) { + return function (stream, state) { + var ch = stream.next(); + + if (ch === endChar) { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + var returnState = getType(state); + state.linkHref = false; + return returnState; + } + + stream.match(linkRE[endChar]); + state.linkHref = true; + return getType(state); + }; + } + + function footnoteLink(stream, state) { + if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { + state.f = footnoteLinkInside; + stream.next(); // Consume [ + if (modeCfg.highlightFormatting) state.formatting = "link"; + state.linkText = true; + return getType(state); + } + return switchInline(stream, state, inlineNormal); + } + + function footnoteLinkInside(stream, state) { + if (stream.match(/^\]:/, true)) { + state.f = state.inline = footnoteUrl; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var returnType = getType(state); + state.linkText = false; + return returnType; + } + + stream.match(/^([^\]\\]|\\.)+/, true); + + return tokenTypes.linkText; + } + + function footnoteUrl(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if (stream.eatSpace()) { + return null; + } + // Match URL + stream.match(/^[^\s]+/, true); + // Check for link title + if (stream.peek() === undefined) { + // End of line, set flag to check next line + state.linkTitle = true; + } else { + // More content on line, check if link title + stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); + } + state.f = state.inline = inlineNormal; + return tokenTypes.linkHref + " url"; + } + + var mode = { + startState: function startState() { + return { + f: blockNormal, + + prevLine: { stream: null }, + thisLine: { stream: null }, + + block: blockNormal, + htmlState: null, + indentation: 0, + + inline: inlineNormal, + text: handleText, + + formatting: false, + linkText: false, + linkHref: false, + linkTitle: false, + code: 0, + em: false, + strong: false, + header: 0, + setext: 0, + hr: false, + taskList: false, + list: false, + listStack: [], + quote: 0, + trailingSpace: 0, + trailingSpaceNewLine: false, + strikethrough: false, + emoji: false, + fencedEndRE: null + }; + }, + + copyState: function copyState(s) { + return { + f: s.f, + + prevLine: s.prevLine, + thisLine: s.thisLine, + + block: s.block, + htmlState: s.htmlState && _codemirror2.default.copyState(htmlMode, s.htmlState), + indentation: s.indentation, + + localMode: s.localMode, + localState: s.localMode ? _codemirror2.default.copyState(s.localMode, s.localState) : null, + + inline: s.inline, + text: s.text, + formatting: false, + linkText: s.linkText, + linkTitle: s.linkTitle, + linkHref: s.linkHref, + code: s.code, + em: s.em, + strong: s.strong, + strikethrough: s.strikethrough, + emoji: s.emoji, + header: s.header, + setext: s.setext, + hr: s.hr, + taskList: s.taskList, + list: s.list, + listStack: s.listStack.slice(0), + quote: s.quote, + indentedCode: s.indentedCode, + trailingSpace: s.trailingSpace, + trailingSpaceNewLine: s.trailingSpaceNewLine, + md_inside: s.md_inside, + fencedEndRE: s.fencedEndRE + }; + }, + + token: function token(stream, state) { + + // Reset state.formatting + state.formatting = false; + + if (stream != state.thisLine.stream) { + state.header = 0; + state.hr = false; + + if (stream.match(/^\s*$/, true)) { + blankLine(state); + return null; + } + + state.prevLine = state.thisLine; + state.thisLine = { stream: stream + + // Reset state.taskList + };state.taskList = false; + + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + + if (!state.localState) { + state.f = state.block; + if (state.f != htmlBlock) { + var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length; + state.indentation = indentation; + state.indentationDiff = null; + if (indentation > 0) return null; + } + } + } + return state.f(stream, state); + }, + + innerMode: function innerMode(state) { + if (state.block == htmlBlock) return { state: state.htmlState, mode: htmlMode }; + if (state.localState) return { state: state.localState, mode: state.localMode }; + return { state: state, mode: mode }; + }, + + indent: function indent(state, textAfter, line) { + if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line); + if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line); + return _codemirror2.default.Pass; + }, + + blankLine: blankLine, + + getType: getType, + + closeBrackets: "()[]{}''\"\"``", + fold: "markdown" + }; + return mode; +}, "xml"); // CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE +/** + * @modifier NHN Ent. FE Development Lab + */ +// based on https://github.com/codemirror/CodeMirror/blob/ff04f127ba8a736b97d06c505fb85d976e3f2980/mode/markdown/markdown.js + + +_codemirror2.default.defineMIME("text/markdown", "markdown"); + +_codemirror2.default.defineMIME("text/x-markdown", "markdown"); + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint-disable */ +var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i; // CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE +/** + * @modifier NHN Ent. FE Development Lab + */ + + +_codemirror2.default.defineMode("gfm", function (config, modeConfig) { + var codeDepth = 0; + function blankLine(state) { + state.code = false; + return null; + } + var gfmOverlay = { + startState: function startState() { + return { + code: false, + codeBlock: false, + ateSpace: false + }; + }, + copyState: function copyState(s) { + return { + code: s.code, + codeBlock: s.codeBlock, + ateSpace: s.ateSpace + }; + }, + token: function token(stream, state) { + state.combineTokens = null; + + // Hack to prevent formatting override inside code blocks (block and inline) + if (state.codeBlock) { + if (stream.match(/^```+/)) { + state.codeBlock = false; + return null; + } + stream.skipToEnd(); + return null; + } + if (stream.sol()) { + state.code = false; + } + if (stream.sol() && stream.match(/^```+/)) { + stream.skipToEnd(); + state.codeBlock = true; + return null; + } + // If this block is changed, it may need to be updated in Markdown mode + if (stream.peek() === '`') { + stream.next(); + var before = stream.pos; + stream.eatWhile('`'); + var difference = 1 + stream.pos - before; + if (!state.code) { + codeDepth = difference; + state.code = true; + } else { + if (difference === codeDepth) { + // Must be exact + state.code = false; + } + } + return null; + } else if (state.code) { + stream.next(); + return null; + } + // Check if space. If so, links can be formatted later on + if (stream.eatSpace()) { + state.ateSpace = true; + return null; + } + // Disable GitHub specifics. SHA, Num, Combine links + /* + if (stream.sol() || state.ateSpace) { + state.ateSpace = false; + if (modeConfig.gitHubSpice !== false) { + if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?=.{0,6}\d)(?:[a-f0-9]{7,40}\b)/)) { + // User/Project@SHA + // User@SHA + // SHA + state.combineTokens = true; + return "link"; + } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { + // User/Project#Num + // User#Num + // #Num + state.combineTokens = true; + return "link"; + } + } + } + if (stream.match(urlRE) && + stream.string.slice(stream.start - 2, stream.start) != "](" && + (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { + // URLs + // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls + // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine + // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL + state.combineTokens = true; + return "link"; + } + */ + stream.next(); + return null; + }, + blankLine: blankLine + }; + + var markdownConfig = { + taskLists: true, + strikethrough: true, + emoji: true + }; + for (var attr in modeConfig) { + markdownConfig[attr] = modeConfig[attr]; + } + markdownConfig.name = "markdown"; + return _codemirror2.default.overlayMode(_codemirror2.default.getMode(config, markdownConfig), gfmOverlay); +}, "markdown"); + +_codemirror2.default.defineMIME("text/x-gfm", "gfm"); + +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint-disable */ +var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, + emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, + unorderedListRE = /[*+-]\s/; // CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE +/** + * @modifier NHN Ent. FE Development Lab + */ + + +_codemirror2.default.commands.indentOrderedList = function (cm) { + if (cm.getOption("disableInput")) return _codemirror2.default.Pass; + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head; + var line = cm.getLine(pos.line); + var cursorBeforeTextInline = line.substr(0, pos.ch); + + if (listRE.test(cursorBeforeTextInline) || cm.somethingSelected()) { + cm.indentSelection("add"); + } else { + cm.execCommand("insertSoftTab"); + } + } + cm.execCommand('fixOrderedListNumber'); +}; + +_codemirror2.default.commands.newlineAndIndentContinueMarkdownList = function (cm) { + if (cm.getOption("disableInput")) return _codemirror2.default.Pass; + var ranges = cm.listSelections(), + replacements = []; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head; + var eolState = cm.getStateAfter(pos.line); + var inList = eolState.list !== false; + var inQuote = eolState.quote !== 0; + + var line = cm.getLine(pos.line), + match = listRE.exec(line); + var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch)); + if (!ranges[i].empty() || !inList && !inQuote || !match || cursorBeforeBullet) { + cm.execCommand("newlineAndIndent"); + return; + } + if (emptyListRE.test(line)) { + if (!/>\s*$/.test(line)) cm.replaceRange("", { + line: pos.line, ch: 0 + }, { + line: pos.line, ch: pos.ch + 1 + }); + replacements[i] = "\n"; + } else { + var indent = match[1], + after = match[5]; + var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0); + var bullet = numbered ? parseInt(match[3], 10) + 1 + match[4] : match[2].replace("x", " "); + replacements[i] = "\n" + indent + bullet + after; + + if (numbered) incrementRemainingMarkdownListNumbers(cm, pos); + } + } + + cm.replaceSelections(replacements); +}; + +// Auto-updating Markdown list numbers when a new item is added to the +// middle of a list +function incrementRemainingMarkdownListNumbers(cm, pos) { + var startLine = pos.line, + lookAhead = 0, + skipCount = 0; + var startItem = listRE.exec(cm.getLine(startLine)), + startIndent = startItem[1]; + + do { + lookAhead += 1; + var nextLineNumber = startLine + lookAhead; + var nextLine = cm.getLine(nextLineNumber), + nextItem = listRE.exec(nextLine); + + if (nextItem) { + var nextIndent = nextItem[1]; + var newNumber = parseInt(startItem[3], 10) + lookAhead - skipCount; + var nextNumber = parseInt(nextItem[3], 10), + itemNumber = nextNumber; + + if (startIndent === nextIndent && !isNaN(nextNumber)) { + if (newNumber === nextNumber) itemNumber = nextNumber + 1; + if (newNumber > nextNumber) itemNumber = newNumber + 1; + cm.replaceRange(nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]), { + line: nextLineNumber, ch: 0 + }, { + line: nextLineNumber, ch: nextLine.length + }); + } else { + if (startIndent.length > nextIndent.length) return; + // This doesn't run if the next line immediatley indents, as it is + // not clear of the users intention (new indented item or same level) + if (startIndent.length < nextIndent.length && lookAhead === 1) return; + skipCount += 1; + } + } + } while (nextItem); +} + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _codemirror = __webpack_require__(10); + +var _codemirror2 = _interopRequireDefault(_codemirror); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint-disable */ +_codemirror2.default.commands.replaceLineTextToUpper = function (cm) { + if (cm.getOption("disableInput")) { + return _codemirror2.default.Pass; + } + + var ranges = cm.listSelections(); + var lineAdjustment = -1; + + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var from = range.anchor; + var to = range.head; + + if (isSameLineSelection(range) && to.line > 0) { + replaceSingleLine(cm, from, to, lineAdjustment); + } else if (!isRangeCollapsed(range)) { + var topLine = from.line < to.line ? from.line : to.line; + + if (topLine > 0) { + var upper = from.line === topLine ? from : to; + var bottom = from.line === topLine ? to : from; + replaceMultiLine(cm, upper, bottom, lineAdjustment); + } + } + } +}; // CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE +/** + * @modifier NHN Ent. FE Development Lab + */ + + +_codemirror2.default.commands.replaceLineTextToLower = function (cm) { + if (cm.getOption("disableInput")) { + return _codemirror2.default.Pass; + } + + var ranges = cm.listSelections(); + var lineAdjustment = 1; + + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var from = range.anchor; + var to = range.head; + var isLastLine = to.line === cm.lastLine(); + + if (isSameLineSelection(range) && !isLastLine) { + replaceSingleLine(cm, from, to, lineAdjustment); + } else if (!isRangeCollapsed(range)) { + var topLine = from.line < to.line ? from.line : to.line; + var upper = from.line === topLine ? from : to; + var bottom = from.line === topLine ? to : from; + + if (bottom.line < cm.lastLine()) { + replaceMultiLine(cm, upper, bottom, lineAdjustment); + } + } + } +}; + +function isRangeCollapsed(range) { + return isSameLineSelection(range) && range.anchor.ch === range.head.ch; +} + +function isSameLineSelection(range) { + return range.anchor.line === range.head.line; +} + +function replaceSingleLine(cm, from, to, lineAdjustment) { + var currentLine = cm.getLine(to.line); + var replacement = cm.getLine(to.line + lineAdjustment); + var range = { + anchor: from, + head: to + }; + + cm.replaceRange(replacement, { + line: to.line, ch: 0 + }, { + line: to.line, ch: currentLine.length + }, '+input'); + + cm.replaceRange(currentLine, { + line: to.line + lineAdjustment, ch: 0 + }, { + line: to.line + lineAdjustment, ch: replacement.length + }, '+input'); + + if (isRangeCollapsed(range)) { + cm.setCursor({ + line: to.line + lineAdjustment, + ch: to.ch + }); + } else { + cm.setSelection({ + line: from.line + lineAdjustment, + ch: from.ch + }, { + line: to.line + lineAdjustment, + ch: to.ch + }); + } +} + +function replaceMultiLine(cm, upper, bottom, lineAdjustment) { + var rangeContent = cm.getRange({ + line: upper.line, ch: 0 + }, { + line: bottom.line, ch: cm.getLine(bottom.line).length + }); + var edgeLineOfConcern = lineAdjustment > 0 ? bottom : upper; + var replacement = cm.getLine(edgeLineOfConcern.line + lineAdjustment); + var targetLine = void 0; + + if (lineAdjustment > 0) { + targetLine = upper; + } else { + targetLine = bottom; + } + + cm.replaceRange(replacement, { + line: targetLine.line, ch: 0 + }, { + line: targetLine.line, ch: cm.getLine(targetLine.line).length + }, '+input'); + + cm.replaceRange(rangeContent, { + line: upper.line + lineAdjustment, ch: 0 + }, { + line: bottom.line + lineAdjustment, ch: cm.getLine(bottom.line + lineAdjustment).length + }, '+input'); + + cm.setSelection({ + line: upper.line + lineAdjustment, ch: upper.ch + }, { + line: bottom.line + lineAdjustment, ch: bottom.ch + }); +} + +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @fileoverview Implements markdown list manager + * @author NHN Ent. FE Development Lab + */ +var FIND_MD_OL_RX = /^[ \t]*[\d]+\. .*/; +var FIND_MD_UL_RX = /^[ \t]*[-*] .*/; +var FIND_MD_TASK_RX = /^[ \t]*[-*]( \[[ xX]])? .*/; +var FIND_TABLE_RX = /^\|([-\s\w\d\t<>?!@#$%^&*()_=+\\/'";: \r[\]]*\|+)+/i; +var FIND_HEADING_RX = /^#+\s/; +var FIND_BLOCK_RX = /^ {0,3}(```|\||>)/; + +/** + * Class MdListManager + */ + +var MdListManager = function () { + /** + * Creates an instance of MdListManager. + * @param {MarkdownEditor} mde - MarkdownEditor instance + * @memberof MdListManager + */ + function MdListManager(mde) { + _classCallCheck(this, MdListManager); + + this.mde = mde; + this.eventManager = mde.eventManager; + + /** + * Name property + * @memberof MdListManager# + * @type {string} + */ + this.name = 'list'; + } + + /** + * Return whether passed line is list or paragraph or not + * @param {string} line line text + * @returns {boolean} + */ + + + _createClass(MdListManager, [{ + key: 'isListOrParagraph', + value: function isListOrParagraph(line) { + return !FIND_BLOCK_RX.test(line) && !FIND_TABLE_RX.test(line) && !FIND_HEADING_RX.test(line); + } + + /** + * Append blank line at list top or bottom if needed + * @param {CodeMirror} cm CodeMirror instance + * @param {number} index index number + * @param {number} endLineNumber end line index number + * @param {number} startLineNumber start line index number + */ + + }, { + key: 'appendBlankLineIfNeed', + value: function appendBlankLineIfNeed(cm, index, endLineNumber, startLineNumber) { + var doc = cm.getDoc(); + var cursorPositionFactor = 0; + var isMultiLineSelection = startLineNumber !== endLineNumber; + var nextLineOfLastIndex = doc.getLine(this._getEndLineNumberOfList(doc, endLineNumber) + 1); + var previousLineOfFirstIndex = doc.getLine(this._getStartLineNumberOfList(doc, startLineNumber) - 1); + + var nextLine = doc.getLine(index + 1); + if (isMultiLineSelection && this._isNeedAppendBlankLine(nextLineOfLastIndex) || !isMultiLineSelection && this._isNeedAppendBlankLine(nextLine)) { + doc.replaceRange('\n', { + line: index, + ch: doc.getLine(index).length + }); + } + + var previousLine = doc.getLine(index - 1); + if (isMultiLineSelection && this._isNeedAppendBlankLine(previousLineOfFirstIndex) || !isMultiLineSelection && this._isNeedAppendBlankLine(previousLine)) { + doc.replaceRange('\n', { + line: startLineNumber, + ch: 0 + }); + cursorPositionFactor += 1; + } + if (!isMultiLineSelection) { + var currentLineNumber = index + cursorPositionFactor; + cm.setCursor(currentLineNumber, doc.getLine(currentLineNumber).length); + } + } + + /** + * Return whether need to append blank line or not + * @param {string} line Line text + * @returns {boolean} + * @private + */ + + }, { + key: '_isNeedAppendBlankLine', + value: function _isNeedAppendBlankLine(line) { + return line && line.length !== 0 && !this._isAList(line); + } + + /** + * Sort line number of selection descending + * @param {{from, to}} range start, end CodeMirror range information + * @returns {{start: {number}, end: {number}}} + */ + + }, { + key: 'createSortedLineRange', + value: function createSortedLineRange(range) { + var isReversed = range.from.line > range.to.line; + var rangeStart = { + line: isReversed ? range.to.line : range.from.line, + ch: 0 + }; + var rangeEnd = { + line: isReversed ? range.from.line : range.to.line, + ch: 0 + }; + + return { + start: rangeStart.line, + end: rangeEnd.line + }; + } + + /** + * Expand line range if need + * @param {object} doc doc instance + * @param {{from, to}} range CodeMirror range information + * @param {function} comparator comparator function + * @returns {{start: number, end: number}} + */ + + }, { + key: 'expandLineRangeIfNeed', + value: function expandLineRangeIfNeed(doc, range, comparator) { + var lineRange = this.createSortedLineRange(range); + var start = lineRange.start, + end = lineRange.end; + + + var isRangeStartInUlOrTask = this._isDifferentListType(comparator, doc.getLine(start)); + var isRangeEndInUlOrTask = this._isDifferentListType(comparator, doc.getLine(end)); + + if (isRangeStartInUlOrTask) { + start = this._getStartLineNumberOfList(doc, start); + } + + if (isRangeEndInUlOrTask) { + end = this._getEndLineNumberOfList(doc, end); + } + + return { + start: start, + end: end + }; + } + + /** + * Replace list syntax + * @param {object} doc CodeMirror doc instance + * @param {number} lineNumber Line number + * @param {RegExp} regexp Regexp for find list syntax + * @param {string} replacePattern Replacement string + */ + + }, { + key: 'replaceLineText', + value: function replaceLineText(doc, lineNumber, regexp, replacePattern) { + var line = doc.getLine(lineNumber); + var currentLineStart = { + line: lineNumber, + ch: 0 + }; + var currentLineEnd = { + line: lineNumber, + ch: line.length + }; + + line = line.replace(regexp, replacePattern); + + doc.replaceRange(line, currentLineStart, currentLineEnd); + } + + /** + * Return whether is a different list type or not + * @param {function} comparator comparator function + * @param {string} line line string + * @returns {boolean} + * @private + */ + + }, { + key: '_isDifferentListType', + value: function _isDifferentListType(comparator, line) { + return line && line.length !== 0 && comparator.call(this, line); + } + + /** + * Return whether is a list or not + * @param {string} line line string + * @returns {boolean} + * @private + */ + + }, { + key: '_isAList', + value: function _isAList(line) { + return line && line.length !== 0 && this._isListLine(line); + } + + /** + * Return whether passed line is list or not + * @param {string} line Line text + * @returns {Boolean} + * @private + */ + + }, { + key: '_isListLine', + value: function _isListLine(line) { + return !!(line.match(FIND_MD_TASK_RX) || line.match(FIND_MD_UL_RX) || line.match(FIND_MD_OL_RX)); + } + + /** + * Get start line number of current list + * @param {object} doc CodeMirror doc instance + * @param {number} startLineNumber start line number of selection + * @returns {number|undefined} + * @private + */ + + }, { + key: '_getStartLineNumberOfList', + value: function _getStartLineNumberOfList(doc, startLineNumber) { + var lineNumber = void 0; + + for (lineNumber = startLineNumber; lineNumber > 0; lineNumber -= 1) { + var previousLine = doc.getLine(lineNumber - 1); + if (!previousLine || !this._isListLine(previousLine)) { + break; + } + } + + return lineNumber; + } + + /** + * Get end line number of current list + * @param {object} doc CodeMirror doc instance + * @param {number} endLineNumber end line number of selection + * @returns {number|undefined} + * @private + */ + + }, { + key: '_getEndLineNumberOfList', + value: function _getEndLineNumberOfList(doc, endLineNumber) { + var lineCount = doc.lineCount(); + var lineNumber = void 0; + + for (lineNumber = endLineNumber; lineNumber < lineCount; lineNumber += 1) { + var nextLine = doc.getLine(lineNumber + 1); + if (!nextLine || !this._isListLine(nextLine)) { + break; + } + } + + return lineNumber; + } + }]); + + return MdListManager; +}(); + +exports.default = MdListManager; + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @fileoverview Implements markdown textObject + * @author NHN Ent. FE Development Lab + */ + +/** + * Class Markdown textObject + */ +var mdTextObject = function () { + /** + * Creates an instance of mdTextObject. + * @param {MarkdownEditor} mde - MarkdownEditor instance + * @param {object} range - range + * @memberof mdTextObject + */ + function mdTextObject(mde, range) { + _classCallCheck(this, mdTextObject); + + this._mde = mde; + + this.setRange(range || mde.getRange()); + } + + /** + * Set start + * @memberof mdTextObject + * @param {object} rangeStart Start of range + * @private + */ + + + _createClass(mdTextObject, [{ + key: '_setStart', + value: function _setStart(rangeStart) { + this._start = rangeStart; + } + + /** + * Set end + * @private + * @memberof mdTextObject + * @param {object} rangeEnd End of range + * @private + */ + + }, { + key: '_setEnd', + value: function _setEnd(rangeEnd) { + this._end = rangeEnd; + } + + /** + * Set range to given range + * @private + * @memberof mdTextObject + * @param {object} range Range object + */ + + }, { + key: 'setRange', + value: function setRange(range) { + this._setStart(range.start); + this._setEnd(range.end); + } + + /** + * Set start to end + * @private + * @memberof mdTextObject + * @param {object} range Range object + */ + + }, { + key: 'setEndBeforeRange', + value: function setEndBeforeRange(range) { + this._setEnd(range.start); + } + + /** + * Expand startOffset by 1 + * @private + * @memberof mdTextObject + */ + + }, { + key: 'expandStartOffset', + value: function expandStartOffset() { + var start = this._start; + + if (start.ch !== 0) { + start.ch -= 1; + } + } + + /** + * Expand endOffset by 1 + * @private + * @memberof mdTextObject + */ + + }, { + key: 'expandEndOffset', + value: function expandEndOffset() { + var end = this._end; + + if (end.ch < this._mde.getEditor().getDoc().getLine(end.line).length) { + end.ch += 1; + } + } + + /** + * Get current selection's text content + * @private + * @memberof mdTextObject + * @returns {{start: {line: number, ch: number}, end: {line: number, ch: number}}} + */ + + }, { + key: 'getTextContent', + value: function getTextContent() { + return this._mde.getEditor().getRange(this._start, this._end); + } + + /** + * Replace current selection's content with given text content + * @private + * @memberof mdTextObject + * @param {string} content Replacement content + */ + + }, { + key: 'replaceContent', + value: function replaceContent(content) { + this._mde.getEditor().replaceRange(content, this._start, this._end, '+input'); + } + + /** + * Delete current selection's content + * @private + * @memberof mdTextObject + */ + + }, { + key: 'deleteContent', + value: function deleteContent() { + this._mde.getEditor().replaceRange('', this._start, this._end, '+delete'); + } + + /** + * peek StartBeforeOffset + * @private + * @memberof mdTextObject + * @param {number} offset Offset + * @returns {{start: {line: number, ch: number}, end: {line: number, ch: number}}} + */ + + }, { + key: 'peekStartBeforeOffset', + value: function peekStartBeforeOffset(offset) { + var peekStart = { + line: this._start.line, + ch: Math.max(this._start.ch - offset, 0) + }; + + return this._mde.getEditor().getRange(peekStart, this._start); + } + }]); + + return mdTextObject; +}(); + +exports.default = mdTextObject; + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements LazyRunner + * @author NHN Ent. FE Development Lab + */ + + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class LazyRunner + */ +var LazyRunner = function () { + /** + * Creates an instance of LazyRunner. + * @memberof LazyRunner + */ + function LazyRunner() { + _classCallCheck(this, LazyRunner); + + this.globalTOID = null; + this.lazyRunFunctions = {}; + } + + _createClass(LazyRunner, [{ + key: 'run', + value: function run(fn, params, context, delay) { + var TOID = void 0; + + if (_tuiCodeSnippet2.default.isString(fn)) { + TOID = this._runRegisteredRun(fn, params, context, delay); + } else { + TOID = this._runSingleRun(fn, params, context, delay, this.globalTOID); + this.globalTOID = TOID; + } + + return TOID; + } + }, { + key: 'registerLazyRunFunction', + value: function registerLazyRunFunction(name, fn, delay, context) { + context = context || this; + + this.lazyRunFunctions[name] = { + fn: fn, + delay: delay, + context: context, + TOID: null + }; + } + }, { + key: '_runSingleRun', + value: function _runSingleRun(fn, params, context, delay, TOID) { + this._clearTOIDIfNeed(TOID); + + TOID = setTimeout(function () { + fn.call(context, params); + }, delay); + + return TOID; + } + }, { + key: '_runRegisteredRun', + value: function _runRegisteredRun(lazyRunName, params, context, delay) { + var lazyRunFunction = this.lazyRunFunctions[lazyRunName]; + var fn = lazyRunFunction.fn; + var TOID = lazyRunFunction.TOID; + + delay = delay || lazyRunFunction.delay; + context = context || lazyRunFunction.context; + + TOID = this._runSingleRun(fn, params, context, delay, TOID); + + lazyRunFunction.TOID = TOID; + + return TOID; + } + }, { + key: '_clearTOIDIfNeed', + value: function _clearTOIDIfNeed(TOID) { + if (TOID) { + clearTimeout(TOID); + } + } + }]); + + return LazyRunner; +}(); + +exports.default = LazyRunner; + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implments wysiwygEditor + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _wwClipboardManager = __webpack_require__(69); + +var _wwClipboardManager2 = _interopRequireDefault(_wwClipboardManager); + +var _wwListManager = __webpack_require__(71); + +var _wwListManager2 = _interopRequireDefault(_wwListManager); + +var _wwTaskManager = __webpack_require__(72); + +var _wwTaskManager2 = _interopRequireDefault(_wwTaskManager); + +var _wwTableManager = __webpack_require__(35); + +var _wwTableManager2 = _interopRequireDefault(_wwTableManager); + +var _wwTableSelectionManager = __webpack_require__(36); + +var _wwTableSelectionManager2 = _interopRequireDefault(_wwTableSelectionManager); + +var _wwHrManager = __webpack_require__(73); + +var _wwHrManager2 = _interopRequireDefault(_wwHrManager); + +var _wwPManager = __webpack_require__(74); + +var _wwPManager2 = _interopRequireDefault(_wwPManager); + +var _wwHeadingManager = __webpack_require__(75); + +var _wwHeadingManager2 = _interopRequireDefault(_wwHeadingManager); + +var _wwCodeBlockManager = __webpack_require__(37); + +var _wwCodeBlockManager2 = _interopRequireDefault(_wwCodeBlockManager); + +var _squireExt = __webpack_require__(76); + +var _squireExt2 = _interopRequireDefault(_squireExt); + +var _keyMapper = __webpack_require__(22); + +var _keyMapper2 = _interopRequireDefault(_keyMapper); + +var _wwTextObject = __webpack_require__(78); + +var _wwTextObject2 = _interopRequireDefault(_wwTextObject); + +var _componentManager = __webpack_require__(31); + +var _componentManager2 = _interopRequireDefault(_componentManager); + +var _codeBlockGadget = __webpack_require__(79); + +var _codeBlockGadget2 = _interopRequireDefault(_codeBlockGadget); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var keyMapper = _keyMapper2.default.getSharedInstance(); + +var FIND_EMPTY_LINE = /<([a-z]+|h\d)>(
    |
    )<\/\1>/gi, + FIND_UNNECESSARY_BR = /(?:
    |
    )<\/(.+?)>/gi, + FIND_BLOCK_TAGNAME_RX = /\b(H[\d]|LI|P|BLOCKQUOTE|TD|PRE)\b/; + +var EDITOR_CONTENT_CSS_CLASSNAME = 'tui-editor-contents'; + +var canObserveMutations = typeof MutationObserver !== 'undefined'; + +/** + * Class WysiwygEditor + */ + +var WysiwygEditor = function () { + /** + * Creates an instance of WysiwygEditor. + * @param {jQuery} $el element to insert editor + * @param {EventManager} eventManager EventManager instance + * @memberof WysiwygEditor + */ + function WysiwygEditor($el, eventManager) { + var _this = this; + + _classCallCheck(this, WysiwygEditor); + + this.componentManager = new _componentManager2.default(this); + this.eventManager = eventManager; + this.$editorContainerEl = $el; + + this._height = 0; + + this._silentChange = false; + + this._keyEventHandlers = {}; + this._managers = {}; + + this._initEvent(); + this._initDefaultKeyEventHandler(); + + this.debouncedPostProcessForChange = _tuiCodeSnippet2.default.debounce(function () { + return _this.postProcessForChange(); + }, 0); + } + + /** + * init + * @memberof WysiwygEditor + */ + + + _createClass(WysiwygEditor, [{ + key: 'init', + value: function init() { + var $editorBody = (0, _jquery2.default)('
    '); + + this.$editorContainerEl.append($editorBody); + + this.editor = new _squireExt2.default($editorBody[0], { + blockTag: 'DIV', + leafNodeNames: { + 'HR': false + } + }); + this.editor.blockCommandShortcuts(); + + this._clipboardManager = new _wwClipboardManager2.default(this); + this._initSquireEvent(); + this._clipboardManager.init(); + + this.get$Body().addClass(EDITOR_CONTENT_CSS_CLASSNAME); + this.$editorContainerEl.css('position', 'relative'); + + this.codeBlockGadget = new _codeBlockGadget2.default({ + eventManager: this.eventManager, + container: this.$editorContainerEl, + wysiwygEditor: this + }); + } + + /** + * _preprocessForInlineElement + * Seperate anchor tags with \u200B and replace blank space between
    and $1 + * @param {string} html Inner html of content editable + * @returns {string} + * @memberof WysiwygEditor + * @private + */ + + }, { + key: '_preprocessForInlineElement', + value: function _preprocessForInlineElement(html) { + return html.replace(/
    ( *)
    $1} keyMap - keyMap string or array of string + * @param {function} handler handler + */ + + }, { + key: 'addKeyEventHandler', + value: function addKeyEventHandler(keyMap, handler) { + var _this3 = this; + + if (!handler) { + handler = keyMap; + keyMap = 'DEFAULT'; + } + + if (!_tuiCodeSnippet2.default.isArray(keyMap)) { + keyMap = [keyMap]; + } + + keyMap.forEach(function (key) { + if (!_this3._keyEventHandlers[key]) { + _this3._keyEventHandlers[key] = []; + } + _this3._keyEventHandlers[key].push(handler); + }); + } + + /** + * REmove key event handler. + * @param {string} keyMap keyMap string + * @param {function} handler handler + */ + + }, { + key: 'removeKeyEventHandler', + value: function removeKeyEventHandler(keyMap, handler) { + if (!handler) { + handler = keyMap; + keyMap = 'DEFAULT'; + } + + var handlers = this._keyEventHandlers[keyMap]; + + if (handlers) { + this._keyEventHandlers[keyMap] = handlers.filter(function (_handler) { + return _handler !== handler; + }); + } + } + + /** + * _runKeyEventHandlers + * Run key event handler + * @param {Event} event event object + * @param {string} keyMap keyMapString + * @private + */ + + }, { + key: '_runKeyEventHandlers', + value: function _runKeyEventHandlers(event, keyMap) { + var range = this.getRange(); + var handlers = void 0, + isNeedNext = void 0; + + handlers = this._keyEventHandlers.DEFAULT; + + if (handlers) { + _tuiCodeSnippet2.default.forEachArray(handlers, function (handler) { + isNeedNext = handler(event, range, keyMap); + + return isNeedNext; + }); + } + + handlers = this._keyEventHandlers[keyMap]; + + if (handlers && isNeedNext !== false) { + _tuiCodeSnippet2.default.forEachArray(handlers, function (handler) { + return handler(event, range, keyMap); + }); + } + } + + /** + * _initSquireEvent + * Initialize squire event + * @private + */ + + }, { + key: '_initSquireEvent', + value: function _initSquireEvent() { + var _this4 = this; + + var squire = this.getEditor(); + var isNeedFirePostProcessForRangeChange = false; + + squire.addEventListener('copy', function (clipboardEvent) { + _this4.eventManager.emit('copy', { + source: 'wysiwyg', + data: clipboardEvent + }); + _tuiCodeSnippet2.default.debounce(function () { + if (!_this4.isEditorValid()) { + return; + } + + _this4.eventManager.emit('copyAfter', { + source: 'wysiwyg', + data: clipboardEvent + }); + })(); + }); + + squire.addEventListener(_tuiCodeSnippet2.default.browser.msie ? 'beforecut' : 'cut', function (clipboardEvent) { + _this4.eventManager.emit('cut', { + source: 'wysiwyg', + data: clipboardEvent + }); + _tuiCodeSnippet2.default.debounce(function () { + if (!_this4.isEditorValid()) { + return; + } + + _this4.eventManager.emit('cutAfter', { + source: 'wysiwyg', + data: clipboardEvent + }); + })(); + }); + + squire.addEventListener(_tuiCodeSnippet2.default.browser.msie ? 'beforepaste' : 'paste', function (clipboardEvent) { + _this4.eventManager.emit('paste', { + source: 'wysiwyg', + data: clipboardEvent + }); + }); + + squire.addEventListener('dragover', function (ev) { + ev.preventDefault(); + + return false; + }); + + squire.addEventListener('drop', function (ev) { + ev.preventDefault(); + + _this4.eventManager.emit('drop', { + source: 'wysiwyg', + data: ev + }); + + return false; + }); + + // change event will fired after range has been updated + squire.addEventListener('input', _tuiCodeSnippet2.default.debounce(function () { + if (!_this4.isEditorValid()) { + return; + } + + if (!_this4._silentChange) { + var eventObj = { + source: 'wysiwyg' + }; + + _this4.eventManager.emit('changeFromWysiwyg', eventObj); + _this4.eventManager.emit('change', eventObj); + _this4.eventManager.emit('contentChangedFromWysiwyg', _this4); + } else { + _this4._silentChange = false; + } + + _this4.getEditor().preserveLastLine(); + }, 0)); + + squire.addEventListener('keydown', function (keyboardEvent) { + var range = _this4.getEditor().getSelection(); + + if (!range.collapsed) { + isNeedFirePostProcessForRangeChange = true; + } + + _this4.eventManager.emit('keydown', { + source: 'wysiwyg', + data: keyboardEvent + }); + + _this4._onKeyDown(keyboardEvent); + }); + + if (_tuiCodeSnippet2.default.browser.firefox) { + squire.addEventListener('keypress', function (keyboardEvent) { + var keyCode = keyboardEvent.keyCode; + + + if (keyCode === 13 || keyCode === 9) { + var range = _this4.getEditor().getSelection(); + + if (!range.collapsed) { + isNeedFirePostProcessForRangeChange = true; + } + + _this4.eventManager.emit('keydown', { + source: 'wysiwyg', + data: keyboardEvent + }); + + _this4._onKeyDown(keyboardEvent); + } + }); + + // firefox produces shattered text nodes + squire.addEventListener('keyup', function () { + var range = _this4.getRange(); + + if (_domUtils2.default.isTextNode(range.commonAncestorContainer) && _domUtils2.default.isTextNode(range.commonAncestorContainer.previousSibling)) { + var prevLen = range.commonAncestorContainer.previousSibling.length; + var curEl = range.commonAncestorContainer; + + range.commonAncestorContainer.previousSibling.appendData(range.commonAncestorContainer.data); + + range.setStart(range.commonAncestorContainer.previousSibling, prevLen + range.startOffset); + range.collapse(true); + + curEl.parentNode.removeChild(curEl); + + _this4.setRange(range); + range.detach(); + } + }); + } + + squire.addEventListener('keyup', function (keyboardEvent) { + if (isNeedFirePostProcessForRangeChange) { + _this4.debouncedPostProcessForChange(); + isNeedFirePostProcessForRangeChange = false; + } + + _this4.eventManager.emit('keyup', { + source: 'wysiwyg', + data: keyboardEvent + }); + }); + + this.$editorContainerEl.on('scroll', function (ev) { + _this4.eventManager.emit('scroll', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('click', function (ev) { + _this4.eventManager.emit('click', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('mousedown', function (ev) { + _this4.eventManager.emit('mousedown', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('mouseover', function (ev) { + _this4.eventManager.emit('mouseover', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('mouseout', function (ev) { + _this4.eventManager.emit('mouseout', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('mouseup', function (ev) { + _this4.eventManager.emit('mouseup', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('contextmenu', function (ev) { + _this4.eventManager.emit('contextmenu', { + source: 'wysiwyg', + data: ev + }); + }); + + squire.addEventListener('focus', function () { + _this4.eventManager.emit('focus', { + source: 'wysiwyg' + }); + }); + + squire.addEventListener('blur', function () { + _this4.fixIMERange(); + _this4.eventManager.emit('blur', { + source: 'wysiwyg' + }); + }); + + // Toolbar status active/inactive + squire.addEventListener('pathChange', function (data) { + var state = { + bold: /(>B|>STRONG|^B$|^STRONG$)/.test(data.path), + italic: /(>I|>EM|^I$|^EM$)/.test(data.path), + strike: /(^S>|>S$|>S>|^S$)/.test(data.path), + code: /CODE/.test(data.path), + codeBlock: /PRE/.test(data.path), + quote: /BLOCKQUOTE/.test(data.path), + list: /LI(?!.task-list-item)/.test(_this4._getLastLiString(data.path)), + task: /LI.task-list-item/.test(_this4._getLastLiString(data.path)), + source: 'wysiwyg' + }; + + _this4.eventManager.emit('stateChange', state); + }); + + squire.addEventListener('willPaste', function (ev) { + // ev has 'fragment' when event occurs from 'insertHTML' of squire + // ev has 'text' when event occurs from 'insertPlainText' of squire + if (ev.fragment) { + _this4.eventManager.emit('willPaste', { + source: 'wysiwyg', + data: ev + }); + } + }); + } + + /** + * Return last matched list item path string matched index to end + * @param {string} path Full path string of current selection + * @returns {string} + * @private + */ + + }, { + key: '_getLastLiString', + value: function _getLastLiString(path) { + var foundedListItem = /LI[^UO]*$/.exec(path); + var result = void 0; + + if (foundedListItem) { + result = foundedListItem[0]; + } else { + result = ''; + } + + return result; + } + + /** + * Handler of keydown event + * @param {object} keyboardEvent Event object + * @private + */ + + }, { + key: '_onKeyDown', + value: function _onKeyDown(keyboardEvent) { + var keyMap = keyMapper.convert(keyboardEvent); + + // to avoid duplicate event firing in firefox + if (keyboardEvent.keyCode) { + this.eventManager.emit('keyMap', { + source: 'wysiwyg', + keyMap: keyMap, + data: keyboardEvent + }); + + if (!keyboardEvent.defaultPrevented) { + this.eventManager.emit('wysiwygKeyEvent', { + keyMap: keyMap, + data: keyboardEvent + }); + } + } + } + + /** + * _initDefaultKeyEventHandler + * Initialize default event handler + * @private + */ + + }, { + key: '_initDefaultKeyEventHandler', + value: function _initDefaultKeyEventHandler() { + var _this5 = this; + + this.addKeyEventHandler('ENTER', function (ev, range) { + if (_this5._isInOrphanText(range)) { + // We need this cuz input text right after table make orphan text in webkit + _this5.defer(function () { + _this5._wrapDefaultBlockToOrphanTexts(); + _this5.breakToNewDefaultBlock(range, 'before'); + }); + } + + _this5.defer(function () { + return _this5.scrollIntoCursor(); + }); + }); + + this.addKeyEventHandler('TAB', function (ev) { + var sq = _this5.getEditor(); + var range = sq.getSelection(); + var isAbleToInput4Spaces = range.collapsed && _this5._isCursorNotInRestrictedAreaOfTabAction(sq); + var isTextSelection = !range.collapsed && _domUtils2.default.isTextNode(range.commonAncestorContainer); + + ev.preventDefault(); + if (isAbleToInput4Spaces || isTextSelection) { + sq.insertPlainText('\xA0\xA0\xA0\xA0'); + + return false; + } + + return true; + }); + } + }, { + key: '_wrapDefaultBlockToOrphanTexts', + value: function _wrapDefaultBlockToOrphanTexts() { + var textNodes = this.get$Body().contents().filter(this.findTextNodeFilter); + + textNodes.each(function (i, node) { + if (node.nextSibling && node.nextSibling.tagName === 'BR') { + (0, _jquery2.default)(node.nextSibling).remove(); + } + + (0, _jquery2.default)(node).wrap('
    '); + }); + } + + /** + * _isInOrphanText + * check if range is orphan text + * @param {Range} range range + * @returns {boolean} result + * @private + */ + + }, { + key: '_isInOrphanText', + value: function _isInOrphanText(range) { + return range.startContainer.nodeType === Node.TEXT_NODE && range.startContainer.parentNode === this.get$Body()[0]; + } + + /** + * _wrapDefaultBlockTo + * Wrap default block to passed range + * @param {Range} range range + * @private + */ + + }, { + key: '_wrapDefaultBlockTo', + value: function _wrapDefaultBlockTo(range) { + this.saveSelection(range); + this._joinSplitedTextNodes(); + this.restoreSavedSelection(); + + range = this.getRange(); + + var textElem = range.startContainer; + var cursorOffset = range.startOffset; + + // after code below, range range is arranged by body + var block = this.getEditor().createDefaultBlock([range.startContainer]); + + // range for insert block + var insertTargetNode = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset); + if (insertTargetNode) { + range.setStartBefore(insertTargetNode); + } else { + // only child in container + range.selectNodeContents(range.startContainer); + } + + range.collapse(true); + + range.insertNode(block); + + // revert range to original node + range.setStart(textElem, cursorOffset); + range.collapse(true); + + this.setRange(range); + } + + /** + * findTextNodeFilter + * @this Node + * @returns {boolean} true or not + */ + + }, { + key: 'findTextNodeFilter', + value: function findTextNodeFilter() { + return this.nodeType === Node.TEXT_NODE; + } + + /** + * _joinSplitedTextNodes + * Join spliated text nodes + * @private + */ + + }, { + key: '_joinSplitedTextNodes', + value: function _joinSplitedTextNodes() { + var prevNode = void 0, + lastGroup = void 0; + var nodesToRemove = []; + var textNodes = this.get$Body().contents().filter(this.findTextNodeFilter); + + textNodes.each(function (i, node) { + if (prevNode === node.previousSibling) { + lastGroup.nodeValue += node.nodeValue; + nodesToRemove.push(node); + } else { + lastGroup = node; + } + + prevNode = node; + }); + + (0, _jquery2.default)(nodesToRemove).remove(); + } + + /** + * saveSelection + * Save current selection before modification + * @memberof WysiwygEditor + * @param {Range} range Range object + */ + + }, { + key: 'saveSelection', + value: function saveSelection(range) { + if (!range) { + range = this.getRange(); + } + + this.getEditor()._saveRangeToBookmark(range); + } + + /** + * set selection by start/end container/offset + * @param {HTMLNode} startContainer - start container + * @param {Number} startOffset - start offset + * @param {HTMLNode} endContainer - end container + * @param {Number} endOffset - end offset + * @returns {Range} - range instance + * @memberof WysiwygEditor + */ + + }, { + key: 'setSelectionByContainerAndOffset', + value: function setSelectionByContainerAndOffset(startContainer, startOffset, endContainer, endOffset) { + var sq = this.getEditor(); + var range = sq.getSelection(); + range.setStart(startContainer, startOffset); + range.setEnd(endContainer, endOffset); + sq.setSelection(range); + + return range; + } + + /** + * restoreSavedSelection + * Restore saved selection + * @memberof WysiwygEditor + */ + + }, { + key: 'restoreSavedSelection', + value: function restoreSavedSelection() { + this.setRange(this.getEditor()._getRangeAndRemoveBookmark()); + } + + /** + * reset + * Reset wysiwyg editor + * @memberof WysiwygEditor + */ + + }, { + key: 'reset', + value: function reset() { + this.setValue(''); + } + + /** + * changeBlockFormatTo + * Change current range block format to passed tag + * @memberof WysiwygEditor + * @param {string} targetTagName Target element tag name + */ + + }, { + key: 'changeBlockFormatTo', + value: function changeBlockFormatTo(targetTagName) { + this.getEditor().changeBlockFormatTo(targetTagName); + this.eventManager.emit('wysiwygRangeChangeAfter', this); + } + + /** + * makeEmptyBlockCurrentSelection + * Make empty block to current selection + * @memberof WysiwygEditor + */ + + }, { + key: 'makeEmptyBlockCurrentSelection', + value: function makeEmptyBlockCurrentSelection() { + var _this6 = this; + + this.getEditor().modifyBlocks(function (frag) { + if (!frag.textContent) { + frag = _this6.getEditor().createDefaultBlock(); + } + + return frag; + }); + } + + /** + * focus + * Focus to editor + * @memberof WysiwygEditor + */ + + }, { + key: 'focus', + value: function focus() { + var scrollTop = this.scrollTop(); + + this.editor.focus(); + + // In webkit, if contenteditable element focus method have been invoked when another input element has focus, + // contenteditable scroll to top automatically so we need scroll it back + if (scrollTop !== this.scrollTop()) { + this.scrollTop(scrollTop); + } + } + + /** + * blur + * Remove focus of editor + * @memberof WysiwygEditor + */ + + }, { + key: 'blur', + value: function blur() { + this.editor.blur(); + } + + /** + * remove + * Remove wysiwyg editor + * @memberof WysiwygEditor + */ + + }, { + key: 'remove', + value: function remove() { + this.getEditor().destroy(); + + this.editor = null; + this.$body = null; + this.eventManager = null; + } + + /** + * setHeight + * Set editor height + * @memberof WysiwygEditor + * @param {number|string} height pixel of height or "auto" + */ + + }, { + key: 'setHeight', + value: function setHeight(height) { + this._height = height; + + this.$editorContainerEl.css('overflow', 'auto'); + this.$editorContainerEl.css('height', '100%'); + this.$editorContainerEl.parent().height(height); + + var paddingHeight = parseInt(this.$editorContainerEl.css('padding-top'), 10) - parseInt(this.$editorContainerEl.css('padding-bottom'), 10); + var marginHeight = parseInt(this.get$Body().css('margin-top'), 10) - parseInt(this.get$Body().css('margin-bottom'), 10); + this.get$Body().css('min-height', height - marginHeight - paddingHeight + 'px'); + } + + /** + * set min height + * @param {number} minHeight - min height in px + * @memberof WysiwygEditor + */ + + }, { + key: 'setMinHeight', + value: function setMinHeight(minHeight) { + var editorBody = this.get$Body().get(0); + editorBody.style.minHeight = minHeight + 'px'; + } + + /** + * setValue + * Set value to wysiwyg editor + * @memberof WysiwygEditor + * @param {string} html - HTML text + * @param {boolean} [cursorToEnd=true] - move cursor to contents end + */ + + }, { + key: 'setValue', + value: function setValue(html) { + var cursorToEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + html = this.eventManager.emitReduce('wysiwygSetValueBefore', html); + + this.editor.setHTML(html); + + this.eventManager.emit('wysiwygSetValueAfter', this); + this.eventManager.emit('contentChangedFromWysiwyg', this); + + if (cursorToEnd) { + this.moveCursorToEnd(); + } + + this.getEditor().preserveLastLine(); + + this.getEditor().removeLastUndoStack(); + this.getEditor().saveUndoState(); + } + + /** + * insert given text to cursor position or selected area + * @param {string} text - text string to insert + * @memberof WysiwygEditor + */ + + }, { + key: 'insertText', + value: function insertText(text) { + this.editor.insertPlainText(text); + } + + /** + * getValue + * Get value of wysiwyg editor + * @memberof WysiwygEditor + * @returns {string} html + */ + + }, { + key: 'getValue', + value: function getValue() { + this._prepareGetHTML(); + + var html = this.editor.getHTML(); + + // empty line replace to br + html = html.replace(FIND_EMPTY_LINE, function (match, tag) { + var result = void 0; + + // we maintain empty list + if (tag === 'li') { + result = match; + // we maintain empty table + } else if (tag === 'td' || tag === 'th') { + result = '<' + tag + '>'; + } else { + result = '
    '; + } + + return result; + }); + + // remove unnecessary brs + html = html.replace(FIND_UNNECESSARY_BR, ''); + + // remove contenteditable block, in this case div + html = html.replace(/]*>/g, ''); + html = html.replace(/<\/div>/g, '
    '); + + html = this.eventManager.emitReduce('wysiwygProcessHTMLText', html); + + return html; + } + + /** + * _prepareGetHTML + * Prepare before get html + * @memberof WysiwygEditor + * @private + */ + + }, { + key: '_prepareGetHTML', + value: function _prepareGetHTML() { + var _this7 = this; + + this.getEditor().modifyDocument(function () { + _this7._joinSplitedTextNodes(); + _this7.eventManager.emit('wysiwygGetValueBefore', _this7); + }); + } + + /** + * postProcessForChange + * @memberof WysiwygEditor + */ + + }, { + key: 'postProcessForChange', + value: function postProcessForChange() { + var _this8 = this; + + if (!this.isEditorValid()) { + return; + } + + this.getEditor().modifyDocument(function () { + _this8.eventManager.emit('wysiwygRangeChangeAfter', _this8); + }); + } + + /** + * readySilentChange + * Ready to silent change + * @memberof WysiwygEditor + */ + + }, { + key: 'readySilentChange', + value: function readySilentChange() { + if (canObserveMutations && !this.getEditor().isIgnoreChange()) { + this._silentChange = true; + } + } + + /** + * getEditor + * Get squire + * @memberof WysiwygEditor + * @returns {SquireExt} squire + */ + + }, { + key: 'getEditor', + value: function getEditor() { + return this.editor; + } + + /** + * replaceSelection + * Replace text of passed range + * @memberof WysiwygEditor + * @param {string} content Content for change current selection + * @param {Range} range range + */ + + }, { + key: 'replaceSelection', + value: function replaceSelection(content, range) { + this.getEditor().replaceSelection(content, range); + } + + /** + * replaceRelativeOffset + * Replace content by relative offset + * @memberof WysiwygEditor + * @param {string} content Content for change current selection + * @param {number} offset Offset of current range + * @param {number} overwriteLength Length to overwrite content + */ + + }, { + key: 'replaceRelativeOffset', + value: function replaceRelativeOffset(content, offset, overwriteLength) { + this.getEditor().replaceRelativeOffset(content, offset, overwriteLength); + } + + /** + * addWidget + * Add widget to selection + * @memberof WysiwygEditor + * @param {Range} range Range object + * @param {Node} node Widget node + * @param {string} style Adding style "over" or "bottom" + * @param {number} [offset] Offset to adjust position + */ + + }, { + key: 'addWidget', + value: function addWidget(range, node, style, offset) { + var pos = this.getEditor().getSelectionPosition(range, style, offset); + var editorContainerPos = this.$editorContainerEl.offset(); + + this.$editorContainerEl.append(node); + + (0, _jquery2.default)(node).css({ + position: 'absolute', + top: pos.top - editorContainerPos.top + this.scrollTop(), + left: pos.left - editorContainerPos.left + }); + } + + /** + * get$Body + * Get jQuery wrapped body container of Squire + * @memberof WysiwygEditor + * @returns {JQuery} jquery body + */ + + }, { + key: 'get$Body', + value: function get$Body() { + return this.getEditor().get$Body(); + } + + /** + * hasFormatWithRx + * Check with given regexp whether current path has some format or not + * @memberof WysiwygEditor + * @param {RegExp} rx Regexp + * @returns {boolean} Match result + */ + + }, { + key: 'hasFormatWithRx', + value: function hasFormatWithRx(rx) { + return this.getEditor().getPath().match(rx); + } + + /** + * breakToNewDefaultBlock + * Break line to new default block from passed range + * @memberof WysiwygEditor + * @param {Range} range Range object + * @param {string} [where] "before" or not + */ + + }, { + key: 'breakToNewDefaultBlock', + value: function breakToNewDefaultBlock(range, where) { + var div = this.editor.createDefaultBlock(); + var currentNode = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset) || _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset - 1); + var appendBefore = _domUtils2.default.getParentUntil(currentNode, this.get$Body()[0]); + + if (where === 'before') { + (0, _jquery2.default)(appendBefore).before(div); + } else { + (0, _jquery2.default)(appendBefore).after(div); + } + + range.setStart(div, 0); + range.collapse(true); + this.setRange(range); + } + + /** + * replaceContentText + * Replace textContet of node + * @memberof WysiwygEditor + * @param {Node} container Container node + * @param {string} from Target text to change + * @param {string} to Replacement text + */ + + }, { + key: 'replaceContentText', + value: function replaceContentText(container, from, to) { + var before = (0, _jquery2.default)(container).html(); + (0, _jquery2.default)(container).html(before.replace(from, to)); + } + + /** + * unwrapBlockTag + * Unwrap Block tag of current range + * @memberof WysiwygEditor + * @param {function} [condition] iterate with tagName + */ + + }, { + key: 'unwrapBlockTag', + value: function unwrapBlockTag(condition) { + if (!condition) { + condition = function condition(tagName) { + return FIND_BLOCK_TAGNAME_RX.test(tagName); + }; + } + + this.getEditor().changeBlockFormat(condition); + this.eventManager.emit('wysiwygRangeChangeAfter', this); + } + + /** + * move scroll to cursor + * scrollIntoView browser function may cause scrolling on document. + * this function aims to replace scrollIntoView function to prevent that. + * it will move the scroll of squire only. + * @memberof SquireExt + */ + + }, { + key: 'scrollIntoCursor', + value: function scrollIntoCursor() { + var scrollTop = this.scrollTop(); + + var _getEditor$getCursorP = this.getEditor().getCursorPosition(), + cursorTop = _getEditor$getCursorP.top, + cursorHeight = _getEditor$getCursorP.height; + + var _$editorContainerEl$g = this.$editorContainerEl.get(0).getBoundingClientRect(), + editorTop = _$editorContainerEl$g.top, + editorHeight = _$editorContainerEl$g.height; + + var cursorAboveEditor = cursorTop - editorTop; + var cursorBelowEditor = cursorTop + cursorHeight - (editorTop + editorHeight); + + if (cursorAboveEditor < 0) { + this.scrollTop(scrollTop + cursorAboveEditor); + } else if (cursorBelowEditor > 0) { + this.scrollTop(scrollTop + cursorBelowEditor); + } + } + + /** + * Set cursor position to end + * @memberof WysiwygEditor + */ + + }, { + key: 'moveCursorToEnd', + value: function moveCursorToEnd() { + this.getEditor().moveCursorToEnd(); + this.scrollIntoCursor(); + this._correctRangeAfterMoveCursor('end'); + } + + /** + * Set cursor position to start + * @memberof WysiwygEditor + */ + + }, { + key: 'moveCursorToStart', + value: function moveCursorToStart() { + this.getEditor().moveCursorToStart(); + this.scrollTop(0); + } + + /** + * Set cursor position to start + * @memberof WysiwygEditor + * @param {number} value Scroll amount + * @returns {boolean} + */ + + }, { + key: 'scrollTop', + value: function scrollTop(value) { + if (_tuiCodeSnippet2.default.isUndefined(value)) { + return this.$editorContainerEl.scrollTop(); + } + + return this.$editorContainerEl.scrollTop(value); + } + + /** + * _correctRangeAfterMoveCursor + * For arrange Range after moveCursorToEnd api invocation. Squire has bug in Firefox, IE. + * @memberof WysiwygEditor + * @param {string} direction Direction of cursor move + * @private + */ + + }, { + key: '_correctRangeAfterMoveCursor', + value: function _correctRangeAfterMoveCursor(direction) { + var range = this.getRange(); + var cursorContainer = this.get$Body().get(0); + + if (direction === 'start') { + while (cursorContainer.firstChild) { + cursorContainer = cursorContainer.firstChild; + } + } else { + while (cursorContainer.lastChild) { + cursorContainer = cursorContainer.lastChild; + } + } + + // IE have problem with cursor after br + if (cursorContainer.tagName === 'BR') { + range.setStartBefore(cursorContainer); + } else { + range.setStartAfter(cursorContainer); + } + + range.collapse(true); + + this.setRange(range); + } + + /** + * Get current Range object + * @memberof WysiwygEditor + * @returns {Range} + */ + + }, { + key: 'getRange', + value: function getRange() { + return this.getEditor().getSelection().cloneRange(); + } + + /** + * get IME range + * cjk composition causes wrong caret position. + * it returns fixed IME composition range + * @memberof WysiwygEditor + * @returns {Range} + */ + + }, { + key: 'getIMERange', + value: function getIMERange() { + var range = void 0; + var selection = getSelection(); + + if (selection && selection.rangeCount) { + range = selection.getRangeAt(0).cloneRange(); + } + + return range; + } + + /** + * get IME range + * cjk composition causes wrong caret position. + * it sets fixed IME composition range + * @memberof WysiwygEditor + */ + + }, { + key: 'fixIMERange', + value: function fixIMERange() { + var range = this.getIMERange(); + + // range exists and it's an WYSIWYG editor content + if (range && (0, _jquery2.default)(range.commonAncestorContainer).closest(this.$editorContainerEl).length) { + this.setRange(range); + } + } + + /** + * set range + * @param {Range} range - range to set + * @memberof WysiwygEditor + */ + + }, { + key: 'setRange', + value: function setRange(range) { + this.getEditor().setSelection(range); + } + + /** + * Get text object of current range + * @memberof WysiwygEditor + * @param {Range} range Range object + * @returns {WwTextObject} + */ + + }, { + key: 'getTextObject', + value: function getTextObject(range) { + return new _wwTextObject2.default(this, range); + } + }, { + key: 'defer', + value: function defer(callback, delayOffset) { + var _this9 = this; + + var delay = delayOffset ? delayOffset : 0; + + setTimeout(function () { + if (_this9.isEditorValid()) { + callback(_this9); + } + }, delay); + } + }, { + key: 'isEditorValid', + value: function isEditorValid() { + return this.getEditor() && _jquery2.default.contains(this.$editorContainerEl[0].ownerDocument, this.$editorContainerEl[0]); + } + }, { + key: '_isCursorNotInRestrictedAreaOfTabAction', + value: function _isCursorNotInRestrictedAreaOfTabAction(editor) { + return !editor.hasFormat('li') && !editor.hasFormat('blockquote') && !editor.hasFormat('table'); + } + + /** + * WysiwygEditor factory method + * @memberof WysiwygEditor + * @param {jQuery} $el Container element for editor + * @param {EventManager} eventManager EventManager instance + * @param {object} [options={}] - option object + * @param {boolean} [options.useCommandShortcut=true] - whether to use squire command shortcuts + * @returns {WysiwygEditor} wysiwygEditor + */ + + }], [{ + key: 'factory', + value: function factory($el, eventManager, options) { + var wwe = new WysiwygEditor($el, eventManager, options); + + wwe.init(); + + wwe.componentManager.addManager(_wwListManager2.default); + wwe.componentManager.addManager(_wwTaskManager2.default); + wwe.componentManager.addManager(_wwTableSelectionManager2.default); + wwe.componentManager.addManager(_wwTableManager2.default); + wwe.componentManager.addManager(_wwHrManager2.default); + wwe.componentManager.addManager(_wwPManager2.default); + wwe.componentManager.addManager(_wwHeadingManager2.default); + wwe.componentManager.addManager(_wwCodeBlockManager2.default); + + return wwe; + } + }]); + + return WysiwygEditor; +}(); + +exports.default = WysiwygEditor; + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg editor clipboard manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _wwPasteContentHelper = __webpack_require__(70); + +var _wwPasteContentHelper2 = _interopRequireDefault(_wwPasteContentHelper); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PASTE_TABLE_BOOKMARK = 'tui-paste-table-bookmark'; +var PASTE_TABLE_CELL_BOOKMARK = 'tui-paste-table-cell-bookmark'; + +/** + * Class WwClipboardManager + */ + +var WwClipboardManager = function () { + /** + * Creates an instance of WwClipboardManager. + * @param {WysiwygEditor} wwe - WysiwygEditor instance + * @memberof WwClipboardManager + */ + function WwClipboardManager(wwe) { + _classCallCheck(this, WwClipboardManager); + + this.wwe = wwe; + this._pch = new _wwPasteContentHelper2.default(this.wwe); + this._selectedSellCount = 0; + this._$clipboardArea = null; + } + + /** + * init + * initialize + * @memberof WwClipboardManager + */ + + + _createClass(WwClipboardManager, [{ + key: 'init', + value: function init() { + var _this = this; + + this.wwe.eventManager.listen('willPaste', function (ev) { + return _this._onWillPaste(ev.data); + }); + this.wwe.eventManager.listen('copy', this._onCopyCut.bind(this)); + this.wwe.eventManager.listen('copyAfter', this._onCopyAfter.bind(this)); + this.wwe.eventManager.listen('cut', this._onCopyCut.bind(this)); + this.wwe.eventManager.listen('cutAfter', this._onCutAfter.bind(this)); + } + }, { + key: '_onCopyCut', + value: function _onCopyCut(event) { + var tableManager = this.wwe.componentManager.getManager('tableSelection'); + var selectedCellCount = tableManager.getSelectedCells().length; + if (!selectedCellCount) { + // preserve selection range in a cell, let squire do the job + return; + } + if (!tableManager.mergedTableSelectionManager) { + // set selection range to all contents in selected cells, then squire + tableManager.createRangeBySelectedCells(); + tableManager.removeClassAttrbuteFromAllCellsIfNeed(); + + return; + } + var editor = this.wwe.getEditor(); + var clipboardEvent = event.data; + var range = editor.getSelection().cloneRange(); + var $clipboardContainer = (0, _jquery2.default)('
    '); + + this._extendRange(range); + $clipboardContainer.append(range.cloneContents()); + this._updateCopyDataForListTypeIfNeed(range, $clipboardContainer); + this.wwe.eventManager.emit('copyBefore', { + source: 'wysiwyg', + $clipboardContainer: $clipboardContainer + }); + + this._setClipboardData(clipboardEvent, $clipboardContainer.html(), $clipboardContainer.text()); + } + }, { + key: '_clearClipboardArea', + value: function _clearClipboardArea() { + if (this._$clipboardArea) { + this._$clipboardArea.remove(); + this._$clipboardArea = null; + } + } + }, { + key: '_onCopyAfter', + value: function _onCopyAfter() { + this.wwe.getEditor().get$Body().focus(); + this._clearClipboardArea(); + } + }, { + key: '_onCutAfter', + value: function _onCutAfter() { + var range = this.wwe.getEditor().getSelection(); + range.deleteContents(); + this.wwe.getEditor().focus(); + this._clearClipboardArea(); + } + }, { + key: '_onWillPaste', + value: function _onWillPaste(pasteData) { + var _this2 = this; + + var $clipboardContainer = (0, _jquery2.default)('
    ').append(pasteData.fragment.cloneNode(true)); + + this._setTableBookmark($clipboardContainer); + + if (this._pasteToTable($clipboardContainer)) { + pasteData.preventDefault(); + } else { + this._preparePaste($clipboardContainer); + this._setTableBookmark($clipboardContainer); + + pasteData.fragment = document.createDocumentFragment(); + (0, _jquery2.default)($clipboardContainer[0].childNodes).each(function (index, element) { + pasteData.fragment.appendChild(element); + }); + } + + // @TODO Temporary code : paste to empty code block + this._pasteToEmptyCodeBlock(pasteData); + + // once right after the squire insertHTML DOM. + var handler = function handler() { + _this2.wwe.getEditor().removeEventListener('input', handler); + _this2.wwe.eventManager.emit('wysiwygRangeChangeAfter', _this2); + _this2._focusTableBookmark(); + }; + this.wwe.getEditor().addEventListener('input', handler); + } + + // @TODO Temporary code : paste to empty code block + // Squire remove empty code block when paste. + // This code should remove after Squire update !!! + // https://github.com/neilj/Squire/blob/7cef58bda854c49989c429d90756bff8d6fe758c/source/Range.js#L259 + + }, { + key: '_pasteToEmptyCodeBlock', + value: function _pasteToEmptyCodeBlock(pasteData) { + var _this3 = this; + + var sq = this.wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var container = range.startContainer; + var wwCodeblockManager = this.wwe.componentManager.getManager('codeblock'); + var shouldChangeSelection = false; + if (wwCodeblockManager.isInCodeBlock(range) && range.collapse && container.nodeName === 'PRE' && !container.textContent) { + var brNode = container.firstChild; + container.insertBefore(pasteData.fragment, brNode); + pasteData.defaultPrevented = true; + shouldChangeSelection = true; + } + + var handler = function handler() { + _this3.wwe.getEditor().removeEventListener('input', handler); + if (shouldChangeSelection) { + range.setStart(container, 1); + sq.setSelection(range); + } + }; + this.wwe.getEditor().addEventListener('input', handler); + } + }, { + key: '_setClipboardData', + value: function _setClipboardData(clipboardEvent, htmlContent, textContent) { + if (_tuiCodeSnippet2.default.browser.msie) { + clipboardEvent.squirePrevented = true; + this._$clipboardArea = this._createClipboardArea(); + this._$clipboardArea.html(htmlContent); + this._$clipboardArea.focus(); + window.getSelection().selectAllChildren(this._$clipboardArea[0]); + } else { + clipboardEvent.preventDefault(); + clipboardEvent.stopPropagation(); + clipboardEvent.clipboardData.setData('text/html', htmlContent); + clipboardEvent.clipboardData.setData('text/plain', textContent); + } + } + }, { + key: '_createClipboardArea', + value: function _createClipboardArea() { + return (0, _jquery2.default)('
    ').attr({ + contenteditable: 'true', + style: 'position:fixed; overflow:hidden; top:0; right:100%; width:1px; height:1px;' + }).appendTo(document.body); + } + + /** + * Update copy data, when commonAncestorContainer nodeName is list type like UL or OL. + * @param {object} range - text range + * @param {jQuery} $clipboardContainer - clibpard container jQuery element + * @private + */ + + }, { + key: '_updateCopyDataForListTypeIfNeed', + value: function _updateCopyDataForListTypeIfNeed(range, $clipboardContainer) { + var commonAncestorNodeName = range.commonAncestorContainer.nodeName; + if (commonAncestorNodeName !== 'UL' && commonAncestorNodeName !== 'OL') { + return; + } + + var $newParent = (0, _jquery2.default)('<' + commonAncestorNodeName + ' />'); + $newParent.append($clipboardContainer.html()); + $clipboardContainer.html(''); + $clipboardContainer.append($newParent); + } + + /** + * Remove empty font elements. + * @param {jQuery} $clipboardContainer - cliboard jQuery container + * @private + */ + + }, { + key: '_removeEmptyFontElement', + value: function _removeEmptyFontElement($clipboardContainer) { + // clipboard data from ms word tend to have unneccesary font tags + $clipboardContainer.children('font').each(function (index, element) { + var $element = (0, _jquery2.default)(element); + + if (!$element.text().trim()) { + $element.remove(); + } + }); + } + + /** + * Paste to table. + * @param {jQuery} $clipboardContainer - clibpard container + * @returns {boolean} whether processed or not + * @private + */ + + }, { + key: '_pasteToTable', + value: function _pasteToTable($clipboardContainer) { + var tableManager = this.wwe.componentManager.getManager('table'); + var tableSelectionManager = this.wwe.componentManager.getManager('tableSelection'); + var range = this.wwe.getEditor().getSelection(); + var pastingToTable = tableManager.isInTable(range); + + var _$clipboardContainer$ = $clipboardContainer.get(0), + childNodes = _$clipboardContainer$.childNodes; + + var containsOneTableOnly = childNodes.length === 1 && childNodes[0].nodeName === 'TABLE'; + var processed = false; + + if (pastingToTable) { + if (containsOneTableOnly) { + tableManager.pasteClipboardData($clipboardContainer.first()); + $clipboardContainer.html(''); // drains clipboard data as we've pasted everything here. + processed = true; + } else if (tableSelectionManager.getSelectedCells().length) { + alert(_i18n2.default.get('Cannot paste values ​​other than a table in the cell selection state')); + $clipboardContainer.html(''); // drains clipboard data + processed = true; + } + } + + return processed; + } + + /** + * Prepare paste. + * @param {jQuery} $clipboardContainer - temporary jQuery container for clipboard contents + * @private + */ + + }, { + key: '_preparePaste', + value: function _preparePaste($clipboardContainer) { + this._removeEmptyFontElement($clipboardContainer); + + this._pch.preparePaste($clipboardContainer); + + this.wwe.eventManager.emit('pasteBefore', { + source: 'wysiwyg', + $clipboardContainer: $clipboardContainer + }); + } + + /** + * set table bookmark which will gain focus after document modification ends. + * @param {jQuery} $clipboardContainer - clipboard container + * @memberof WwClipboardManager + * @private + */ + + }, { + key: '_setTableBookmark', + value: function _setTableBookmark($clipboardContainer) { + var $lastNode = (0, _jquery2.default)($clipboardContainer[0].childNodes).last(); + var isLastNodeTable = $lastNode[0] && $lastNode[0].nodeName === 'TABLE'; + + if (isLastNodeTable) { + $lastNode.addClass(PASTE_TABLE_BOOKMARK); + } + } + + /** + * Focus to table after document modification. + * @param {object} sq - squire editor instance + * @private + */ + + }, { + key: '_focusTableBookmark', + value: function _focusTableBookmark() { + var sq = this.wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var $bookmarkedTable = sq.get$Body().find('.' + PASTE_TABLE_BOOKMARK); + var $bookmarkedCell = sq.get$Body().find('.' + PASTE_TABLE_CELL_BOOKMARK); + + if ($bookmarkedTable.length) { + $bookmarkedTable.removeClass(PASTE_TABLE_BOOKMARK); + range.setEndAfter($bookmarkedTable[0]); + range.collapse(false); + sq.setSelection(range); + } + if ($bookmarkedCell.length) { + $bookmarkedCell.removeClass(PASTE_TABLE_CELL_BOOKMARK); + range.selectNodeContents($bookmarkedCell[0]); + range.collapse(false); + sq.setSelection(range); + } + } + + /** + * _extendRange + * extend range if need + * @memberof WwClipboardManager + * @param {Range} range to extend + * @private + */ + + }, { + key: '_extendRange', + value: function _extendRange(range) { + // non-text node && not selected whole area, then expand the range + if (_domUtils2.default.isTextNode(range.commonAncestorContainer) && (range.startOffset !== 0 || range.commonAncestorContainer.textContent.length !== range.endOffset) && range.commonAncestorContainer.nodeName !== 'TD') { + return; + } + + if (range.startOffset === 0) { + range = this._extendStartRange(range); + } + + if (range.endOffset === _domUtils2.default.getOffsetLength(range.endContainer)) { + range = this._extendEndRange(range); + } + + // commonAncestor if all of it's children has been selected + if (this._isWholeCommonAncestorContainerSelected(range)) { + range.selectNode(range.commonAncestorContainer); + } + this.wwe.getEditor().setSelection(range); + } + + /** + * Extends current range's startContainer + * @memberof WwClipboardManager + * @param {Range} range Range object + * @returns {Range} + * @private + */ + + }, { + key: '_extendStartRange', + value: function _extendStartRange(range) { + var newBound = range.startContainer; + + // expand range + while (newBound.parentNode !== range.commonAncestorContainer && newBound.parentNode !== this.wwe.get$Body()[0] && !newBound.previousSibling) { + newBound = newBound.parentNode; + } + + // expand range + range.setStart(newBound.parentNode, _domUtils2.default.getNodeOffsetOfParent(newBound)); + + return range; + } + + /** + * Extends current range's endContainer + * @memberof WwClipboardManager + * @param {Range} range Range object + * @returns {Range} + * @private + */ + + }, { + key: '_extendEndRange', + value: function _extendEndRange(range) { + var newBound = range.endContainer; + var boundNext = newBound.nextSibling; + + // expand range + while (newBound.parentNode !== range.commonAncestorContainer && newBound.parentNode !== this.wwe.get$Body()[0] && (!boundNext || _domUtils2.default.getNodeName(boundNext) === 'BR' && newBound.parentNode.lastChild === boundNext)) { + newBound = newBound.parentNode; + boundNext = newBound.nextSibling; + } + + // expand range level + range.setEnd(newBound.parentNode, _domUtils2.default.getNodeOffsetOfParent(newBound) + 1); + + return range; + } + + /** + * _isWholeCommonAncestorContainerSelected + * Check whether whole commonAncestorContainter textContent selected or not + * @memberof WwClipboardManager + * @param {Range} range Range object + * @returns {boolean} result + * @private + */ + + }, { + key: '_isWholeCommonAncestorContainerSelected', + value: function _isWholeCommonAncestorContainerSelected(range) { + return range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE && range.commonAncestorContainer !== this.wwe.get$Body()[0] && range.startOffset === 0 && range.endOffset === range.commonAncestorContainer.childNodes.length && range.commonAncestorContainer === range.startContainer && range.commonAncestorContainer === range.endContainer; + } + }]); + + return WwClipboardManager; +}(); + +exports.default = WwClipboardManager; + +/***/ }), +/* 70 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements WwPasteContentHelper + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _htmlSanitizer = __webpack_require__(34); + +var _htmlSanitizer2 = _interopRequireDefault(_htmlSanitizer); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class WwPasteContentHelper + */ +var WwPasteContentHelper = function () { + /** + * Creates an instance of WwPasteContentHelper. + * @param {WysiwygEditor} wwe - wysiwygEditor instance + * @memberof WwPasteContentHelper + */ + function WwPasteContentHelper(wwe) { + _classCallCheck(this, WwPasteContentHelper); + + this.wwe = wwe; + } + + /** + * Process paste data before paste + * @memberof WwPasteContentHelper + * @param {jQuery} $container - clipboard container + */ + + + _createClass(WwPasteContentHelper, [{ + key: 'preparePaste', + value: function preparePaste($container) { + var range = this.wwe.getEditor().getSelection().cloneRange(); + var wwCodeblockManager = this.wwe.componentManager.getManager('codeblock'); + var firstBlockIsTaken = false; + var $tempContainer = (0, _jquery2.default)('
    '); + + var nodeName = void 0, + node = void 0, + isPastingList = void 0; + + this._pasteFirstAid($container); + + var childNodes = _tuiCodeSnippet2.default.toArray($container[0].childNodes); + while (childNodes.length) { + node = childNodes[0]; + + nodeName = _domUtils2.default.getNodeName(node); + isPastingList = nodeName === 'LI' || nodeName === 'UL' || nodeName === 'OL'; + + if (wwCodeblockManager.isInCodeBlock(range)) { + $tempContainer.append(wwCodeblockManager.prepareToPasteOnCodeblock(childNodes)); + } else if (isPastingList) { + $tempContainer.append(this._prepareToPasteList(childNodes, range, firstBlockIsTaken)); + firstBlockIsTaken = true; + } else { + $tempContainer.append(childNodes.shift()); + } + } + + $container.html($tempContainer.html()); + } + + /** + * Wrap orphan node(inline, text) with div element + * @param {jQuery} $container - clipboard container + * @memberof WwPasteContentHelper + * @returns {DocumentFragment} + * @private + */ + + }, { + key: '_wrapOrphanNodeWithDiv', + value: function _wrapOrphanNodeWithDiv($container) { + var $tempContainer = (0, _jquery2.default)('
    '); + var array = _tuiCodeSnippet2.default.toArray($container[0].childNodes); + var currentDiv = void 0; + + _tuiCodeSnippet2.default.forEachArray(array, function (node) { + var isTextNode = node.nodeType === 3; + /* eslint-disable max-len */ + var isInlineNode = /^(SPAN|A|CODE|EM|I|STRONG|B|S|ABBR|ACRONYM|CITE|DFN|KBD|SAMP|VAR|BDO|Q|SUB|SUP)$/ig.test(node.tagName); + /* eslint-enable max-len */ + + if (isTextNode || isInlineNode) { + if (!currentDiv) { + currentDiv = document.createElement('div'); + $tempContainer.append(currentDiv); + // newFrag.appendChild(currentDiv); + } + + currentDiv.appendChild(node); + } else { + if (currentDiv && currentDiv.lastChild.tagName !== 'BR') { + currentDiv.appendChild((0, _jquery2.default)('
    ')[0]); + } + + currentDiv = null; + $tempContainer.append(node); + // newFrag.appendChild(node); + } + }); + + return $tempContainer.html(); + } + + /** + * Processing paste data after paste + * @param {jQuery} $container - clipboard container + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_pasteFirstAid', + value: function _pasteFirstAid($container) { + var _this = this; + + var blockTags = 'div, section, article, aside, nav, menus, p'; + + $container.html((0, _htmlSanitizer2.default)($container.html(), true)); + + $container.find('*').each(function (i, node) { + _this._removeStyles(node); + }); + + this._unwrapIfNonBlockElementHasBr($container); + this._unwrapNestedBlocks($container, blockTags); + this._removeUnnecessaryBlocks($container, blockTags); + + $container.html(this._wrapOrphanNodeWithDiv($container)); + + this._preElementAid($container); + + this._tableElementAid($container); + + $container.children('br').remove(); + } + + /** + * PRE tag formatting + * @memberof WwPasteContentHelper + * @private + * @param {jQuery} $container - clipboard container + */ + + }, { + key: '_preElementAid', + value: function _preElementAid($container) { + var wwCodeblockManager = this.wwe.componentManager.getManager('codeblock'); + wwCodeblockManager.modifyCodeBlockForWysiwyg($container); + } + + /** + * Unwrap span children of document fragment with div element + * @param {jQuery} $container - clipboard container + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_unwrapIfNonBlockElementHasBr', + value: function _unwrapIfNonBlockElementHasBr($container) { + var nonBlockElements = $container.find('span, a, b, em, i, s'); + + nonBlockElements.each(function (i, node) { + var brChildren = (0, _jquery2.default)(node).children('br'); + + if (brChildren.length && node.nodeName !== 'LI' && node.nodeName !== 'UL') { + brChildren.eq(0).unwrap(); + } + }); + } + + /** + * Unwrap nested block elements + * @param {jQuery} $container - clipboard container + * @param {string} blockTags - Tag names of block tag + * @private + */ + + }, { + key: '_unwrapNestedBlocks', + value: function _unwrapNestedBlocks($container, blockTags) { + var $leafElements = $container.find(':not(:has(*))').not('b,s,i,em,code,span'); + + $leafElements.each(function (i, node) { + var leafElement = node.nodeName === 'BR' ? (0, _jquery2.default)(node.parentNode) : (0, _jquery2.default)(node); + + while (leafElement.parents(blockTags).length) { + var $parent = leafElement.parent(blockTags); + + if ($parent.length && $parent[0] !== $container[0]) { + leafElement.unwrap(); + } else { + leafElement = leafElement.parent(); + } + } + }); + } + + /** + * Remove unnecessary block element in pasting data + * @param {jQuery} $container - clipboard container + * @param {string} blockTags - Tag names of block tag + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_removeUnnecessaryBlocks', + value: function _removeUnnecessaryBlocks($container, blockTags) { + $container.find(blockTags).each(function (index, blockElement) { + var $blockElement = (0, _jquery2.default)(blockElement); + var tagName = blockElement.tagName; + + var isDivElement = tagName === 'DIV'; + var isInListItem = $blockElement.parent('li').length !== 0; + var isInBlockquote = $blockElement.parent('blockquote').length !== 0; + var hasBlockChildElement = $blockElement.children(blockTags).length; + + if (isDivElement && (isInListItem || isInBlockquote || !hasBlockChildElement)) { + return; + } + + $blockElement.replaceWith($blockElement.html()); + }); + } + + /** + * Remove inline style + * @param {Node} node Node for remove style attribute + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_removeStyles', + value: function _removeStyles(node) { + var $node = (0, _jquery2.default)(node); + var colorValue = void 0; + + if (_domUtils2.default.getNodeName($node[0]) !== 'SPAN') { + $node.removeAttr('style'); + } else { + // Most browser return computed color value even if without style attribute + if ($node.attr('style')) { + colorValue = $node.css('color'); + } + + $node.removeAttr('style'); + + if (colorValue) { + $node.css('color', colorValue); + } else { + $node.contents().unwrap(); + } + } + } + + /** + * Processing before paste list + * @param {Array.} nodes Pasting data + * @param {object} rangeInfo Range information + * @param {boolean} firstBlockIsTaken Whether first block element taken or not + * @returns {DocumentFragment} + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_prepareToPasteList', + value: function _prepareToPasteList(nodes, rangeInfo, firstBlockIsTaken) { + var nodeName = _domUtils2.default.getNodeName(nodes[0]); + var node = nodes.shift(); + var newFragment = this.wwe.getEditor().getDocument().createDocumentFragment(); + + // IE somethimes returns ul without li + if (nodeName !== 'LI' && nodes.length && nodes[0].tagName === 'LI') { + nodeName = 'LI'; + + node = this._makeNodeAndAppend({ + tagName: nodeName + }, node); + } + + // pasting list into list, we should care indentation + if (nodeName === 'OL' || nodeName === 'UL') { + // ignore cursor if pasting data has block + if (!firstBlockIsTaken && this.wwe.getEditor().hasFormat('LI')) { + (0, _jquery2.default)(newFragment).append(this._wrapCurrentFormat(node)); + } else { + (0, _jquery2.default)(newFragment).append(node); + } + } else if (nodeName === 'LI') { + // handle list group + var listGroup = this.wwe.getEditor().getDocument().createDocumentFragment(); + listGroup.appendChild(node); + + while (nodes.length && nodes[0].tagName === 'LI') { + listGroup.appendChild(nodes.shift()); + } + + // pasting list into list, we should care indentation + // ignore cursor if pasting data has block + if (!firstBlockIsTaken && this.wwe.getEditor().hasFormat('LI')) { + (0, _jquery2.default)(newFragment).append(this._wrapCurrentFormat(listGroup)); + } else if (rangeInfo && (rangeInfo.commonAncestorName === 'UL' || rangeInfo.commonAncestorName === 'OL')) { + (0, _jquery2.default)(newFragment).append(this._makeNodeAndAppend({ + tagName: rangeInfo.commonAncestorName + }, listGroup)); + // list from outside + } else { + (0, _jquery2.default)(newFragment).append(this._makeNodeAndAppend({ + tagName: 'UL' + }, listGroup)); + } + } + + return newFragment; + } + + /** + * Unwrap fragment first child for pasting node inline + * @memberof WwPasteContentHelper + * @private + * @param {Node} node Pasting DocumentFragment + * @returns {NodeList} + */ + + }, { + key: '_unwrapFragmentFirstChildForPasteAsInline', + value: function _unwrapFragmentFirstChildForPasteAsInline(node) { + (0, _jquery2.default)(node).find('br').remove(); + + return node.childNodes; + } + + /** + * Wrap nodes with current format + * @param {DocumentFragment} nodes P + * @returns {HTMLElement} + * @private + */ + + }, { + key: '_wrapCurrentFormat', + value: function _wrapCurrentFormat(nodes) { + var _this2 = this; + + var currentTagName = void 0; + + // expand to pasting area + this._eachCurrentPath(function (path) { + if (path.tagName !== 'DIV') { + if (_domUtils2.default.isElemNode(nodes)) { + currentTagName = nodes.tagName; + } else { + currentTagName = nodes.firstChild.tagName; + } + + if (path.tagName !== currentTagName) { + nodes = _this2._makeNodeAndAppend(path, nodes); + } + } + }); + + return nodes; + } + }, { + key: '_eachCurrentPath', + value: function _eachCurrentPath(iteratee) { + var paths = _domUtils2.default.getPath(this.wwe.getEditor().getSelection().startContainer, this.wwe.get$Body()[0]); + + for (var i = paths.length - 1; i > -1; i -= 1) { + iteratee(paths[i]); + } + } + + /** _makeNodeAndAppend + * make node and append their own children + * @param {HTMLElement} pathInfo HTMLElement to make + * @param {HTMLElement} content Nodes to append + * @returns {HTMLElement} node + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_makeNodeAndAppend', + value: function _makeNodeAndAppend(pathInfo, content) { + var node = (0, _jquery2.default)('<' + pathInfo.tagName + '/>'); + + node.append(content); + + if (pathInfo.id) { + node.attr('id', pathInfo.id); + } + + if (pathInfo.className) { + node.addClass(pathInfo.className); + } + + return node[0]; + } + + /** + * Pasting table element pre-process + * @param {jQuery} $container - clipboard container + * @memberof WwPasteContentHelper + * @private + */ + + }, { + key: '_tableElementAid', + value: function _tableElementAid($container) { + this._removeColgroup($container); + this._completeTableIfNeed($container); + this._updateTableIDClassName($container); + } + + /** + * Remove colgroup tag + * @param {jQuery} $container - clipboard container + * @memberof WwPasteContentHelper + * @private + **/ + + }, { + key: '_removeColgroup', + value: function _removeColgroup($container) { + $container.find('colgroup').remove(); + } + + /** + * Complete and append table to fragment + * @param {jQuery} $container - clipboard container + * @private + */ + + }, { + key: '_completeTableIfNeed', + value: function _completeTableIfNeed($container) { + var tableManager = this.wwe.componentManager.getManager('table'); + var wrapperTr = tableManager.wrapDanglingTableCellsIntoTrIfNeed($container); + + if (wrapperTr) { + $container.append(wrapperTr); + } + + var wrapperTbody = tableManager.wrapTrsIntoTbodyIfNeed($container); + + if (wrapperTbody) { + $container.append(wrapperTbody); + } + + var wrapperTable = tableManager.wrapTheadAndTbodyIntoTableIfNeed($container); + + if (wrapperTable) { + $container.append(wrapperTable); + } + } + + /** + * Update table ID class name in fragment + * @param {jQuery} $container - clipboard container + * @private + */ + + }, { + key: '_updateTableIDClassName', + value: function _updateTableIDClassName($container) { + var tableManager = this.wwe.componentManager.getManager('table'); + + $container.find('table').each(function (index, table) { + (0, _jquery2.default)(table).removeClass(function (idx, className) { + return className.replace(/.*\s*(te-content-table-\d+)\s*.*/, '$1'); + }); + }); + + $container.find('table').each(function (index, table) { + (0, _jquery2.default)(table).addClass(tableManager.getTableIDClassName()); + }); + } + }]); + + return WwPasteContentHelper; +}(); + +exports.default = WwPasteContentHelper; + +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg list manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var FIND_LI_ELEMENT = /
  • (
    |
    ){0,}<\1>/g, ':BLANK_LINE:<$1>'); + } + + /** + * make arbitrary nesting list out of standard list + * `
    • text
      • text2
    ` to + * `
    • text
      • text2
    ` + * @param {string} html string to convert + * @returns {string} converted HTML text + * @private + */ + + }, { + key: '_convertToArbitraryNestingList', + value: function _convertToArbitraryNestingList(html) { + var NESTED_LIST_QUERY = 'li > ul, li > ol'; + var wrapper = document.createElement('div'); + wrapper.innerHTML = html; + + var nestedList = wrapper.querySelector(NESTED_LIST_QUERY); + while (nestedList !== null) { + var parentLI = nestedList.parentNode; + var parentList = parentLI.parentNode; + + parentList.insertBefore(nestedList, parentLI.nextElementSibling); + + nestedList = wrapper.querySelector(NESTED_LIST_QUERY); + } + + return wrapper.innerHTML; + } + + /** + * make standard list out of arbitrary nesting list + * `
    • text
      • text2
    ` from + * `
    • text
      • text2
    ` + * @param {string} html string to convert + * @returns {string} converted HTML text + * @private + */ + + }, { + key: '_convertFromArbitraryNestingList', + value: function _convertFromArbitraryNestingList(html) { + var NESTED_LIST_QUERY = 'ol > ol, ol > ul, ul > ol, ul > ul'; + var wrapperDiv = document.createElement('div'); + wrapperDiv.innerHTML = html; + + var nestedList = wrapperDiv.querySelector(NESTED_LIST_QUERY); + while (nestedList !== null) { + var prevLI = nestedList.previousElementSibling; + while (prevLI && prevLI.tagName !== 'LI') { + prevLI = prevLI.previousElementSibling; + } + + if (prevLI) { + prevLI.appendChild(nestedList); + } else { + this._unwrap(nestedList); + } + + nestedList = wrapperDiv.querySelector(NESTED_LIST_QUERY); + } + + return wrapperDiv.innerHTML; + } + + /** + * unwrap nesting list + * @param {Node} nestedList - nested list to unwrap + * @private + */ + + }, { + key: '_unwrap', + value: function _unwrap(nestedList) { + var fragment = document.createDocumentFragment(); + while (nestedList.firstChild) { + fragment.appendChild(nestedList.firstChild); + } + nestedList.parentNode.replaceChild(fragment, nestedList); + } + + /** + * Return lines in selection + * @param {Node} start Start element + * @param {Node} end End element + * @param {HTMLElement} body Editor body element + * @returns {Array.} + * @private + */ + + }, { + key: 'getLinesOfSelection', + value: function getLinesOfSelection(start, end) { + var lines = []; + var isLastLine = false; + var needNext = true; + var nextLine = void 0; + + if (_domUtils2.default.isTextNode(start)) { + start = (0, _jquery2.default)(start).parents(DIV_OR_LI).first().get(0); + } + + if (_domUtils2.default.isTextNode(end)) { + end = (0, _jquery2.default)(end).parents(DIV_OR_LI).first().get(0); + } + + for (var line = start; needNext; line = nextLine) { + if ((0, _jquery2.default)(line).is(DIV_OR_LI)) { + lines.push(line); + + if (line === end) { + isLastLine = true; + } else { + nextLine = this._getNextLine(line, end); + } + } else { + break; + } + needNext = nextLine && !isLastLine; + } + + return lines; + } + + /** + * get next line + * @param {Node} currentLine - current line node + * @param {Node} end - last node in selection + * @returns {Node} - next line node + * @private + */ + + }, { + key: '_getNextLine', + value: function _getNextLine(currentLine, end) { + var nextLine = currentLine.nextElementSibling; + + if (!nextLine) { + // current line was the last line in ul/ol + // while we have lines those has not been processed yet. + nextLine = currentLine.parentNode.nextElementSibling; + } else if ((0, _jquery2.default)(nextLine).is(UL_OR_OL)) { + // we don't sure firstChild is LI. arbtrary list can have another ol/ul + nextLine = nextLine.querySelector('li'); + } + + if ((0, _jquery2.default)(nextLine).is(DIV_OR_LI) || nextLine === end) { + return nextLine; + } + + return this._getNextLine(nextLine); + } + + /** + * merge to previous list + * consider remove this function when https://github.com/neilj/Squire/issues/294 resolved + * @param {HTMLLIElement} currentLine - current li element + * @ignore + */ + + }, { + key: 'mergeList', + value: function mergeList(currentLine) { + var currentList = currentLine.parentNode; + var prevList = currentList.previousElementSibling; + var nextList = currentList.nextElementSibling; + + if (currentList.firstElementChild === currentLine) { + if (prevList && (0, _jquery2.default)(prevList).is(UL_OR_OL)) { + this._mergeList(currentList, prevList); + currentList = prevList; + } + } + + if (currentList.lastElementChild === currentLine) { + if (nextList && (0, _jquery2.default)(nextList).is(UL_OR_OL)) { + this._mergeList(nextList, currentList); + } + } + } + + /** + * merge list to targetList + * @param {HTMLOListElement|HTMLUListElement} list - list to merge + * @param {HTMLOListElement|HTMLUListElement} targetList - target list + * @ignore + */ + + }, { + key: '_mergeList', + value: function _mergeList(list, targetList) { + var listItem = list.firstElementChild; + + if (targetList && (0, _jquery2.default)(targetList).is(UL_OR_OL)) { + while (listItem) { + var temp = listItem.nextElementSibling; + targetList.appendChild(listItem); + listItem = temp; + } + + list.parentNode.removeChild(list); + } + } + }]); + + return WwListManager; +}(); + +exports.default = WwListManager; + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg task manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var TASK_CLASS_NAME = 'task-list-item'; +var TASK_ATTR_NAME = 'data-te-task'; +var TASK_CHECKED_CLASS_NAME = 'checked'; + +/** + * Class WwTaskManager + */ + +var WwTaskManager = function () { + /** + * Creates an instance of WwTaskManager. + * @param {WysiwygEditor} wwe - WysiwygEditor instance + * @memberof WwTaskManager + */ + function WwTaskManager(wwe) { + _classCallCheck(this, WwTaskManager); + + this.wwe = wwe; + this.eventManager = wwe.eventManager; + + /** + * Name property + * @memberof WwTaskManager# + * @type {string} + */ + this.name = 'task'; + + this._init(); + } + + /** + * _init + * Init + * @memberof WwTaskManager + * @private + */ + + + _createClass(WwTaskManager, [{ + key: '_init', + value: function _init() { + this._initKeyHandler(); + this._initEvent(); + + this.wwe.getEditor().addEventListener('mousedown', function (ev) { + var isOnTaskBox = ev.offsetX < 18 && ev.offsetY < 18; + + if (ev.target.hasAttribute(TASK_ATTR_NAME) && isOnTaskBox) { + (0, _jquery2.default)(ev.target).toggleClass(TASK_CHECKED_CLASS_NAME); + } + }); + } + + /** + * _initEvent + * Initialize event + * @memberof WwTaskManager + * @private + */ + + }, { + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this.eventManager.listen('wysiwygSetValueAfter', function () { + _this._removeTaskListClass(); + }); + } + + /** + * _initKeyHandler + * Initialize key event handler + * @memberof WwTaskManager + * @private + */ + + }, { + key: '_initKeyHandler', + value: function _initKeyHandler() { + var _this2 = this; + + this.wwe.addKeyEventHandler('ENTER', function (ev, range) { + if (_this2.isInTaskList(range)) { + _this2.wwe.defer(function () { + var newRange = _this2.wwe.getRange(); + var $li = (0, _jquery2.default)(newRange.startContainer).closest('li'); + $li.removeClass(TASK_CHECKED_CLASS_NAME); + }); + } + }); + } + + /** + * isInTaskList + * Check whether passed range is in task list or not + * @param {Range} range range + * @returns {boolean} result + * @memberof WwTaskManager + */ + + }, { + key: 'isInTaskList', + value: function isInTaskList(range) { + var li = void 0; + + if (!range) { + range = this.wwe.getEditor().getSelection().cloneRange(); + } + + if (range.startContainer.nodeType === Node.ELEMENT_NODE && range.startContainer.tagName === 'LI') { + li = range.startContainer; + } else { + li = (0, _jquery2.default)(range.startContainer).parents('li').get(0); + } + + return (0, _jquery2.default)(li).hasClass(TASK_CLASS_NAME); + } + + /** + * unformatTask + * Unforamt task + * @param {Node} node target + * @memberof WwTaskManager + */ + + }, { + key: 'unformatTask', + value: function unformatTask(node) { + var $li = (0, _jquery2.default)(node).closest('li'); + + $li.removeClass(TASK_CLASS_NAME); + $li.removeClass(TASK_CHECKED_CLASS_NAME); + + $li.removeAttr(TASK_ATTR_NAME); + + if (!$li.attr('class')) { + $li.removeAttr('class'); + } + } + + /** + * formatTask + * Format task + * @param {Node} node target + * @memberof WwTaskManager + */ + + }, { + key: 'formatTask', + value: function formatTask(node) { + var $selected = (0, _jquery2.default)(node); + var $li = $selected.closest('li'); + + $li.addClass(TASK_CLASS_NAME); + $li.attr(TASK_ATTR_NAME, ''); + } + + /** + * _formatTaskIfNeed + * Format task if current range has task class name + * @memberof WwTaskManager + * @private + */ + + }, { + key: '_formatTaskIfNeed', + value: function _formatTaskIfNeed() { + var range = this.wwe.getEditor().getSelection().cloneRange(); + + if (this.isInTaskList(range)) { + this.formatTask(range.startContainer); + } + } + + /** + * _removeTaskListClass + * Remove tasklist class + * @memberof WwTaskManager + * @private + */ + + }, { + key: '_removeTaskListClass', + value: function _removeTaskListClass() { + // because task-list class is block merge normal list and task list + this.wwe.get$Body().find('.task-list').each(function (index, node) { + (0, _jquery2.default)(node).removeClass('task-list'); + }); + } + }]); + + return WwTaskManager; +}(); + +exports.default = WwTaskManager; + +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg hr manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class WwHrManager + */ +var WwHrManager = function () { + /** + * Creates an instance of WwHrManager. + * @param {WysiwygEditor} wwe - WysiwygEditor instance + * @memberof WwHrManager + */ + function WwHrManager(wwe) { + _classCallCheck(this, WwHrManager); + + this.wwe = wwe; + this.eventManager = wwe.eventManager; + + /** + * Name property + * @memberof WwHrManager# + * @type {string} + */ + this.name = 'hr'; + + this._init(); + } + + /** + * _init + * Initialize + * @memberof WwHrManager + * @private + */ + + + _createClass(WwHrManager, [{ + key: '_init', + value: function _init() { + this._initKeyHandler(); + this._initEvent(); + } + + /** + * _initEvent + * Initialize eventmanager event + * @memberof WwHrManager + * @private + */ + + }, { + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this.eventManager.listen('wysiwygSetValueAfter', function () { + _this._unwrapDivOnHr(); + }); + + this.eventManager.listen('wysiwygGetValueBefore', function () { + _this._wrapDefaultBlockToOrphanTexts(); + }); + } + + /** + * _initKeyHandler + * Initialize key event handler + * @memberof WwHrManager + * @private + */ + + }, { + key: '_initKeyHandler', + value: function _initKeyHandler() { + var _this2 = this; + + this.wwe.addKeyEventHandler(function (ev, range) { + return _this2._onTypedInHr(range); + }); + + this.wwe.addKeyEventHandler('ENTER', function (ev, range) { + if (range.collapsed) { + return _this2._removeHrOnEnter(range, ev); + } + + return true; + }); + + this.wwe.addKeyEventHandler('BACK_SPACE', function (ev, range) { + if (range.collapsed) { + return _this2._removeHrOnBackspace(range, ev); + } + + return true; + }); + } + + /** + * _isInHr + * Check whether passed range is in hr or not + * @param {Range} range range + * @returns {boolean} result + * @memberof WwHrManager + * @private + */ + + }, { + key: '_isInHr', + value: function _isInHr(range) { + return _domUtils2.default.getNodeName(range.startContainer.childNodes[range.startOffset]) === 'HR'; + } + + /** + * _isNearHr + * Check whether passed range is near hr or not + * @param {Range} range range + * @returns {boolean} result + * @memberof WwHrManager + * @private + */ + + }, { + key: '_isNearHr', + value: function _isNearHr(range) { + var prevNode = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset - 1); + + return _domUtils2.default.getNodeName(prevNode) === 'HR'; + } + + /** + * Handler for delete HR when user typing within + * @param {Range} range Range object + * @memberof WwHrManager + * @private + */ + + }, { + key: '_onTypedInHr', + value: function _onTypedInHr(range) { + var _this3 = this; + + // in case user try to input above hr + if (this._isInHr(range) || this._isNearHr(range)) { + this.wwe.defer(function (wwe) { + wwe.saveSelection(); + _this3._wrapDefaultBlockToOrphanTexts(); + wwe.restoreSavedSelection(); + }); + } + } + + /** + * _removeHrOnEnter + * Remove hr if need on enter + * @param {Range} range range + * @param {Event} ev event + * @returns {boolean} return true if hr was removed + * @memberof WwHrManager + * @private + */ + + }, { + key: '_removeHrOnEnter', + value: function _removeHrOnEnter(range, ev) { + var hrSuspect = void 0, + blockPosition = void 0; + + if (this._isInHr(range)) { + hrSuspect = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset); + } else if (this._isNearHr(range)) { + hrSuspect = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset - 1); + blockPosition = 'before'; + } + + return this._changeHrToNewDefaultBlock(hrSuspect, range, ev, blockPosition); + } + + /** + * _removeHrOnBackspace + * Remove hr if need on backspace + * @param {Range} range range + * @param {Event} ev event + * @returns {boolean} return true if hr was removed + * @memberof WwHrManager + * @private + */ + + }, { + key: '_removeHrOnBackspace', + value: function _removeHrOnBackspace(range, ev) { + var hrSuspect = void 0, + blockPosition = void 0; + + if (this._isInHr(range)) { + hrSuspect = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset); + } else if (range.startOffset === 0) { + hrSuspect = _domUtils2.default.getTopPrevNodeUnder(range.startContainer, this.wwe.get$Body()[0]); + blockPosition = 'none'; + } else if (this._isNearHr(range)) { + hrSuspect = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset - 1); + blockPosition = 'before'; + } + + return this._changeHrToNewDefaultBlock(hrSuspect, range, ev, blockPosition); + } + + /** + * _changeHrToNewDefaultBlock + * Remove hr and add new default block then set range to it + * @param {Node} hrSuspect Node could be hr + * @param {Range} range range + * @param {Event} ev event + * @param {strong} newBlockPosition new default block add position + * @returns {boolean} return true if hr was removed + * @memberof WwHrManager + * @private + */ + + }, { + key: '_changeHrToNewDefaultBlock', + value: function _changeHrToNewDefaultBlock(hrSuspect, range, ev, newBlockPosition) { + if (hrSuspect && _domUtils2.default.getNodeName(hrSuspect) === 'HR') { + ev.preventDefault(); + + if (newBlockPosition !== 'none') { + this.wwe.breakToNewDefaultBlock(range, newBlockPosition); + } + + (0, _jquery2.default)(hrSuspect).remove(); + + return false; + } + + return true; + } + + /** + * _unwrapDivOnHr + * Unwrap default block on hr + * @memberof WwHrManager + * @private + */ + + }, { + key: '_unwrapDivOnHr', + value: function _unwrapDivOnHr() { + var editorContentBody = this.wwe.get$Body().get(0); + this.wwe.get$Body().find('hr').each(function (index, node) { + var parentDiv = (0, _jquery2.default)(node).parent('div'); + if (parentDiv[0] !== editorContentBody) { + parentDiv.find('br').remove(); + (0, _jquery2.default)(node).unwrap(); + } + }); + } + + /** + * _wrapDefaultBlockToOrphanTexts + * Wrap default block to orphan texts + * mainly, this is used for orphan text that made by controlling hr + * @memberof WwHrManager + * @private + */ + + }, { + key: '_wrapDefaultBlockToOrphanTexts', + value: function _wrapDefaultBlockToOrphanTexts() { + var textNodes = this.wwe.get$Body().contents().filter(findTextNodeFilter); + + textNodes.each(function (i, node) { + (0, _jquery2.default)(node).wrap('
    '); + }); + } + }]); + + return WwHrManager; +}(); + +/** + * findTextNodeFilter + * @function + * @this Node + * @returns {boolean} + * @ignore + */ + + +function findTextNodeFilter() { + return this.nodeType === Node.TEXT_NODE; +} + +exports.default = WwHrManager; + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg p tag manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class WwPManager + */ +var WwPManager = function () { + /** + * Creates an instance of WwPManager. + * @param {WysiwygEditor} wwe - wysiwygEditor instance + * @memberof WwPManager + */ + function WwPManager(wwe) { + _classCallCheck(this, WwPManager); + + this.wwe = wwe; + this.eventManager = wwe.eventManager; + + /** + * Name property + * @memberof WwPManager# + * @type {string} + */ + this.name = 'p'; + + this._initEvent(); + } + + /** + * _initEvent + * Initialize event + * @memberof WwPManager + * @private + */ + + + _createClass(WwPManager, [{ + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this.eventManager.listen('wysiwygSetValueBefore', function (html) { + return _this._splitPtagContentLines(html); + }); + + this.eventManager.listen('wysiwygSetValueAfter', function () { + _this._ensurePtagContentWrappedWithDiv(); + _this._unwrapPtags(); + }); + } + + /** + * Split multiple line content of p tags + * @param {string} html html text + * @returns {string} result + * @private + */ + + }, { + key: '_splitPtagContentLines', + value: function _splitPtagContentLines(html) { + if (html) { + var $wrapper = (0, _jquery2.default)('
    '); + + $wrapper.html(html); + $wrapper.find('p').each(function (pIndex, para) { + var content = para.innerHTML; + var lines = content.split(/
    /gi); + var lastIndex = lines.length - 1; + // cross browsing: old browser not has nextElementSibling attribute + var nextElement = para.nextElementSibling || para.nextSibling; + var splitedContent = ''; + + splitedContent = lines.map(function (line, index) { + var result = ''; + + if (index > 0 && index < lastIndex) { + line = line ? line : '
    '; + } + + if (line) { + result = '
    ' + line + '
    '; + } + + return result; + }); + + // For paragraph, we add empty line + if (nextElement && nextElement.nodeName === 'P') { + splitedContent.push('

    '); + } + + (0, _jquery2.default)(para).replaceWith((0, _jquery2.default)(splitedContent.join(''))); + }); + html = $wrapper.html(); + } + + return html; + } + + /** + * _ensurePtagContentWrappedWithDiv + * Wrap new line inside P tag to DIV, and additional empty line added within too + * @memberof WwPManager + * @private + */ + + }, { + key: '_ensurePtagContentWrappedWithDiv', + value: function _ensurePtagContentWrappedWithDiv() { + this.wwe.get$Body().find('p').each(function (index, node) { + if ((0, _jquery2.default)(node).find('div').length <= 0) { + (0, _jquery2.default)(node).wrapInner('
    '); + } + + if ((0, _jquery2.default)(node).next().is('p')) { + (0, _jquery2.default)(node).append('

    '); + } + }); + } + + /** + * _unwrapPtags + * Unwrap P tag + * @memberof WwPManager + * @private + */ + + }, { + key: '_unwrapPtags', + value: function _unwrapPtags() { + this.wwe.get$Body().find('div').each(function (index, node) { + if ((0, _jquery2.default)(node).parent().is('p')) { + (0, _jquery2.default)(node).unwrap(); + } + }); + } + }]); + + return WwPManager; +}(); + +exports.default = WwPManager; + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements wysiwyg heading manager + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var FIND_HEADING_RX = /h[\d]/i; + +/** + * Class WwHeadingManager + */ + +var WwHeadingManager = function () { + /** + * Creates an instance of WwHeadingManager. + * @param {WysiwygEditor} wwe - WysiwygEditor instance + * @memberof WwHeadingManager + */ + function WwHeadingManager(wwe) { + _classCallCheck(this, WwHeadingManager); + + this.wwe = wwe; + this.eventManager = wwe.eventManager; + + /** + * Name property + * @memberof WwHeadingManager# + * @type {string} + */ + this.name = 'heading'; + + this._init(); + } + + /** + * _init + * Initialize + * @memberof WwHeadingManager + * @private + */ + + + _createClass(WwHeadingManager, [{ + key: '_init', + value: function _init() { + this._initEvent(); + this._initKeyHandler(); + } + }, { + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this.eventManager.listen('wysiwygSetValueAfter', function () { + _this._wrapDefaultBlockToHeadingInner(); + }); + } + + /** + * _initKeyHandler + * Initialize key event handler + * @memberof WwHeadingManager + * @private + */ + + }, { + key: '_initKeyHandler', + value: function _initKeyHandler() { + var _this2 = this; + + this.wwe.addKeyEventHandler('ENTER', function (ev, range) { + if (_this2.wwe.hasFormatWithRx(FIND_HEADING_RX)) { + _this2._onEnter(ev, range); + + return false; + } + + return true; + }); + + this.wwe.addKeyEventHandler('BACK_SPACE', function (ev, range) { + if (_this2.wwe.hasFormatWithRx(FIND_HEADING_RX)) { + _this2._removePrevTopNodeIfNeed(ev, range); + + return false; + } + + return true; + }); + } + + /** + * _wrapDefaultBlockToHeadingInner + * Wrap default block to heading inner contents + * @private + */ + + }, { + key: '_wrapDefaultBlockToHeadingInner', + value: function _wrapDefaultBlockToHeadingInner() { + this.wwe.get$Body().find('h1, h2, h3, h4, h5, h6').each(function (index, node) { + if ((0, _jquery2.default)(node).children('div, p').length <= 0) { + (0, _jquery2.default)(node).wrapInner('
    '); + } + }); + } + + /** + * _unwrapHeading + * Unwrap heading + * @memberof WwHeadingManager + * @private + */ + + }, { + key: '_unwrapHeading', + value: function _unwrapHeading() { + this.wwe.unwrapBlockTag(function (node) { + return FIND_HEADING_RX.test(node); + }); + } + + /** + * _onEnter + * Enter key handler + * @memberof WwHeadingManager + * @param {Event} event event object + * @param {Range} range range + * @private + */ + + }, { + key: '_onEnter', + value: function _onEnter(event, range) { + var _this3 = this; + + if (range.startOffset > 0) { + // I hate this but there's no way + this.wwe.defer(function (wwe) { + _this3._unwrapHeading(); + wwe.getEditor().removeLastUndoStack(); + }); + } else { + event.preventDefault(); + this._insertEmptyBlockToPrevious(range); + } + } + + /** + * _insertEmptyBlockToPrevious + * Insert empty block to previous of passed range + * @memberof WwHeadingManager + * @param {Range} range range + * @private + */ + + }, { + key: '_insertEmptyBlockToPrevious', + value: function _insertEmptyBlockToPrevious(range) { + this.wwe.getEditor().saveUndoState(range); + (0, _jquery2.default)('

    ').insertBefore(_domUtils2.default.getParentUntil(range.startContainer, this.wwe.get$Body()[0])); + } + + /** + * _removePrevTopNodeIfNeed + * Remove previous top node if need + * @memberof WwHeadingManager + * @param {Event} event event object + * @param {Range} range range + * @returns {Boolean} whether needed or not + * @private + */ + + }, { + key: '_removePrevTopNodeIfNeed', + value: function _removePrevTopNodeIfNeed(event, range) { + var isHandled = false; + + if (range.collapsed && range.startOffset === 0) { + var startContainer = range.startContainer; + + var prevTopNode = _domUtils2.default.getTopPrevNodeUnder(startContainer, this.wwe.get$Body()[0]); + var isPrevTopNodeEmpty = prevTopNode && prevTopNode.textContent.length === 0; + var sq = this.wwe.getEditor(); + + if (startContainer.textContent.length === 0) { + isHandled = this._removeHedingAndChangeSelection(event, range, prevTopNode); + } else if (isPrevTopNodeEmpty) { + event.preventDefault(); + sq.saveUndoState(range); + + (0, _jquery2.default)(prevTopNode).remove(); + isHandled = true; + } + } + + return isHandled; + } + + /** + * Remove heading and change selection + * @param {object} event Event object + * @param {Range} range Range object + * @param {HTMLElement} prevTopNode Previous top node + * @returns {boolean} + * @private + */ + + }, { + key: '_removeHedingAndChangeSelection', + value: function _removeHedingAndChangeSelection(event, range, prevTopNode) { + var startContainer = range.startContainer; + + var sq = this.wwe.getEditor(); + var $Body = this.wwe.get$Body(); + var isHeading = FIND_HEADING_RX.test(_domUtils2.default.getNodeName(startContainer)); + var headingElement = isHeading ? startContainer : (0, _jquery2.default)(startContainer).parents('h1,h2,h3,h4,h5,h6')[0]; + var targetNode = prevTopNode; + var offset = 1; + + if (!event.defaultPrevented) { + event.preventDefault(); + sq.saveUndoState(range); + } + + (0, _jquery2.default)(headingElement).remove(); + + if (!prevTopNode) { + targetNode = $Body.children('div').first().get(0); + offset = 0; + } + + range.setStart(targetNode, offset); + range.collapse(true); + sq.setSelection(range); + + return true; + } + }]); + + return WwHeadingManager; +}(); + +exports.default = WwHeadingManager; + +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _squireRte = __webpack_require__(77); + +var _squireRte2 = _interopRequireDefault(_squireRte); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _util = __webpack_require__(38); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements squire extension + * @author NHN Ent. FE Development Lab + */ + + +var FIND_BLOCK_TAGNAME_RX = /\b(H[\d]|LI|P|BLOCKQUOTE|TD)\b/; +var isIElt11 = /Trident\/[456]\./.test(navigator.userAgent); + +/** + * Class SquireExt + * @extends {Squire} + */ + +var SquireExt = function (_Squire) { + _inherits(SquireExt, _Squire); + + /** + * Creates an instance of SquireExt. + * @augments Squire + * @memberof SquireExt + */ + function SquireExt() { + var _ref; + + _classCallCheck(this, SquireExt); + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var _this = _possibleConstructorReturn(this, (_ref = SquireExt.__proto__ || Object.getPrototypeOf(SquireExt)).call.apply(_ref, [this].concat(args))); + + _this._decorateHandlerToCancelable('copy'); + _this._decorateHandlerToCancelable(isIElt11 ? 'beforecut' : 'cut'); + _this._decorateHandlerToCancelable(isIElt11 ? 'beforepaste' : 'paste'); + + _this.get$Body = function () { + _this.$body = _this.$body || (0, _jquery2.default)(_this.getRoot()); + + return _this.$body; + }; + return _this; + } + + /** + * _decorateHandlerToCancelable + * Decorate squire handler to cancelable cuz sometimes, we dont need squire handler process + * event.preventDefault() will cancel squire and browser default behavior + * event.squirePrevented = true will cancel squire but allow browser default behavior + * @param {string} eventName event name + * @private + */ + + + _createClass(SquireExt, [{ + key: '_decorateHandlerToCancelable', + value: function _decorateHandlerToCancelable(eventName) { + var handlers = this._events[eventName]; + + if (handlers.length > 1) { + throw new Error('too many' + eventName + 'handlers in squire'); + } + + var handler = handlers[0].bind(this); + + handlers[0] = function (event) { + if (!event.defaultPrevented && !event.squirePrevented) { + handler(event); + } + }; + } + }, { + key: 'changeBlockFormat', + value: function changeBlockFormat(srcCondition, targetTagName) { + var _this2 = this; + + this.modifyBlocks(function (frag) { + var current = void 0, + newFrag = void 0, + newBlock = void 0, + nextBlock = void 0, + tagName = void 0, + lastNodeOfNextBlock = void 0, + appendChidToNextBlock = void 0; + + // HR is non-block element, so frag don't have it + // make a default block + if (frag.childNodes.length) { + current = frag.childNodes.item(0); + } else { + current = _this2.createDefaultBlock(); + frag.appendChild(current); + } + + if (srcCondition) { + // find last depth + while (current.firstChild) { + current = current.firstChild; + } + + appendChidToNextBlock = function appendChidToNextBlock(node) { + nextBlock.appendChild(node); + }; + + // find tag + while (current !== frag) { + var _current = current; + tagName = _current.tagName; + + + if (_tuiCodeSnippet2.default.isFunction(srcCondition) ? srcCondition(tagName) : tagName === srcCondition) { + nextBlock = current.childNodes.item(0); + + // there is no next blocktag + // eslint-disable-next-line max-depth + if (!_domUtils2.default.isElemNode(nextBlock) || current.childNodes.length > 1) { + nextBlock = _this2.createDefaultBlock(); + + _tuiCodeSnippet2.default.forEachArray(_tuiCodeSnippet2.default.toArray(current.childNodes), appendChidToNextBlock); + + lastNodeOfNextBlock = nextBlock.lastChild; + + // remove unneccesary br + // eslint-disable-next-line max-depth + if (lastNodeOfNextBlock && _domUtils2.default.getNodeName(lastNodeOfNextBlock) === 'BR') { + nextBlock.removeChild(lastNodeOfNextBlock); + } + } + + // eslint-disable-next-line max-depth + if (targetTagName) { + newBlock = _this2.createElement(targetTagName, [nextBlock]); + } else { + newBlock = nextBlock; + } + + newFrag = _this2.getDocument().createDocumentFragment(); + newFrag.appendChild(newBlock); + + frag = newFrag; + + break; + } + + current = current.parentNode; + } + } + + // if source condition node is not founded, we wrap current div node with node named targetTagName + if ((!newFrag || !srcCondition) && targetTagName && _domUtils2.default.getNodeName(frag.childNodes[0]) === 'DIV') { + frag = _this2.createElement(targetTagName, [frag.childNodes[0]]); + } + + return frag; + }); + } + }, { + key: 'changeBlockFormatTo', + value: function changeBlockFormatTo(targetTagName) { + this.changeBlockFormat(function (tagName) { + return FIND_BLOCK_TAGNAME_RX.test(tagName); + }, targetTagName); + } + }, { + key: 'getCaretPosition', + value: function getCaretPosition() { + return this.getCursorPosition(); + } + }, { + key: 'replaceSelection', + value: function replaceSelection(content, selection) { + if (selection) { + this.setSelection(selection); + } + + this._ignoreChange = true; + this.insertHTML(content); + } + }, { + key: 'replaceRelativeOffset', + value: function replaceRelativeOffset(content, offset, overwriteLength) { + var selection = this.getSelection().cloneRange(); + + this._replaceRelativeOffsetOfSelection(content, offset, overwriteLength, selection); + } + }, { + key: '_replaceRelativeOffsetOfSelection', + value: function _replaceRelativeOffsetOfSelection(content, offset, overwriteLength, selection) { + var startSelectionInfo = void 0, + endSelectionInfo = void 0, + finalOffset = void 0; + var endOffsetNode = selection.endContainer; + var endTextOffset = selection.endOffset; + + if (_domUtils2.default.getNodeName(endOffsetNode) !== 'TEXT') { + endOffsetNode = this._getClosestTextNode(endOffsetNode, endTextOffset); + + if (endOffsetNode) { + if (_domUtils2.default.isTextNode(endOffsetNode)) { + endTextOffset = endOffsetNode.nodeValue.length; + } else { + endTextOffset = endOffsetNode.textContent.length; + } + } + } + + if (endOffsetNode) { + startSelectionInfo = this.getSelectionInfoByOffset(endOffsetNode, endTextOffset + offset); + selection.setStart(startSelectionInfo.element, startSelectionInfo.offset); + + finalOffset = endTextOffset + (offset + overwriteLength); + endSelectionInfo = this.getSelectionInfoByOffset(endOffsetNode, finalOffset); + selection.setEnd(endSelectionInfo.element, endSelectionInfo.offset); + + this.replaceSelection(content, selection); + } else { + this.replaceSelection(content); + } + } + }, { + key: '_getClosestTextNode', + value: function _getClosestTextNode(node, offset) { + var foundNode = _domUtils2.default.getChildNodeByOffset(node, offset - 1); + + if (_domUtils2.default.getNodeName(foundNode) !== 'TEXT') { + foundNode = foundNode.previousSibling; + } + + return foundNode; + } + }, { + key: 'getSelectionInfoByOffset', + value: function getSelectionInfoByOffset(anchorElement, offset) { + var traceElement = void 0, + traceElementLength = void 0, + traceOffset = void 0, + stepLength = void 0; + var direction = offset >= 0 ? 'next' : 'previous'; + var offsetAbs = Math.abs(offset); + var latestAvailableElement = traceElement; + + if (direction === 'next') { + traceElement = anchorElement; + } else { + traceElement = anchorElement.previousSibling; + } + + traceOffset = offsetAbs; + stepLength = 0; + + while (traceElement) { + if (_domUtils2.default.isTextNode(traceElement)) { + traceElementLength = traceElement.nodeValue.length; + } else { + traceElementLength = traceElement.textContent.length; + } + + stepLength += traceElementLength; + + if (offsetAbs <= stepLength) { + break; + } + + traceOffset -= traceElementLength; + + if (_domUtils2.default.getTextLength(traceElement) > 0) { + latestAvailableElement = traceElement; + } + + traceElement = traceElement[direction + 'Sibling']; + } + + if (!traceElement) { + traceElement = latestAvailableElement; + traceOffset = _domUtils2.default.getTextLength(traceElement); + } + + if (direction === 'previous') { + traceOffset = _domUtils2.default.getTextLength(traceElement) - traceOffset; + } + + return { + element: traceElement, + offset: traceOffset + }; + } + }, { + key: 'getSelectionPosition', + value: function getSelectionPosition(selection, style, offset) { + var marker = this.createElement('INPUT'); + var range = selection.cloneRange(); + var endSelectionInfo = this.getSelectionInfoByOffset(selection.endContainer, selection.endOffset + (offset || 0)); + range.setStart(range.startContainer, range.startOffset); + range.setEnd(endSelectionInfo.element, endSelectionInfo.offset); + + // to prevent squire input event fire + this._ignoreChange = true; + this.insertElement(marker, range); + + var pos = (0, _jquery2.default)(marker).offset(); + + if (style !== 'over') { + pos.top += (0, _jquery2.default)(marker).outerHeight(); + } + + marker.parentNode.removeChild(marker); + + selection.setStart(selection.endContainer, selection.endOffset); + selection.collapse(true); + + this.setSelection(selection); + + return pos; + } + }, { + key: 'removeLastUndoStack', + value: function removeLastUndoStack() { + if (this._undoStack.length) { + this._undoStackLength -= 1; + this._undoIndex -= 1; + this._undoStack.pop(); + this._isInUndoState = false; + } + } + }, { + key: 'replaceParent', + value: function replaceParent(node, from, to) { + var target = (0, _jquery2.default)(node).closest(from); + + if (target.length) { + target.wrapInner('<' + to + '/>'); + target.children().unwrap(); + } + } + }, { + key: 'preserveLastLine', + value: function preserveLastLine() { + var lastBlock = this.get$Body().children().last(); + + if (_domUtils2.default.getNodeName(lastBlock[0]) !== 'DIV') { + this._ignoreChange = true; + (0, _jquery2.default)(this.createDefaultBlock()).insertAfter(lastBlock); + } + } + }, { + key: 'scrollTop', + value: function scrollTop(top) { + if (_tuiCodeSnippet2.default.isUndefined(top)) { + return this.get$Body().scrollTop(); + } + + return this.get$Body().scrollTop(top); + } + }, { + key: 'isIgnoreChange', + value: function isIgnoreChange() { + return this._ignoreChange; + } + }, { + key: 'focus', + value: function focus() { + _squireRte2.default.prototype.focus.call(this); + } + }, { + key: 'blockCommandShortcuts', + value: function blockCommandShortcuts() { + var _this3 = this; + + var meta = _util.isMac ? 'meta' : 'ctrl'; + var keys = ['b', 'i', 'u', 'shift-7', 'shift-5', 'shift-6', 'shift-8', 'shift-9', '[', ']', 'd']; + + keys.forEach(function (key) { + _this3.setKeyHandler(meta + '-' + key, function (editor, keyboardEvent) { + keyboardEvent.preventDefault(); + }); + }); + } + }]); + + return SquireExt; +}(_squireRte2.default); + +exports.default = SquireExt; + +/***/ }), +/* 77 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_77__; + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements WwTextObject + * @author NHN Ent. FE Development Lab + */ + + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var isIE11 = _tuiCodeSnippet2.default.browser.msie && _tuiCodeSnippet2.default.browser.version === 11; +var isWindowChrome = navigator.appVersion.indexOf('Win') !== -1 && _tuiCodeSnippet2.default.browser.chrome; +var isNeedOffsetFix = isIE11 || isWindowChrome; + +/** + * Class WwTextObject + */ + +var WwTextObject = function () { + /** + * Creates an instance of WwTextObject. + * @param {WysiwygEditor} wwe - wysiwygEditor + * @param {Range} range - Range object + * @memberof WwTextObject + */ + function WwTextObject(wwe, range) { + _classCallCheck(this, WwTextObject); + + this._wwe = wwe; + + // msie11 and window chrome can't make start offset of range api correctly when compositing korean. + // so we need fix this when compositing korean.(and maybe other languages that needs composition.) + if (isNeedOffsetFix) { + this.isComposition = false; + this._initCompositionEvent(); + } + + this.setRange(range || this._wwe.getRange()); + } + + /** + * Initialize composition event + * @memberof WwTextObject + * @private + */ + + + _createClass(WwTextObject, [{ + key: '_initCompositionEvent', + value: function _initCompositionEvent() { + var _this = this; + + this._wwe.getEditor().addEventListener('compositionstart', function () { + _this.isComposition = true; + }); + + this._wwe.getEditor().addEventListener('compositionend', function () { + _this.isComposition = false; + }); + } + + /** + * Set _range object to given range object + * @param {Range} range Range object + * @memberof WwTextObject + */ + + }, { + key: 'setRange', + value: function setRange(range) { + if (this._range) { + this._range.detach(); + } + + this._range = range; + } + + /** + * Expand start offset by one + * @memberof WwTextObject + */ + + }, { + key: 'expandStartOffset', + value: function expandStartOffset() { + var range = this._range; + + if (_domUtils2.default.isTextNode(range.startContainer) && range.startOffset > 0) { + range.setStart(range.startContainer, range.startOffset - 1); + } + } + + /** + * Expand end offset by one + * @memberof WwTextObject + */ + + }, { + key: 'expandEndOffset', + value: function expandEndOffset() { + var range = this._range; + + if (_domUtils2.default.isTextNode(range.endContainer) && range.endOffset < range.endContainer.nodeValue.length) { + range.setEnd(range.endContainer, range.endOffset + 1); + } + } + + /** + * setEnd range on start + * @param {Range} range Range object + * @memberof WwTextObject + */ + + }, { + key: 'setEndBeforeRange', + value: function setEndBeforeRange(range) { + var offset = range.startOffset; + + if (this.isComposition) { + offset += 1; + } + + this._range.setEnd(range.startContainer, offset); + } + + /** + * Get text content + * @returns {string} + * @memberof WwTextObject + */ + + }, { + key: 'getTextContent', + value: function getTextContent() { + return this._range.cloneContents().textContent; + } + + /** + * Replace current selection content to given text + * @param {string} content Text content + * @memberof WwTextObject + */ + + }, { + key: 'replaceContent', + value: function replaceContent(content) { + this._wwe.getEditor().setSelection(this._range); + this._wwe.getEditor().insertHTML(content); + this._range = this._wwe.getRange(); + } + + /** + * Delete current selection content + * @memberof WwTextObject + */ + + }, { + key: 'deleteContent', + value: function deleteContent() { + this._wwe.getEditor().setSelection(this._range); + this._wwe.getEditor().insertHTML(''); + this._range = this._wwe.getRange(); + } + + /** + * Peek previous element's content + * @param {number} offset Offset to peek + * @returns {string} + * @memberof WwTextObject + */ + + }, { + key: 'peekStartBeforeOffset', + value: function peekStartBeforeOffset(offset) { + var range = this._range.cloneRange(); + + range.setStart(range.startContainer, Math.max(range.startOffset - offset, 0)); + range.setEnd(this._range.startContainer, this._range.startOffset); + + return range.cloneContents().textContent; + } + }]); + + return WwTextObject; +}(); + +exports.default = WwTextObject; + +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _blockOverlay = __webpack_require__(80); + +var _blockOverlay2 = _interopRequireDefault(_blockOverlay); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements UI code block gadget + * @author NHN Ent. FE Development Lab + */ + + +var EVENT_LANGUAGE_CHANGED = 'language-changed'; +var GADGET_WIDTH = 250; +var GADGET_HEIGHT = 30; + +/** + * Class CodeBlockGadget + * @extends {BlockOverlay} + */ + +var CodeBlockGadget = function (_BlockOverlay) { + _inherits(CodeBlockGadget, _BlockOverlay); + + /** + * Creates an instance of CodeBlockGadget. + * @param {Object} options - options + * @param {EventManager} options.eventManager - event manager instance + * @param {HTMLElement} options.container - container element + * @param {WysiwygEditor} options.wysiwygEditor - wysiwyg editor instance + * @memberof CodeBlockGadget + */ + function CodeBlockGadget(_ref) { + var eventManager = _ref.eventManager, + container = _ref.container, + wysiwygEditor = _ref.wysiwygEditor; + + _classCallCheck(this, CodeBlockGadget); + + var _this = _possibleConstructorReturn(this, (CodeBlockGadget.__proto__ || Object.getPrototypeOf(CodeBlockGadget)).call(this, { + eventManager: eventManager, + container: container, + attachedSelector: 'pre' + })); + + _this._wysiwygEditor = wysiwygEditor; + _this._popupCodeBlockLanguages = null; + + _this._initDOM(); + _this._initDOMEvent(); + return _this; + } + + _createClass(CodeBlockGadget, [{ + key: '_initDOM', + value: function _initDOM() { + this.$el.addClass('code-block-header'); + this._$languageLabel = (0, _jquery2.default)('text'); + this.$el.append(this._$languageLabel); + this._$buttonOpenModalEditor = (0, _jquery2.default)(''); + this.$el.append(this._$buttonOpenModalEditor); + } + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + this._$buttonOpenModalEditor.on('click', function () { + return _this2._openPopupCodeBlockEditor(); + }); + } + }, { + key: '_openPopupCodeBlockEditor', + value: function _openPopupCodeBlockEditor() { + this._eventManager.emit('openPopupCodeBlockEditor', this.getAttachedElement()); + } + }, { + key: '_updateLanguage', + value: function _updateLanguage() { + var attachedElement = this.getAttachedElement(); + var language = attachedElement ? attachedElement.getAttribute('data-language') : null; + + this._$languageLabel.text(language ? language : 'text'); + } + + /** + * update gadget position + * @memberof CodeBlockGadget + * @protected + * @override + */ + + }, { + key: 'syncLayout', + value: function syncLayout() { + var $attachedElement = (0, _jquery2.default)(this.getAttachedElement()); + var offset = $attachedElement.offset(); + + offset.left = offset.left + ($attachedElement.outerWidth() - GADGET_WIDTH); + + this.$el.offset(offset); + this.$el.height(GADGET_HEIGHT); + this.$el.width(GADGET_WIDTH); + } + + /** + * on show + * @memberof CodeBlockGadget + * @protected + * @override + */ + + }, { + key: 'onShow', + value: function onShow() { + var _this3 = this; + + _get(CodeBlockGadget.prototype.__proto__ || Object.getPrototypeOf(CodeBlockGadget.prototype), 'onShow', this).call(this); + + this._onAttachedElementChange = function () { + return _this3._updateLanguage(); + }; + (0, _jquery2.default)(this.getAttachedElement()).on(EVENT_LANGUAGE_CHANGED, this._onAttachedElementChange); + + this._updateLanguage(); + } + + /** + * on hide + * @memberof CodeBlockGadget + * @protected + * @override + */ + + }, { + key: 'onHide', + value: function onHide() { + (0, _jquery2.default)(this.getAttachedElement()).off(EVENT_LANGUAGE_CHANGED, this._onAttachedElementChange); + + _get(CodeBlockGadget.prototype.__proto__ || Object.getPrototypeOf(CodeBlockGadget.prototype), 'onHide', this).call(this); + } + }]); + + return CodeBlockGadget; +}(_blockOverlay2.default); + +exports.default = CodeBlockGadget; + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements UI block overlay + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class BlockOverlay + */ +var BlockOverlay = function () { + /** + * Creates an instance of BlockOverlay. + * @param {Object} options - options + * @param {EventManager} options.eventManager - event manager instance + * @param {HTMLElement} options.container - container element + * @param {string} options.attachedSelector - selector string to find attached element + * @memberof BlockOverlay + */ + function BlockOverlay(_ref) { + var eventManager = _ref.eventManager, + container = _ref.container, + attachedSelector = _ref.attachedSelector; + + _classCallCheck(this, BlockOverlay); + + this._eventManager = eventManager; + this._attachedSelector = '[contenteditable=true] ' + attachedSelector; + this._$container = (0, _jquery2.default)(container); + this._$attachedElement = null; + + /** + * is activated. + * if this blockOverlay is active, It always be visible unconditionally. + * @type {boolean} + */ + this.active = false; + + this._createElement(); + this._initEvent(); + } + + _createClass(BlockOverlay, [{ + key: '_createElement', + value: function _createElement() { + this.$el = (0, _jquery2.default)('
    '); + this.$el.css({ + position: 'absolute', + display: 'none', + 'z-index': 1 + }); + this._$container.append(this.$el); + } + }, { + key: '_initEvent', + value: function _initEvent() { + var _this = this; + + this._eventManager.listen('change', this._onChange.bind(this)); + this._eventManager.listen('mouseover', this._onMouseOver.bind(this)); + this._eventManager.listen('focus', function () { + _this.setVisibility(false); + }); + this._eventManager.listen('mousedown', function () { + _this.setVisibility(false); + }); + } + }, { + key: '_onChange', + value: function _onChange() { + if (this._$attachedElement && _jquery2.default.contains(document, this._$attachedElement[0])) { + this.syncLayout(); + } else { + this.setVisibility(false); + } + } + }, { + key: '_onMouseOver', + value: function _onMouseOver(ev) { + var originalEvent = ev.data; + var $eventTarget = (0, _jquery2.default)(originalEvent.target); + var $attachedElement = $eventTarget.closest(this._attachedSelector); + + if ($attachedElement.length) { + this._$attachedElement = $attachedElement; + this.setVisibility(true); + } else if ($eventTarget.closest(this.$el).length) { + this.setVisibility(true); + } else if (!this.active) { + this.setVisibility(false); + } + } + + /** + * update blockOverlay position & size update to attached element + * you may want to override this to adjust position & size + * @memberof BlockOverlay + * @protected + */ + + }, { + key: 'syncLayout', + value: function syncLayout() { + this.$el.offset(this._$attachedElement.offset()); + this.$el.width(this._$attachedElement.outerWidth()); + this.$el.height(this._$attachedElement.outerHeight()); + } + + /** + * attached element + * @protected + * @returns {HTMLElement} - attached element + * @memberof BlockOverlay + */ + + }, { + key: 'getAttachedElement', + value: function getAttachedElement() { + return this._$attachedElement ? this._$attachedElement.get(0) : null; + } + + /** + * visibility + * @protected + * @returns {boolean} visibility + * @memberof BlockOverlay + */ + + }, { + key: 'getVisibility', + value: function getVisibility() { + return this.$el.css('display') === 'block'; + } + + /** + * visibility + * @param {boolean} visibility - is visible + * @protected + * @memberof BlockOverlay + */ + + }, { + key: 'setVisibility', + value: function setVisibility(visibility) { + if (visibility && this._$attachedElement) { + if (!this.getVisibility()) { + this.$el.css('display', 'block'); + this.syncLayout(); + this.onShow(); + } + } else if (!visibility) { + if (this.getVisibility()) { + this.$el.css('display', 'none'); + this.onHide(); + } + } + } + + /** + * called on show. you may want to override to get the event + * @memberof BlockOverlay + * @protected + * @abstract + */ + + }, { + key: 'onShow', + value: function onShow() {} + + /** + * called on hide. you may want to override to get the event + * @memberof BlockOverlay + * @protected + */ + + }, { + key: 'onHide', + value: function onHide() { + this.active = false; + this._$attachedElement = null; + } + }]); + + return BlockOverlay; +}(); + +exports.default = BlockOverlay; + +/***/ }), +/* 81 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview editor layout + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Editor container template + * @type {string} + * @ignore + */ +var containerTmpl = ['
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '
    '].join(''); + +/** + * Class Layout + */ + +var Layout = function () { + /** + * Creates an instance of Layout. + * @param {object} options - Option object + * @param {EventManager} eventManager - Event manager instance + * @memberof Layout + */ + function Layout(options, eventManager) { + _classCallCheck(this, Layout); + + this.$el = (0, _jquery2.default)(options.el); + this.height = options.height; + this.type = options.initialEditType; + this.eventManager = eventManager; + + this.init(); + this._initEvent(); + } + + /** + * Initializer + * @memberof Layout + */ + + + _createClass(Layout, [{ + key: 'init', + value: function init() { + this._renderLayout(); + + this._initMarkdownAndPreviewSection(); + this._initWysiwygSection(); + } + + /** + * Initialize show and hide event + * @memberof Layout + * @private + */ + + }, { + key: '_initEvent', + value: function _initEvent() { + this.eventManager.listen('hide', this.hide.bind(this)); + this.eventManager.listen('show', this.show.bind(this)); + } + + /** + * Create editor container with template + * @memberof Layout + * @private + */ + + }, { + key: '_renderLayout', + value: function _renderLayout() { + this.$el.css('box-sizing', 'border-box'); + this.$containerEl = (0, _jquery2.default)(containerTmpl).appendTo(this.$el); + } + + /** + * Switch editor mode to WYSIWYG + * @memberof Layout + */ + + }, { + key: 'switchToWYSIWYG', + value: function switchToWYSIWYG() { + this.$containerEl.removeClass('te-md-mode'); + this.$containerEl.addClass('te-ww-mode'); + } + + /** + * Switch editor mode to Markdown + * @memberof Layout + */ + + }, { + key: 'switchToMarkdown', + value: function switchToMarkdown() { + this.$containerEl.removeClass('te-ww-mode'); + this.$containerEl.addClass('te-md-mode'); + } + + /** + * Initialize editor to Markdown and set preview section + * @memberof Layout + * @private + */ + + }, { + key: '_initMarkdownAndPreviewSection', + value: function _initMarkdownAndPreviewSection() { + this.$mdEditorContainerEl = this.$containerEl.find('.te-md-container .te-editor'); + this.$previewEl = this.$containerEl.find('.te-md-container .te-preview'); + } + + /** + * Initialize editor to WYSIWYG + * @memberof Layout + * @private + */ + + }, { + key: '_initWysiwygSection', + value: function _initWysiwygSection() { + this.$wwEditorContainerEl = this.$containerEl.find('.te-ww-container .te-editor'); + } + + /** + * Set preview to vertical split style + * @memberof Layout + * @private + */ + + }, { + key: '_verticalSplitStyle', + value: function _verticalSplitStyle() { + this.$containerEl.find('.te-md-container').removeClass('te-preview-style-tab'); + this.$containerEl.find('.te-md-container').addClass('te-preview-style-vertical'); + } + + /** + * Set tab style preview mode + * @memberof Layout + * @private + */ + + }, { + key: '_tabStyle', + value: function _tabStyle() { + this.$containerEl.find('.te-md-container').removeClass('te-preview-style-vertical'); + this.$containerEl.find('.te-md-container').addClass('te-preview-style-tab'); + } + + /** + * Toggle preview style between tab and vertical split + * @memberof Layout + * @param {string} style Preview style ('tab' or 'vertical') + */ + + }, { + key: 'changePreviewStyle', + value: function changePreviewStyle(style) { + if (style === 'tab') { + this._tabStyle(); + } else if (style === 'vertical') { + this._verticalSplitStyle(); + } + } + + /** + * Hide Editor + * @memberof Layout + */ + + }, { + key: 'hide', + value: function hide() { + this.$el.find('.tui-editor').addClass('te-hide'); + } + + /** + * Show Editor + * @memberof Layout + */ + + }, { + key: 'show', + value: function show() { + this.$el.find('.tui-editor').removeClass('te-hide'); + } + + /** + * Remove Editor + * @memberof Layout + */ + + }, { + key: 'remove', + value: function remove() { + this.$el.find('.tui-editor').remove(); + } + + /** + * Get jQuery wrapped editor container element + * @memberof Layout + * @returns {jQuery} + */ + + }, { + key: 'getEditorEl', + value: function getEditorEl() { + return this.$containerEl; + } + + /** + * Get jQuery wrapped preview element + * @memberof Layout + * @returns {jQuery} + */ + + }, { + key: 'getPreviewEl', + value: function getPreviewEl() { + return this.$previewEl; + } + + /** + * Get jQuery wrapped Markdown editor element + * @memberof Layout + * @returns {jQuery} + */ + + }, { + key: 'getMdEditorContainerEl', + value: function getMdEditorContainerEl() { + return this.$mdEditorContainerEl; + } + + /** + * Get jQuery wrapped WYSIWYG editor element + * @memberof Layout + * @returns {jQuery} + */ + + }, { + key: 'getWwEditorContainerEl', + value: function getWwEditorContainerEl() { + return this.$wwEditorContainerEl; + } + }]); + + return Layout; +}(); + +exports.default = Layout; + +/***/ }), +/* 82 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements Command + * @author NHN Ent. FE Development Lab + */ + + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class Command + */ +var Command = function () { + /** + * @param {string} name Command name + * @param {number} type Command type (Command.TYPE) + * @param {Array.} [keyMap] keyMap + */ + function Command(name, type, keyMap) { + _classCallCheck(this, Command); + + this.name = name; + this.type = type; + + if (keyMap) { + this.setKeyMap(keyMap); + } + } + /** + * getName + * returns Name of command + * @memberof Command + * @returns {string} Command Name + */ + + + _createClass(Command, [{ + key: 'getName', + value: function getName() { + return this.name; + } + + /** + * getType + * returns Type of command + * @memberof Command + * @returns {number} Command Command type number + */ + + }, { + key: 'getType', + value: function getType() { + return this.type; + } + + /** + * isMDType + * returns whether Command Type is Markdown or not + * @memberof Command + * @returns {boolean} result + */ + + }, { + key: 'isMDType', + value: function isMDType() { + return this.type === Command.TYPE.MD; + } + + /** + * isWWType + * returns whether Command Type is Wysiwyg or not + * @memberof Command + * @returns {boolean} result + */ + + }, { + key: 'isWWType', + value: function isWWType() { + return this.type === Command.TYPE.WW; + } + + /** + * isGlobalType + * returns whether Command Type is Global or not + * @memberof Command + * @returns {boolean} result + */ + + }, { + key: 'isGlobalType', + value: function isGlobalType() { + return this.type === Command.TYPE.GB; + } + + /** + * setKeyMap + * Set keymap value for each os + * @memberof Command + * @param {string} win Windows Key(and etc) + * @param {string} mac Mac osx key + */ + + }, { + key: 'setKeyMap', + value: function setKeyMap(win, mac) { + this.keyMap = [win, mac]; + } + }]); + + return Command; +}(); + +/** + * Command factory method + * @memberof Command + * @param {string} typeStr Editor type name + * @param {object} props Property + * @param {string} props.name Command name + * @param {number} props.type Command type number + * @returns {Command} + */ + + +Command.factory = function (typeStr, props) { + var type = void 0; + + if (typeStr === 'markdown') { + type = Command.TYPE.MD; + } else if (typeStr === 'wysiwyg') { + type = Command.TYPE.WW; + } else if (typeStr === 'global') { + type = Command.TYPE.GB; + } + + var command = new Command(props.name, type); + + _tuiCodeSnippet2.default.extend(command, props); + + return command; +}; + +/** + * Command Type Constant + * markdown : 0 + * wysiwyg : 1 + * global : 2 + * @memberof Command + * @type {object} + */ +Command.TYPE = { + MD: 0, + WW: 1, + GB: 2 +}; + +exports.default = Command; + +/***/ }), +/* 83 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_83__; + +/***/ }), +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Copyright (c) 2016, Revin Guillen. +// Distributed under an MIT license: https://github.com/revin/markdown-it-task-lists/ + +/** + * @fileoverview Implements markdownitTaskPlugin + * @modifier Sungho Kim(sungho-kim@nhnent.com) FE Development Lab/NHN Ent. + * @modifier Junghwan Park(junghwan.park@nhnent.com) FE Development Lab/NHN Ent. + */ +/* eslint-disable */ + +/** + * Task list renderer for Markdown-it + * @param {object} markdownit Markdown-it instance + * @ignore + */ +var MarkdownitTaskRenderer = function MarkdownitTaskRenderer(markdownit) { + markdownit.core.ruler.after('inline', 'tui-task-list', function (state) { + var TASK_LIST_ITEM_CLASS_NAME = 'task-list-item'; + var CHECKED_CLASS_NAME = 'checked'; + var tokens = state.tokens; + var className; + var tokenIndex; + + // tokenIndex=0 'ul', tokenIndex=1 'li', tokenIndex=2 'p_open' + for (tokenIndex = 2; tokenIndex < tokens.length; tokenIndex += 1) { + if (isTaskListItemToken(tokens, tokenIndex)) { + if (isChecked(tokens[tokenIndex])) { + className = TASK_LIST_ITEM_CLASS_NAME + ' ' + CHECKED_CLASS_NAME; + } else { + className = TASK_LIST_ITEM_CLASS_NAME; + } + + removeMarkdownTaskFormatText(tokens[tokenIndex]); + + setTokenAttribute(tokens[tokenIndex - 2], 'class', className); + setTokenAttribute(tokens[tokenIndex - 2], 'data-te-task', ''); + } + } + }); +}; + +/** + * Remove task format text for rendering + * @param {object} token Token object + * @ignore + */ +function removeMarkdownTaskFormatText(token) { + // '[X] ' length is 4 + // FIXED: we don't need first space + token.content = token.content.slice(4); + token.children[0].content = token.children[0].content.slice(4); +} + +/** + * Return boolean value whether task checked or not + * @param {object} token Token object + * @returns {boolean} + * @ignore + */ +function isChecked(token) { + var checked = false; + + if (token.content.indexOf('[x]') === 0 || token.content.indexOf('[X]') === 0) { + checked = true; + } + + return checked; +} + +/** + * Set attribute of passed token + * @param {object} token Token object + * @param {string} attributeName Attribute name for set + * @param {string} attributeValue Attribute value for set + * @ignore + */ +function setTokenAttribute(token, attributeName, attributeValue) { + var index = token.attrIndex(attributeName); + var attr = [attributeName, attributeValue]; + + if (index < 0) { + token.attrPush(attr); + } else { + token.attrs[index] = attr; + } +} + +/** + * Return boolean value whether task list item or not + * @param {array} tokens Token object + * @param {number} index Number of token index + * @returns {boolean} + * @ignore + */ +function isTaskListItemToken(tokens, index) { + return tokens[index].type === 'inline' && tokens[index - 1].type === 'paragraph_open' && tokens[index - 2].type === 'list_item_open' && (tokens[index].content.indexOf('[ ]') === 0 || tokens[index].content.indexOf('[x]') === 0 || tokens[index].content.indexOf('[X]') === 0); +} +/* eslint-enable */ + +module.exports = MarkdownitTaskRenderer; + +/***/ }), +/* 85 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Copyright (c) 2016, Revin Guillen. +// Distributed under an MIT license: https://github.com/revin/markdown-it-task-lists/ +/* eslint-disable */ +/** + * @fileoverview Implements markdownitCodeBlockPlugin + * @modifier NHN Ent. FE Development Lab + */ + +/** + * Code block renderer for Markdown-it + * @param {object} markdownit Markdown-it instance + * @ignore + */ +var MarkdownitCodeBlockRenderer = function MarkdownitCodeBlockRenderer(markdownit) { + markdownit.core.ruler.after('block', 'tui-code-block', function (state) { + var DEFAULT_NUMBER_OF_BACKTICKS = 3; + var tokens = state.tokens; + var currentToken, tokenIndex, numberOfBackticks; + + for (tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) { + currentToken = tokens[tokenIndex]; + + if (isCodeFenceToken(currentToken)) { + numberOfBackticks = currentToken.markup.length; + if (numberOfBackticks > DEFAULT_NUMBER_OF_BACKTICKS) { + setTokenAttribute(currentToken, 'data-backticks', numberOfBackticks, true); + } + if (currentToken.info) { + setTokenAttribute(currentToken, 'data-language', escape(currentToken.info.replace(' ', ''), true)); + } + } + } + }); +}; + +/** + * Set attribute of passed token + * @param {object} token Token object + * @param {string} attributeName Attribute name for set + * @param {string} attributeValue Attribute value for set + * @ignore + */ +function setTokenAttribute(token, attributeName, attributeValue) { + var index = token.attrIndex(attributeName); + var attr = [attributeName, attributeValue]; + + if (index < 0) { + token.attrPush(attr); + } else { + token.attrs[index] = attr; + } +} +/** + * Return boolean value whether passed token is code fence or not + * @param {object} token Token object + * @returns {boolean} + * @ignore + */ +function isCodeFenceToken(token) { + return token.block === true && token.tag === 'code' && token.type === 'fence'; +} + +/** + * escape code from markdown-it + * @param {string} html HTML string + * @param {string} encode Boolean value of whether encode or not + * @returns {string} + * @ignore + */ +function escape(html, encode) { + return html.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, '''); +} +/* eslint-enable */ + +module.exports = MarkdownitCodeBlockRenderer; + +/***/ }), +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. +// Distributed under an ISC license: https://github.com/markdown-it/markdown-it/ +/** + * @fileoverview Implements MarkdownItCodeRenderer + * @modifier NHN Ent. FE Development Lab + */ + +/* eslint-disable */ +module.exports = function code(state, startLine, endLine /*, silent*/) { + // Added by Junghwan Park + var FIND_LIST_RX = / {0,3}(?:-|\*|\d\.) /; + var lines = state.src.split('\n'); + var currentLine = lines[startLine]; + // Added by Junghwan Park + + var nextLine, + last, + token, + emptyLines = 0; + + // Add condition by Junghwan Park + if (currentLine.match(FIND_LIST_RX) || state.sCount[startLine] - state.blkIndent < 4) { + // Add condition by Junghwan Park + return false; + } + + last = nextLine = startLine + 1; + + while (nextLine < endLine) { + if (state.isEmpty(nextLine)) { + emptyLines++; + + // workaround for lists: 2 blank lines should terminate indented + // code block, but not fenced code block + if (emptyLines >= 2 && state.parentType === 'list') { + break; + } + + nextLine++; + continue; + } + + emptyLines = 0; + + if (state.sCount[nextLine] - state.blkIndent >= 4) { + nextLine++; + last = nextLine; + continue; + } + break; + } + + state.line = last; + + token = state.push('code_block', 'code', 0); + token.content = state.getLines(startLine, last, 4 + state.blkIndent, true); + token.map = [startLine, state.line]; + + return true; +}; +/* eslint-enable */ + +/***/ }), +/* 87 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. +// Distributed under MIT license: https://github.com/markdown-it/markdown-it/ +/** + * @fileoverview Implements markdownitCodeBlockQuoteRenderer + * @modifier NHN Ent. FE Development Lab + */ + +/* eslint-disable */ + +// Block quotes + + + +// prevent quote, pre in list #811 +// ref: #989 +// #811 START +// var isSpace = require('../common/utils').isSpace; + +function isSpace(code) { + switch (code) { + case 0x09: + case 0x20: + return true; + } + return false; +} +// #811 END + +module.exports = function blockquote(state, startLine, endLine, silent) { + var adjustTab, + ch, + i, + initial, + l, + lastLineEmpty, + lines, + nextLine, + offset, + oldBMarks, + oldBSCount, + oldIndent, + oldParentType, + oldSCount, + oldTShift, + spaceAfterMarker, + terminate, + terminatorRules, + token, + wasOutdented, + oldLineMax = state.lineMax, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + // #811 START + var FIND_LIST_RX = /(?:-|\*|\d+\.) {1,4}(?:> {0,3})[^>]*$/; + var sourceLines = state.src.split('\n'); + var currentLine = sourceLines[startLine]; + // #811 END + + // if it's indented more than 3 spaces, it should be a code block + if (state.sCount[startLine] - state.blkIndent >= 4) { + return false; + } + + // check the block quote marker + if (state.src.charCodeAt(pos++) !== 0x3E /* > */) { + return false; + } + // #811 START + // check block quote in list + if (currentLine.match(FIND_LIST_RX) /*&& !currentLine.match(/^ {0,6}>/)*/) { + return false; + } + // #811 END + + // we know that it's going to be a valid blockquote, + // so no point trying to find the end of it in silent mode + if (silent) { + return true; + } + + // skip spaces after ">" and re-calculate offset + initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]); + + // skip one optional space after '>' + if (state.src.charCodeAt(pos) === 0x20 /* space */) { + // ' > test ' + // ^ -- position start of line here: + pos++; + initial++; + offset++; + adjustTab = false; + spaceAfterMarker = true; + } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) { + spaceAfterMarker = true; + + if ((state.bsCount[startLine] + offset) % 4 === 3) { + // ' >\t test ' + // ^ -- position start of line here (tab has width===1) + pos++; + initial++; + offset++; + adjustTab = false; + } else { + // ' >\t test ' + // ^ -- position start of line here + shift bsCount slightly + // to make extra space appear + adjustTab = true; + } + } else { + spaceAfterMarker = false; + } + + oldBMarks = [state.bMarks[startLine]]; + state.bMarks[startLine] = pos; + + while (pos < max) { + ch = state.src.charCodeAt(pos); + + if (isSpace(ch)) { + if (ch === 0x09) { + offset += 4 - (offset + state.bsCount[startLine] + (adjustTab ? 1 : 0)) % 4; + } else { + offset++; + } + } else { + break; + } + + pos++; + } + + oldBSCount = [state.bsCount[startLine]]; + state.bsCount[startLine] = state.sCount[startLine] + 1 + (spaceAfterMarker ? 1 : 0); + + lastLineEmpty = pos >= max; + + oldSCount = [state.sCount[startLine]]; + state.sCount[startLine] = offset - initial; + + oldTShift = [state.tShift[startLine]]; + state.tShift[startLine] = pos - state.bMarks[startLine]; + + terminatorRules = state.md.block.ruler.getRules('blockquote'); + + oldParentType = state.parentType; + state.parentType = 'blockquote'; + wasOutdented = false; + + // Search the end of the block + // + // Block ends with either: + // 1. an empty line outside: + // ``` + // > test + // + // ``` + // 2. an empty line inside: + // ``` + // > + // test + // ``` + // 3. another tag: + // ``` + // > test + // - - - + // ``` + for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { + // check if it's outdented, i.e. it's inside list item and indented + // less than said list item: + // + // ``` + // 1. anything + // > current blockquote + // 2. checking this line + // ``` + if (state.sCount[nextLine] < state.blkIndent) wasOutdented = true; + + pos = state.bMarks[nextLine] + state.tShift[nextLine]; + max = state.eMarks[nextLine]; + + if (pos >= max) { + // Case 1: line is not inside the blockquote, and this line is empty. + break; + } + + if (state.src.charCodeAt(pos++) === 0x3E /* > */ && !wasOutdented) { + // This line is inside the blockquote. + + // skip spaces after ">" and re-calculate offset + initial = offset = state.sCount[nextLine] + pos - (state.bMarks[nextLine] + state.tShift[nextLine]); + + // skip one optional space after '>' + if (state.src.charCodeAt(pos) === 0x20 /* space */) { + // ' > test ' + // ^ -- position start of line here: + pos++; + initial++; + offset++; + adjustTab = false; + spaceAfterMarker = true; + } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) { + spaceAfterMarker = true; + + if ((state.bsCount[nextLine] + offset) % 4 === 3) { + // ' >\t test ' + // ^ -- position start of line here (tab has width===1) + pos++; + initial++; + offset++; + adjustTab = false; + } else { + // ' >\t test ' + // ^ -- position start of line here + shift bsCount slightly + // to make extra space appear + adjustTab = true; + } + } else { + spaceAfterMarker = false; + } + + oldBMarks.push(state.bMarks[nextLine]); + state.bMarks[nextLine] = pos; + + while (pos < max) { + ch = state.src.charCodeAt(pos); + + if (isSpace(ch)) { + if (ch === 0x09) { + offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4; + } else { + offset++; + } + } else { + break; + } + + pos++; + } + + lastLineEmpty = pos >= max; + + oldBSCount.push(state.bsCount[nextLine]); + state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0); + + oldSCount.push(state.sCount[nextLine]); + state.sCount[nextLine] = offset - initial; + + oldTShift.push(state.tShift[nextLine]); + state.tShift[nextLine] = pos - state.bMarks[nextLine]; + continue; + } + + // Case 2: line is not inside the blockquote, and the last line was empty. + if (lastLineEmpty) { + break; + } + + // Case 3: another tag found. + terminate = false; + for (i = 0, l = terminatorRules.length; i < l; i++) { + if (terminatorRules[i](state, nextLine, endLine, true)) { + terminate = true; + break; + } + } + + if (terminate) { + // Quirk to enforce "hard termination mode" for paragraphs; + // normally if you call `tokenize(state, startLine, nextLine)`, + // paragraphs will look below nextLine for paragraph continuation, + // but if blockquote is terminated by another tag, they shouldn't + state.lineMax = nextLine; + + if (state.blkIndent !== 0) { + // state.blkIndent was non-zero, we now set it to zero, + // so we need to re-calculate all offsets to appear as + // if indent wasn't changed + oldBMarks.push(state.bMarks[nextLine]); + oldBSCount.push(state.bsCount[nextLine]); + oldTShift.push(state.tShift[nextLine]); + oldSCount.push(state.sCount[nextLine]); + state.sCount[nextLine] -= state.blkIndent; + } + + break; + } + + oldBMarks.push(state.bMarks[nextLine]); + oldBSCount.push(state.bsCount[nextLine]); + oldTShift.push(state.tShift[nextLine]); + oldSCount.push(state.sCount[nextLine]); + + // A negative indentation means that this is a paragraph continuation + // + state.sCount[nextLine] = -1; + } + + oldIndent = state.blkIndent; + state.blkIndent = 0; + + token = state.push('blockquote_open', 'blockquote', 1); + token.markup = '>'; + token.map = lines = [startLine, 0]; + + state.md.block.tokenize(state, startLine, nextLine); + + token = state.push('blockquote_close', 'blockquote', -1); + token.markup = '>'; + + state.lineMax = oldLineMax; + state.parentType = oldParentType; + lines[1] = state.line; + + // Restore original tShift; this might not be necessary since the parser + // has already been here, but just to make sure we can do that. + for (i = 0; i < oldTShift.length; i++) { + state.bMarks[i + startLine] = oldBMarks[i]; + state.tShift[i + startLine] = oldTShift[i]; + state.sCount[i + startLine] = oldSCount[i]; + state.bsCount[i + startLine] = oldBSCount[i]; + } + state.blkIndent = oldIndent; + + return true; +}; + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. +// Distributed under an ISC license: https://github.com/markdown-it/markdown-it/ + +/** + * @fileoverview Implements markdownitTableRenderer + * @modifier NHN Ent. FE Development Lab + */ + +/*eslint-disable */ +function getLine(state, line) { + var pos = state.bMarks[line] + state.blkIndent, + max = state.eMarks[line]; + + return state.src.substr(pos, max - pos); +} + +function escapedSplit(str) { + var result = [], + pos = 0, + max = str.length, + ch, + escapes = 0, + lastPos = 0, + backTicked = false, + lastBackTick = 0; + + ch = str.charCodeAt(pos); + + while (pos < max) { + if (ch === 0x60 /* ` */ && escapes % 2 === 0) { + backTicked = !backTicked; + lastBackTick = pos; + } else if (ch === 0x7c /* | */ && escapes % 2 === 0 && !backTicked) { + result.push(str.substring(lastPos, pos)); + lastPos = pos + 1; + } else if (ch === 0x5c /* \ */) { + escapes += 1; + } else { + escapes = 0; + } + + pos += 1; + + // If there was an un-closed backtick, go back to just after + // the last backtick, but as if it was a normal character + if (pos === max && backTicked) { + backTicked = false; + pos = lastBackTick + 1; + } + + ch = str.charCodeAt(pos); + } + + result.push(str.substring(lastPos)); + + return result; +} + +module.exports = function table(state, startLine, endLine, silent) { + var ch, lineText, pos, i, nextLine, columns, columnCount, token, aligns, alignCount, t, tableLines, tbodyLines; + + // should have at least three lines + if (startLine + 2 > endLine) { + return false; + } + + nextLine = startLine + 1; + + if (state.sCount[nextLine] < state.blkIndent) { + return false; + } + + // first character of the second line should be '|' or '-' + + pos = state.bMarks[nextLine] + state.tShift[nextLine]; + if (pos >= state.eMarks[nextLine]) { + return false; + } + + ch = state.src.charCodeAt(pos); + if (ch !== 0x7C /* | */ && ch !== 0x2D /* - */ && ch !== 0x3A /* : */) { + return false; + } + + lineText = getLine(state, startLine + 1); + if (!/^[-:| ]+$/.test(lineText)) { + return false; + } + + columns = lineText.split('|'); + aligns = []; + for (i = 0; i < columns.length; i += 1) { + t = columns[i].trim(); + if (!t) { + // allow empty columns before and after table, but not in between columns; + // e.g. allow ` |---| `, disallow ` ---||--- ` + if (i === 0 || i === columns.length - 1) { + continue; + } else { + return false; + } + } + + if (!/^:?-+:?$/.test(t)) { + return false; + } + if (t.charCodeAt(t.length - 1) === 0x3A /* : */) { + aligns.push(t.charCodeAt(0) === 0x3A /* : */ ? 'center' : 'right'); + } else if (t.charCodeAt(0) === 0x3A /* : */) { + aligns.push('left'); + } else { + aligns.push(''); + } + } + alignCount = aligns.length; + + lineText = getLine(state, startLine).trim(); + if (lineText.indexOf('|') === -1) { + return false; + } + columns = escapedSplit(lineText.replace(/^\||\|$/g, '')); + + // header row will define an amount of columns in the entire table, + // and align row shouldn't be smaller than that (the rest of the rows can) + columnCount = columns.length; + if (columnCount > alignCount) { + return false; + } else if (columnCount < alignCount) { + for (i = 0; i < alignCount - columnCount; i += 1) { + columns.push(''); + } + columnCount = columns.length; + } + + if (silent) { + return true; + } + + token = state.push('table_open', 'table', 1); + token.map = tableLines = [startLine, 0]; + + token = state.push('thead_open', 'thead', 1); + token.map = [startLine, startLine + 1]; + + token = state.push('tr_open', 'tr', 1); + token.map = [startLine, startLine + 1]; + + for (i = 0; i < columnCount; i += 1) { + token = state.push('th_open', 'th', 1); + token.map = [startLine, startLine + 1]; + if (aligns[i]) { + // FIXED: change property style to align + token.attrs = [['align', aligns[i]]]; + } + + token = state.push('inline', '', 0); + token.content = columns[i].trim(); + token.map = [startLine, startLine + 1]; + token.children = []; + + token = state.push('th_close', 'th', -1); + } + + token = state.push('tr_close', 'tr', -1); + token = state.push('thead_close', 'thead', -1); + + token = state.push('tbody_open', 'tbody', 1); + token.map = tbodyLines = [startLine + 2, 0]; + + for (nextLine = startLine + 2; nextLine < endLine; nextLine += 1) { + if (state.sCount[nextLine] < state.blkIndent) { + break; + } + + lineText = getLine(state, nextLine); + if (lineText.indexOf('|') === -1) { + break; + } + + // keep spaces at beginning of line to indicate an empty first cell, but + // strip trailing whitespace + columns = escapedSplit(lineText.replace(/^\||\|\s*$/g, '')); + + token = state.push('tr_open', 'tr', 1); + for (i = 0; i < columnCount; i += 1) { + token = state.push('td_open', 'td', 1); + if (aligns[i]) { + // FIXED: change property style to align + token.attrs = [['align', aligns[i]]]; + } + + token = state.push('inline', '', 0); + token.content = columns[i] ? columns[i].trim() : ''; + token.children = []; + + token = state.push('td_close', 'td', -1); + } + token = state.push('tr_close', 'tr', -1); + } + token = state.push('tbody_close', 'tbody', -1); + token = state.push('table_close', 'table', -1); + + tableLines[1] = tbodyLines[1] = nextLine; + state.line = nextLine; + return true; +}; + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. +// Distributed under an ISC license: https://github.com/markdown-it/markdown-it/ + +/** + * @fileoverview Implements markdownitHtmlBlockRenderer + * @modifier NHN Ent. FE Development Lab + */ +/* eslint-disable */ +// HTML block + + + +// An array of opening and corresponding closing sequences for html tags, +// last argument defines whether it can terminate a paragraph or not +// + +// void tag names --- Added by Junghwan Park + +var voidTagNames = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']; +var HTML_SEQUENCES = [[/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true], [/^/, true], [/^<\?/, /\?>/, true], [/^/, true], [/^/, true], [new RegExp('^<(' + voidTagNames.join('|') + ')', 'i'), /^\/?>$/, true], [new RegExp('^|$))', 'i'), /^$/, true], [/^(?:<[A-Za-z][A-Za-z0-9\-]*(?:\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\s*=\s*(?:[^"'=<>`\x00-\x20]+|'[^']*'|"[^"]*"))?)*\s*\/?>|<\/[A-Za-z][A-Za-z0-9\-]*\s*>)\s*$/, /^$/, false]]; + +module.exports = function html_block(state, startLine, endLine, silent) { + var i, + nextLine, + token, + lineText, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + if (!state.md.options.html) { + return false; + } + + if (state.src.charCodeAt(pos) !== 0x3C /* < */) { + return false; + } + + lineText = state.src.slice(pos, max); + + for (i = 0; i < HTML_SEQUENCES.length; i++) { + if (HTML_SEQUENCES[i][0].test(lineText)) { + // add condition for return when meet void element --- Added by Junghwan Park + if (i === 5) { + return false; + } else { + break; + } + } + } + + if (i === HTML_SEQUENCES.length) { + return false; + } + + if (silent) { + // true if this sequence can be a terminator, false otherwise + return HTML_SEQUENCES[i][2]; + } + + nextLine = startLine + 1; + + // If we are here - we detected HTML block. + // Let's roll down till block end. + if (!HTML_SEQUENCES[i][1].test(lineText)) { + for (; nextLine < endLine; nextLine++) { + if (state.sCount[nextLine] < state.blkIndent) { + break; + } + + pos = state.bMarks[nextLine] + state.tShift[nextLine]; + max = state.eMarks[nextLine]; + lineText = state.src.slice(pos, max); + + if (HTML_SEQUENCES[i][1].test(lineText)) { + if (lineText.length !== 0) { + nextLine++; + } + break; + } + } + } + + state.line = nextLine; + + token = state.push('html_block', '', 0); + token.map = [startLine, nextLine]; + token.content = state.getLines(startLine, nextLine, state.blkIndent, true); + + return true; +}; +/* eslint-enable */ + +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. +// Distributed under MIT license: https://github.com/markdown-it/markdown-it/ +/** + * @fileoverview Implements markdownitBackticksRenderer + * @modifier NHN Ent. FE Development Lab + */ +/* eslint-disable */ + +// Parse backticks +module.exports = function backtick(state, silent) { + var start, + max, + marker, + matchStart, + matchEnd, + token, + pos = state.pos, + ch = state.src.charCodeAt(pos); + + if (ch !== 0x60 /* ` */) { + return false; + } + + start = pos; + pos++; + max = state.posMax; + + while (pos < max && state.src.charCodeAt(pos) === 0x60 /* ` */) { + pos++; + } + + marker = state.src.slice(start, pos); + + matchStart = matchEnd = pos; + + while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) { + matchEnd = matchStart + 1; + + while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60 /* ` */) { + matchEnd++; + } + + if (matchEnd - matchStart === marker.length) { + if (!silent) { + token = state.push('code_inline', 'code', 0); + token.markup = marker; + token.content = state.src.slice(pos, matchStart).replace(/[ \n]+/g, ' ').trim(); + // TUI.EDITOR MODIFICATION START + // store number of backtick in data-backtick + // https://github.nhnent.com/fe/tui.editor/pull/981 + token.attrSet('data-backticks', token.markup.length); + // TUI.EDITOR MODIFICATION END + } + state.pos = matchEnd; + return true; + } + } + + if (!silent) { + state.pending += marker; + } + state.pos += marker.length; + return true; +}; + +/***/ }), +/* 91 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_91__; + +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements editor preivew + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _mdPreview = __webpack_require__(32); + +var _mdPreview2 = _interopRequireDefault(_mdPreview); + +var _eventManager = __webpack_require__(39); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _extManager = __webpack_require__(40); + +var _extManager2 = _interopRequireDefault(_extManager); + +var _convertor = __webpack_require__(41); + +var _convertor2 = _interopRequireDefault(_convertor); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +var _codeBlockManager = __webpack_require__(23); + +var _codeBlockManager2 = _interopRequireDefault(_codeBlockManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var TASK_ATTR_NAME = 'data-te-task'; +var TASK_CHECKED_CLASS_NAME = 'checked'; + +/** + * Class ToastUIEditorViewer + */ + +var ToastUIEditorViewer = function () { + /** + * Viewer + * @param {object} options Option object + * @param {HTMLElement} options.el - container element + * @param {string} options.initialValue Editor's initial value + * @param {object} options.events eventlist Event list + * @param {function} options.events.load It would be emitted when editor fully load + * @param {function} options.events.change It would be emitted when content changed + * @param {function} options.events.stateChange It would be emitted when format change by cursor position + * @param {function} options.events.focus It would be emitted when editor get focus + * @param {function} options.events.blur It would be emitted when editor loose focus + * @param {object} options.hooks Hook list + * @param {function} options.hooks.previewBeforeHook Submit preview to hook URL before preview be shown + * @param {string[]} [options.exts] - extensions + */ + function ToastUIEditorViewer(options) { + var _this = this; + + _classCallCheck(this, ToastUIEditorViewer); + + this.options = _jquery2.default.extend({ + useDefaultHTMLSanitizer: true, + codeBlockLanguages: _codeBlockManager.CodeBlockManager.getHighlightJSLanguages(), + customConvertor: null + }, options); + + this.eventManager = new _eventManager2.default(); + this.commandManager = new _commandManager2.default(this); + if (this.options.customConvertor) { + // eslint-disable-next-line new-cap + this.convertor = new this.options.customConvertor(this.eventManager); + } else { + this.convertor = new _convertor2.default(this.eventManager); + } + this.toMarkOptions = null; + + if (this.options.useDefaultHTMLSanitizer) { + this.convertor.initHtmlSanitizer(); + } + + if (this.options.hooks) { + _tuiCodeSnippet2.default.forEach(this.options.hooks, function (fn, key) { + _this.addHook(key, fn); + }); + } + + if (this.options.events) { + _tuiCodeSnippet2.default.forEach(this.options.events, function (fn, key) { + _this.on(key, fn); + }); + } + + this.preview = new _mdPreview2.default((0, _jquery2.default)(this.options.el), this.eventManager, this.convertor, true); + + this.preview.$el.on('mousedown', _jquery2.default.proxy(this._toggleTask, this)); + + _extManager2.default.applyExtension(this, this.options.exts); + + this.setValue(this.options.initialValue); + + this.eventManager.emit('load', this); + } + + /** + * Toggle task by detecting mousedown event. + * @param {MouseEvent} ev - event + * @private + */ + + + _createClass(ToastUIEditorViewer, [{ + key: '_toggleTask', + value: function _toggleTask(ev) { + var isBeneathTaskBox = ev.offsetX < 18 && ev.offsetY > 18; + + if (ev.target.hasAttribute(TASK_ATTR_NAME) && !isBeneathTaskBox) { + (0, _jquery2.default)(ev.target).toggleClass(TASK_CHECKED_CLASS_NAME); + this.eventManager.emit('change', { + source: 'viewer', + data: ev + }); + } + } + + /** + * Set content for preview + * @memberof ToastUIEditorViewer + * @param {string} markdown Markdown text + */ + + }, { + key: 'setMarkdown', + value: function setMarkdown(markdown) { + this.markdownValue = markdown = markdown || ''; + + this.preview.refresh(this.markdownValue); + this.eventManager.emit('setMarkdownAfter', this.markdownValue); + } + + /** + * Set content for preview + * @memberof ToastUIEditorViewer + * @param {string} markdown Markdown text + * @deprecated + */ + + }, { + key: 'setValue', + value: function setValue(markdown) { + this.setMarkdown(markdown); + } + + /** + * Bind eventHandler to event type + * @memberof ToastUIEditorViewer + * @param {string} type Event type + * @param {function} handler Event handler + */ + + }, { + key: 'on', + value: function on(type, handler) { + this.eventManager.listen(type, handler); + } + + /** + * Unbind eventHandler from event type + * @memberof ToastUIEditorViewer + * @param {string} type Event type + */ + + }, { + key: 'off', + value: function off(type) { + this.eventManager.removeEventHandler(type); + } + + /** + * Remove Viewer preview from document + * @memberof ToastUIEditorViewer + */ + + }, { + key: 'remove', + value: function remove() { + this.eventManager.emit('removeEditor'); + this.preview.$el.off('mousedown', _jquery2.default.proxy(this._toggleTask, this)); + this.options = null; + this.eventManager = null; + this.commandManager = null; + this.convertor = null; + this.preview = null; + } + + /** + * Add hook to Viewer preview's event + * @memberof ToastUIEditorViewer + * @param {string} type Event type + * @param {function} handler Event handler + */ + + }, { + key: 'addHook', + value: function addHook(type, handler) { + this.eventManager.removeEventHandler(type); + this.eventManager.listen(type, handler); + } + + /** + * Return true + * @memberof ToastUIEditorViewer + * @returns {boolean} + */ + + }, { + key: 'isViewer', + value: function isViewer() { + return true; + } + + /** + * Return false + * @memberof ToastUIEditorViewer + * @returns {boolean} + */ + + }, { + key: 'isMarkdownMode', + value: function isMarkdownMode() { + return false; + } + + /** + * Return false + * @memberof ToastUIEditorViewer + * @returns {boolean} + */ + + }, { + key: 'isWysiwygMode', + value: function isWysiwygMode() { + return false; + } + + /** + * Define extension + * @memberof ToastUIEditorViewer + * @param {string} name Extension name + * @param {ExtManager~extension} ext extension + */ + + }], [{ + key: 'defineExtension', + value: function defineExtension(name, ext) { + _extManager2.default.defineExtension(name, ext); + } + }]); + + return ToastUIEditorViewer; +}(); + +/** + * check whther is viewer + * @type {boolean} + */ + + +ToastUIEditorViewer.isViewer = true; + +/** + * domUtil instance + * @type {DomUtil} + */ +ToastUIEditorViewer.domUtils = _domUtils2.default; + +/** + * CodeBlockManager instance + * @type {CodeBlockManager} + */ +ToastUIEditorViewer.codeBlockManager = _codeBlockManager2.default; + +/** + * MarkdownIt hightlight instance + * @type {MarkdownIt} + */ +ToastUIEditorViewer.markdownitHighlight = _convertor2.default.getMarkdownitHighlightRenderer(); + +/** + * MarkdownIt instance + * @type {MarkdownIt} + */ +ToastUIEditorViewer.markdownit = _convertor2.default.getMarkdownitRenderer(); + +/** + * @ignore + */ +ToastUIEditorViewer.i18n = null; + +/** + * @ignore + */ +ToastUIEditorViewer.Button = null; + +/** + * @ignore + */ +ToastUIEditorViewer.WwCodeBlockManager = null; + +/** + * @ignore + */ +ToastUIEditorViewer.WwTableManager = null; + +/** + * @ignore + */ +ToastUIEditorViewer.WwTableSelectionManager = null; + +module.exports = ToastUIEditorViewer; + +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview default UI + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _defaultToolbar = __webpack_require__(94); + +var _defaultToolbar2 = _interopRequireDefault(_defaultToolbar); + +var _tab = __webpack_require__(46); + +var _tab2 = _interopRequireDefault(_tab); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _modeSwitch = __webpack_require__(98); + +var _modeSwitch2 = _interopRequireDefault(_modeSwitch); + +var _popupAddLink = __webpack_require__(99); + +var _popupAddLink2 = _interopRequireDefault(_popupAddLink); + +var _popupAddImage = __webpack_require__(100); + +var _popupAddImage2 = _interopRequireDefault(_popupAddImage); + +var _popupTableUtils = __webpack_require__(101); + +var _popupTableUtils2 = _interopRequireDefault(_popupTableUtils); + +var _popupAddTable = __webpack_require__(102); + +var _popupAddTable2 = _interopRequireDefault(_popupAddTable); + +var _popupAddHeading = __webpack_require__(103); + +var _popupAddHeading2 = _interopRequireDefault(_popupAddHeading); + +var _popupCodeBlockLanguages = __webpack_require__(104); + +var _popupCodeBlockLanguages2 = _interopRequireDefault(_popupCodeBlockLanguages); + +var _popupCodeBlockEditor = __webpack_require__(105); + +var _popupCodeBlockEditor2 = _interopRequireDefault(_popupCodeBlockEditor); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +var _tooltip = __webpack_require__(29); + +var _tooltip2 = _interopRequireDefault(_tooltip); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CLASS_TOOLBAR = 'te-toolbar-section'; +var CLASS_MARKDOWN_TAB = 'te-markdown-tab-section'; +var CLASS_EDITOR = 'te-editor-section'; +var CLASS_MODE_SWITCH = 'te-mode-switch-section'; +var CONTAINER_TEMPLATE = '\n
    \n
    \n
    \n
    \n
    \n'; + +/** + * Class Default UI + * initialize ui instances. toolbar, popups + */ + +var DefaultUI = function () { + + /** + * Creates an instance of DefaultUI. + * @param {ToastUIEditor} editor - editor instance + * @memberof DefaultUI + */ + + + /** + * mode switch instance + * @memberof DefaultUI + * @private + * @type {ModeSwitch} + */ + + + /** + * markdown tab section jQuery element + * @memberof DefaultUI + * @private + * @type {HTMLElement} + */ + + + /** + * editor type ww/md + * @memberof DefaultUI + * @private + * @type {string} + */ + + + /** + * @memberof DefaultUI + * @type {HTMLElement} + * @private + */ + + + /** + * DefaultToolbar wrapper element + * @memberof DefaultUI + * @type {jQuery} + */ + function DefaultUI(editor) { + _classCallCheck(this, DefaultUI); + + Object.defineProperty(this, 'name', { + enumerable: true, + writable: true, + value: 'default' + }); + Object.defineProperty(this, '_popups', { + enumerable: true, + writable: true, + value: [] + }); + + this._editor = editor; + this._initialEditType = editor.options.initialEditType; + + this._init(editor.options); + this._initEvent(); + } + + /** + * popup instances + * @memberof DefaultUI + * @private + * @type {Array} + */ + + + /** + * markdown tab + * @memberof DefaultUI + * @private + * @type {Tab} + */ + + + /** + * editor instance + * @memberof DefaultUI + * @private + * @type {ToastUIEditor} + */ + + + /** + * editor section element + * @memberof DefaultUI + * @private + * @type {HTMLElement} + */ + + + /** + * DefaultToolbar instance + * @memberof DefaultUI + * @type {DefaultToolbar} + * @private + */ + + /** + * UI name + * @memberof DefaultUI + * @type {string} + */ + + + _createClass(DefaultUI, [{ + key: '_init', + value: function _init(_ref) { + var container = _ref.el, + toolbarItems = _ref.toolbarItems, + hideModeSwitch = _ref.hideModeSwitch; + + this.$el = (0, _jquery2.default)(CONTAINER_TEMPLATE).appendTo(container); + this._container = container; + this._editorSection = this.$el.find('.' + CLASS_EDITOR).get(0); + this._editorSection.appendChild(this._editor.layout.getEditorEl().get(0)); + + this._initToolbar(this._editor.eventManager, toolbarItems); + this._initModeSwitch(hideModeSwitch); + + this._initPopupAddLink(); + this._initPopupAddImage(); + this._initPopupAddTable(); + this._initPopupAddHeading(); + this._initPopupTableUtils(); + this._initPopupCodeBlockLanguages(); + this._initPopupCodeBlockEditor(); + + this._initMarkdownTab(); + } + }, { + key: '_initEvent', + value: function _initEvent() { + this._editor.eventManager.listen('hide', this.hide.bind(this)); + this._editor.eventManager.listen('show', this.show.bind(this)); + this._editor.eventManager.listen('changeMode', this._markdownTabControl.bind(this)); + this._editor.eventManager.listen('changePreviewStyle', this._markdownTabControl.bind(this)); + } + }, { + key: '_initToolbar', + value: function _initToolbar(eventManager, toolbarItems) { + var toolbar = new _defaultToolbar2.default(eventManager, toolbarItems); + this._toolbar = toolbar; + this.$el.find('.' + CLASS_TOOLBAR).append(toolbar.$el); + } + }, { + key: '_initModeSwitch', + value: function _initModeSwitch(hideModeSwitch) { + var _this = this; + + var modeSwitchTabBar = this.$el.find('.' + CLASS_MODE_SWITCH); + var editType = this._initialEditType === 'markdown' ? _modeSwitch2.default.TYPE.MARKDOWN : _modeSwitch2.default.TYPE.WYSIWYG; + var modeSwitch = new _modeSwitch2.default(modeSwitchTabBar, editType); + this._modeSwitch = modeSwitch; + + if (hideModeSwitch) { + modeSwitch.hide(); + } + + modeSwitch.on('modeSwitched', function (ev, type) { + return _this._editor.changeMode(type); + }); + } + }, { + key: '_initMarkdownTab', + value: function _initMarkdownTab() { + var editor = this._editor; + + this._markdownTab = new _tab2.default({ + initName: _i18n2.default.get('Write'), + items: [_i18n2.default.get('Write'), _i18n2.default.get('Preview')], + sections: [editor.layout.getMdEditorContainerEl(), editor.layout.getPreviewEl()] + }); + this._$markdownTabSection = this.$el.find('.' + CLASS_MARKDOWN_TAB); + this._$markdownTabSection.append(this._markdownTab.$el); + + this._markdownTab.on('itemClick', function (ev, itemText) { + if (itemText === _i18n2.default.get('Preview')) { + editor.eventManager.emit('previewNeedsRefresh'); + editor.eventManager.emit('changePreviewTabPreview'); + editor.eventManager.emit('closeAllPopup'); + } else { + editor.getCodeMirror().focus(); + editor.eventManager.emit('changePreviewTabWrite'); + } + }); + } + }, { + key: '_markdownTabControl', + value: function _markdownTabControl() { + if (this._editor.isMarkdownMode() && this._editor.getCurrentPreviewStyle() === 'tab') { + this._$markdownTabSection.show(); + this._markdownTab.activate(_i18n2.default.get('Write')); + } else { + this._$markdownTabSection.hide(); + } + } + }, { + key: '_initPopupAddLink', + value: function _initPopupAddLink() { + this._popups.push(new _popupAddLink2.default({ + $target: this.$el, + editor: this._editor + })); + } + }, { + key: '_initPopupAddImage', + value: function _initPopupAddImage() { + this._popups.push(new _popupAddImage2.default({ + $target: this.$el, + eventManager: this._editor.eventManager + })); + } + }, { + key: '_initPopupAddTable', + value: function _initPopupAddTable() { + this._popups.push(new _popupAddTable2.default({ + $target: this._toolbar.$el, + eventManager: this._editor.eventManager, + $button: this.$el.find('button.tui-table'), + css: { + 'position': 'absolute' + } + })); + } + }, { + key: '_initPopupAddHeading', + value: function _initPopupAddHeading() { + this._popups.push(new _popupAddHeading2.default({ + $target: this._toolbar.$el, + eventManager: this._editor.eventManager, + $button: this.$el.find('button.tui-heading'), + css: { + 'position': 'absolute' + } + })); + } + }, { + key: '_initPopupTableUtils', + value: function _initPopupTableUtils() { + var _this2 = this; + + this._editor.eventManager.listen('contextmenu', function (ev) { + if ((0, _jquery2.default)(ev.data.target).parents('[contenteditable=true] table').length > 0) { + ev.data.preventDefault(); + _this2._editor.eventManager.emit('openPopupTableUtils', ev.data); + } + }); + + this._popups.push(new _popupTableUtils2.default({ + $target: this.$el, + eventManager: this._editor.eventManager + })); + } + }, { + key: '_initPopupCodeBlockLanguages', + value: function _initPopupCodeBlockLanguages() { + var editor = this._editor; + this._popups.push(new _popupCodeBlockLanguages2.default({ + $target: this.$el, + eventManager: editor.eventManager, + languages: editor.options.codeBlockLanguages + })); + } + }, { + key: '_initPopupCodeBlockEditor', + value: function _initPopupCodeBlockEditor() { + this._popups.push(new _popupCodeBlockEditor2.default({ + $target: this.$el, + eventManager: this._editor.eventManager, + convertor: this._editor.convertor + })); + } + + /** + * get toolbar instance + * @returns {Toolbar} - toolbar instance + * @memberof DefaultUI + */ + + }, { + key: 'getToolbar', + value: function getToolbar() { + return this._toolbar; + } + + /** + * set toolbar instance + * @param {Toolbar} toolbar - toolbar + * @memberof DefaultUI + */ + + }, { + key: 'setToolbar', + value: function setToolbar(toolbar) { + this._toolbar.destroy(); + this._toolbar = toolbar; + } + + /** + * get mode switch instance + * @memberof DefaultUI + * @returns {ModeSwitch} - mode switch instance + */ + + }, { + key: 'getModeSwitch', + value: function getModeSwitch() { + return this._modeSwitch; + } + + /** + * get editor section height + * @returns {Number} - height of editor section + * @memberof DefaultUI + */ + + }, { + key: 'getEditorSectionHeight', + value: function getEditorSectionHeight() { + var clientRect = this._editorSection.getBoundingClientRect(); + + return clientRect.bottom - clientRect.top; + } + + /** + * get editor height + * @returns {Number} - height of editor + * @memberof DefaultUI + */ + + }, { + key: 'getEditorHeight', + value: function getEditorHeight() { + var clientRect = this._container.getBoundingClientRect(); + + return clientRect.bottom - clientRect.top; + } + + /** + * get Table Popup + * @returns {PopupTableUtils} - PopupTableUtils + * @memberof DefaultUI + */ + + }, { + key: 'getPopupTableUtils', + value: function getPopupTableUtils() { + var tablePopup = void 0; + this._popups.forEach(function (popup) { + if (popup instanceof _popupTableUtils2.default) { + tablePopup = popup; + } + }); + + return tablePopup; + } + + /** + * hide + * @memberof DefaultUI + */ + + }, { + key: 'hide', + value: function hide() { + this.$el.addClass('te-hide'); + } + + /** + * show + * @memberof DefaultUI + */ + + }, { + key: 'show', + value: function show() { + this.$el.removeClass('te-hide'); + } + + /** + * remove + * @memberof DefaultUI + */ + + }, { + key: 'remove', + value: function remove() { + this.$el.remove(); + _tooltip2.default.hide(); + } + + /** + * creates popup + * @param {LayerPopupOption} options - layerPopup options + * @returns {LayerPopup} - crated layerPopup + * @memberof DefaultUI + */ + + }, { + key: 'createPopup', + value: function createPopup(options) { + return new _layerpopup2.default(options); + } + }]); + + return DefaultUI; +}(); + +exports.default = DefaultUI; + +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _resizeObserverPolyfill = __webpack_require__(95); + +var _resizeObserverPolyfill2 = _interopRequireDefault(_resizeObserverPolyfill); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +var _toolbar = __webpack_require__(43); + +var _toolbar2 = _interopRequireDefault(_toolbar); + +var _popupDropdownToolbar = __webpack_require__(97); + +var _popupDropdownToolbar2 = _interopRequireDefault(_popupDropdownToolbar); + +var _toolbarItemFactory = __webpack_require__(45); + +var _toolbarItemFactory2 = _interopRequireDefault(_toolbarItemFactory); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview implements DefaultToolbar + * @author NHN Ent. FE Development Lab + */ + + +var MORE_BUTTON_NAME = 'more'; + +/** + * default toolbar + * @extends Toolbar + */ + +var DefaultToolbar = function (_Toolbar) { + _inherits(DefaultToolbar, _Toolbar); + + /** + * popup dropdown toolbar + * @memberof DefaultToolbar + * @private + * @type {PopupDropdownToolbar} + */ + function DefaultToolbar(eventManager, options) { + _classCallCheck(this, DefaultToolbar); + + var _this = _possibleConstructorReturn(this, (DefaultToolbar.__proto__ || Object.getPrototypeOf(DefaultToolbar)).call(this, eventManager, options)); + + _this._init(eventManager); + _this._bindWidthChangedEvent(); + return _this; + } + + /** + * insert toolbar item + * @param {number} index - index at given item inserted + * @param {ToolbarItem|string|object} item - toolbar item + * @memberof Toolbar + */ + + + /** + * resize observer + * @memberof DefaultToolbar + * @private + * @type {ResizeObserver} + */ + + /** + * more button + * @memberof DefaultToolbar + * @private + * @type {ToolbarButton} + */ + + + _createClass(DefaultToolbar, [{ + key: 'insertItem', + value: function insertItem(index, item) { + _get(DefaultToolbar.prototype.__proto__ || Object.getPrototypeOf(DefaultToolbar.prototype), 'insertItem', this).call(this, index, item); + this._arrangeMoreButton(); + } + }, { + key: '_init', + value: function _init(eventManager) { + var moreButton = _toolbarItemFactory2.default.create('button', { + name: MORE_BUTTON_NAME, + className: 'tui-more', + tooltip: _i18n2.default.get('More'), + event: _popupDropdownToolbar2.default.OPEN_EVENT + }); + this._moreButton = moreButton; + + this._popupDropdownToolbar = new _popupDropdownToolbar2.default({ + eventManager: eventManager, + $target: this.$el, + $button: moreButton.$el + }); + + this.addItem(moreButton); + } + }, { + key: '_bindWidthChangedEvent', + value: function _bindWidthChangedEvent() { + var _this2 = this; + + this._observer = new _resizeObserverPolyfill2.default(function () { + _this2._popupDropdownToolbar.hide(); + _this2._balanceButtons(); + }); + this._observer.observe(this.$el.get(0)); + } + }, { + key: '_balanceButtons', + value: function _balanceButtons() { + var _this3 = this; + + var dropDownToolbarItems = this._popupDropdownToolbar.getItems(); + dropDownToolbarItems.forEach(function (item) { + _this3._popupDropdownToolbar.removeItem(item, false); + + var itemLength = _this3.getItems().length; + _get(DefaultToolbar.prototype.__proto__ || Object.getPrototypeOf(DefaultToolbar.prototype), 'insertItem', _this3).call(_this3, itemLength, item); + }); + + this.removeItem(this._moreButton, false); + _get(DefaultToolbar.prototype.__proto__ || Object.getPrototypeOf(DefaultToolbar.prototype), 'insertItem', this).call(this, 0, this._moreButton); + + var toolbarHeight = this.$el.height(); + var defaultToolbarItems = this.getItems(); + var overflowItems = defaultToolbarItems.filter(function (item) { + return item.$el.position().top > toolbarHeight; + }); + + overflowItems.forEach(function (item) { + _this3.removeItem(item, false); + _this3._popupDropdownToolbar.addItem(item); + }); + + this._arrangeMoreButton(); + } + }, { + key: '_arrangeMoreButton', + value: function _arrangeMoreButton() { + if (!this._popupDropdownToolbar) { + return; + } + + this.removeItem(this._moreButton, false); + + var hasOverflow = this._popupDropdownToolbar.getItems().length > 0; + var itemLength = this.getItems().length; + if (hasOverflow) { + _get(DefaultToolbar.prototype.__proto__ || Object.getPrototypeOf(DefaultToolbar.prototype), 'insertItem', this).call(this, itemLength, this._moreButton); + } + } + + /** + * destroy + * @override + */ + + }, { + key: 'destroy', + value: function destroy() { + if (this._observer) { + this._observer.disconnect(); + } + } + }]); + + return DefaultToolbar; +}(_toolbar2.default); + +exports.default = DefaultToolbar; + +/***/ }), +/* 95 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* WEBPACK VAR INJECTION */(function(global) {/** + * A collection of shims that provide minimal functionality of the ES6 collections. + * + * These implementations are not meant to be used outside of the ResizeObserver + * modules as they cover only a limited range of use cases. + */ +/* eslint-disable require-jsdoc, valid-jsdoc */ +var MapShim = (function () { + if (typeof Map !== 'undefined') { + return Map; + } + + /** + * Returns index in provided array that matches the specified key. + * + * @param {Array} arr + * @param {*} key + * @returns {number} + */ + function getIndex(arr, key) { + var result = -1; + + arr.some(function (entry, index) { + if (entry[0] === key) { + result = index; + + return true; + } + + return false; + }); + + return result; + } + + return (function () { + function anonymous() { + this.__entries__ = []; + } + + var prototypeAccessors = { size: { configurable: true } }; + + /** + * @returns {boolean} + */ + prototypeAccessors.size.get = function () { + return this.__entries__.length; + }; + + /** + * @param {*} key + * @returns {*} + */ + anonymous.prototype.get = function (key) { + var index = getIndex(this.__entries__, key); + var entry = this.__entries__[index]; + + return entry && entry[1]; + }; + + /** + * @param {*} key + * @param {*} value + * @returns {void} + */ + anonymous.prototype.set = function (key, value) { + var index = getIndex(this.__entries__, key); + + if (~index) { + this.__entries__[index][1] = value; + } else { + this.__entries__.push([key, value]); + } + }; + + /** + * @param {*} key + * @returns {void} + */ + anonymous.prototype.delete = function (key) { + var entries = this.__entries__; + var index = getIndex(entries, key); + + if (~index) { + entries.splice(index, 1); + } + }; + + /** + * @param {*} key + * @returns {void} + */ + anonymous.prototype.has = function (key) { + return !!~getIndex(this.__entries__, key); + }; + + /** + * @returns {void} + */ + anonymous.prototype.clear = function () { + this.__entries__.splice(0); + }; + + /** + * @param {Function} callback + * @param {*} [ctx=null] + * @returns {void} + */ + anonymous.prototype.forEach = function (callback, ctx) { + var this$1 = this; + if ( ctx === void 0 ) ctx = null; + + for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) { + var entry = list[i]; + + callback.call(ctx, entry[1], entry[0]); + } + }; + + Object.defineProperties( anonymous.prototype, prototypeAccessors ); + + return anonymous; + }()); +})(); + +/** + * Detects whether window and document objects are available in current environment. + */ +var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document; + +// Returns global object of a current environment. +var global$1 = (function () { + if (typeof global !== 'undefined' && global.Math === Math) { + return global; + } + + if (typeof self !== 'undefined' && self.Math === Math) { + return self; + } + + if (typeof window !== 'undefined' && window.Math === Math) { + return window; + } + + // eslint-disable-next-line no-new-func + return Function('return this')(); +})(); + +/** + * A shim for the requestAnimationFrame which falls back to the setTimeout if + * first one is not supported. + * + * @returns {number} Requests' identifier. + */ +var requestAnimationFrame$1 = (function () { + if (typeof requestAnimationFrame === 'function') { + // It's required to use a bounded function because IE sometimes throws + // an "Invalid calling object" error if rAF is invoked without the global + // object on the left hand side. + return requestAnimationFrame.bind(global$1); + } + + return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); }; +})(); + +// Defines minimum timeout before adding a trailing call. +var trailingTimeout = 2; + +/** + * Creates a wrapper function which ensures that provided callback will be + * invoked only once during the specified delay period. + * + * @param {Function} callback - Function to be invoked after the delay period. + * @param {number} delay - Delay after which to invoke callback. + * @returns {Function} + */ +var throttle = function (callback, delay) { + var leadingCall = false, + trailingCall = false, + lastCallTime = 0; + + /** + * Invokes the original callback function and schedules new invocation if + * the "proxy" was called during current request. + * + * @returns {void} + */ + function resolvePending() { + if (leadingCall) { + leadingCall = false; + + callback(); + } + + if (trailingCall) { + proxy(); + } + } + + /** + * Callback invoked after the specified delay. It will further postpone + * invocation of the original function delegating it to the + * requestAnimationFrame. + * + * @returns {void} + */ + function timeoutCallback() { + requestAnimationFrame$1(resolvePending); + } + + /** + * Schedules invocation of the original function. + * + * @returns {void} + */ + function proxy() { + var timeStamp = Date.now(); + + if (leadingCall) { + // Reject immediately following calls. + if (timeStamp - lastCallTime < trailingTimeout) { + return; + } + + // Schedule new call to be in invoked when the pending one is resolved. + // This is important for "transitions" which never actually start + // immediately so there is a chance that we might miss one if change + // happens amids the pending invocation. + trailingCall = true; + } else { + leadingCall = true; + trailingCall = false; + + setTimeout(timeoutCallback, delay); + } + + lastCallTime = timeStamp; + } + + return proxy; +}; + +// Minimum delay before invoking the update of observers. +var REFRESH_DELAY = 20; + +// A list of substrings of CSS properties used to find transition events that +// might affect dimensions of observed elements. +var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight']; + +// Check if MutationObserver is available. +var mutationObserverSupported = typeof MutationObserver !== 'undefined'; + +/** + * Singleton controller class which handles updates of ResizeObserver instances. + */ +var ResizeObserverController = function() { + this.connected_ = false; + this.mutationEventsAdded_ = false; + this.mutationsObserver_ = null; + this.observers_ = []; + + this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); + this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY); +}; + +/** + * Adds observer to observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be added. + * @returns {void} + */ + + +/** + * Holds reference to the controller's instance. + * + * @private {ResizeObserverController} + */ + + +/** + * Keeps reference to the instance of MutationObserver. + * + * @private {MutationObserver} + */ + +/** + * Indicates whether DOM listeners have been added. + * + * @private {boolean} + */ +ResizeObserverController.prototype.addObserver = function (observer) { + if (!~this.observers_.indexOf(observer)) { + this.observers_.push(observer); + } + + // Add listeners if they haven't been added yet. + if (!this.connected_) { + this.connect_(); + } +}; + +/** + * Removes observer from observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be removed. + * @returns {void} + */ +ResizeObserverController.prototype.removeObserver = function (observer) { + var observers = this.observers_; + var index = observers.indexOf(observer); + + // Remove observer if it's present in registry. + if (~index) { + observers.splice(index, 1); + } + + // Remove listeners if controller has no connected observers. + if (!observers.length && this.connected_) { + this.disconnect_(); + } +}; + +/** + * Invokes the update of observers. It will continue running updates insofar + * it detects changes. + * + * @returns {void} + */ +ResizeObserverController.prototype.refresh = function () { + var changesDetected = this.updateObservers_(); + + // Continue running updates if changes have been detected as there might + // be future ones caused by CSS transitions. + if (changesDetected) { + this.refresh(); + } +}; + +/** + * Updates every observer from observers list and notifies them of queued + * entries. + * + * @private + * @returns {boolean} Returns "true" if any observer has detected changes in + * dimensions of it's elements. + */ +ResizeObserverController.prototype.updateObservers_ = function () { + // Collect observers that have active observations. + var activeObservers = this.observers_.filter(function (observer) { + return observer.gatherActive(), observer.hasActive(); + }); + + // Deliver notifications in a separate cycle in order to avoid any + // collisions between observers, e.g. when multiple instances of + // ResizeObserver are tracking the same element and the callback of one + // of them changes content dimensions of the observed target. Sometimes + // this may result in notifications being blocked for the rest of observers. + activeObservers.forEach(function (observer) { return observer.broadcastActive(); }); + + return activeObservers.length > 0; +}; + +/** + * Initializes DOM listeners. + * + * @private + * @returns {void} + */ +ResizeObserverController.prototype.connect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already added. + if (!isBrowser || this.connected_) { + return; + } + + // Subscription to the "Transitionend" event is used as a workaround for + // delayed transitions. This way it's possible to capture at least the + // final state of an element. + document.addEventListener('transitionend', this.onTransitionEnd_); + + window.addEventListener('resize', this.refresh); + + if (mutationObserverSupported) { + this.mutationsObserver_ = new MutationObserver(this.refresh); + + this.mutationsObserver_.observe(document, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + } else { + document.addEventListener('DOMSubtreeModified', this.refresh); + + this.mutationEventsAdded_ = true; + } + + this.connected_ = true; +}; + +/** + * Removes DOM listeners. + * + * @private + * @returns {void} + */ +ResizeObserverController.prototype.disconnect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already removed. + if (!isBrowser || !this.connected_) { + return; + } + + document.removeEventListener('transitionend', this.onTransitionEnd_); + window.removeEventListener('resize', this.refresh); + + if (this.mutationsObserver_) { + this.mutationsObserver_.disconnect(); + } + + if (this.mutationEventsAdded_) { + document.removeEventListener('DOMSubtreeModified', this.refresh); + } + + this.mutationsObserver_ = null; + this.mutationEventsAdded_ = false; + this.connected_ = false; +}; + +/** + * "Transitionend" event handler. + * + * @private + * @param {TransitionEvent} event + * @returns {void} + */ +ResizeObserverController.prototype.onTransitionEnd_ = function (ref) { + var propertyName = ref.propertyName; if ( propertyName === void 0 ) propertyName = ''; + + // Detect whether transition may affect dimensions of an element. + var isReflowProperty = transitionKeys.some(function (key) { + return !!~propertyName.indexOf(key); + }); + + if (isReflowProperty) { + this.refresh(); + } +}; + +/** + * Returns instance of the ResizeObserverController. + * + * @returns {ResizeObserverController} + */ +ResizeObserverController.getInstance = function () { + if (!this.instance_) { + this.instance_ = new ResizeObserverController(); + } + + return this.instance_; +}; + +ResizeObserverController.instance_ = null; + +/** + * Defines non-writable/enumerable properties of the provided target object. + * + * @param {Object} target - Object for which to define properties. + * @param {Object} props - Properties to be defined. + * @returns {Object} Target object. + */ +var defineConfigurable = (function (target, props) { + for (var i = 0, list = Object.keys(props); i < list.length; i += 1) { + var key = list[i]; + + Object.defineProperty(target, key, { + value: props[key], + enumerable: false, + writable: false, + configurable: true + }); + } + + return target; +}); + +/** + * Returns the global object associated with provided element. + * + * @param {Object} target + * @returns {Object} + */ +var getWindowOf = (function (target) { + // Assume that the element is an instance of Node, which means that it + // has the "ownerDocument" property from which we can retrieve a + // corresponding global object. + var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView; + + // Return the local global object if it's not possible extract one from + // provided element. + return ownerGlobal || global$1; +}); + +// Placeholder of an empty content rectangle. +var emptyRect = createRectInit(0, 0, 0, 0); + +/** + * Converts provided string to a number. + * + * @param {number|string} value + * @returns {number} + */ +function toFloat(value) { + return parseFloat(value) || 0; +} + +/** + * Extracts borders size from provided styles. + * + * @param {CSSStyleDeclaration} styles + * @param {...string} positions - Borders positions (top, right, ...) + * @returns {number} + */ +function getBordersSize(styles) { + var positions = [], len = arguments.length - 1; + while ( len-- > 0 ) positions[ len ] = arguments[ len + 1 ]; + + return positions.reduce(function (size, position) { + var value = styles['border-' + position + '-width']; + + return size + toFloat(value); + }, 0); +} + +/** + * Extracts paddings sizes from provided styles. + * + * @param {CSSStyleDeclaration} styles + * @returns {Object} Paddings box. + */ +function getPaddings(styles) { + var positions = ['top', 'right', 'bottom', 'left']; + var paddings = {}; + + for (var i = 0, list = positions; i < list.length; i += 1) { + var position = list[i]; + + var value = styles['padding-' + position]; + + paddings[position] = toFloat(value); + } + + return paddings; +} + +/** + * Calculates content rectangle of provided SVG element. + * + * @param {SVGGraphicsElement} target - Element content rectangle of which needs + * to be calculated. + * @returns {DOMRectInit} + */ +function getSVGContentRect(target) { + var bbox = target.getBBox(); + + return createRectInit(0, 0, bbox.width, bbox.height); +} + +/** + * Calculates content rectangle of provided HTMLElement. + * + * @param {HTMLElement} target - Element for which to calculate the content rectangle. + * @returns {DOMRectInit} + */ +function getHTMLElementContentRect(target) { + // Client width & height properties can't be + // used exclusively as they provide rounded values. + var clientWidth = target.clientWidth; + var clientHeight = target.clientHeight; + + // By this condition we can catch all non-replaced inline, hidden and + // detached elements. Though elements with width & height properties less + // than 0.5 will be discarded as well. + // + // Without it we would need to implement separate methods for each of + // those cases and it's not possible to perform a precise and performance + // effective test for hidden elements. E.g. even jQuery's ':visible' filter + // gives wrong results for elements with width & height less than 0.5. + if (!clientWidth && !clientHeight) { + return emptyRect; + } + + var styles = getWindowOf(target).getComputedStyle(target); + var paddings = getPaddings(styles); + var horizPad = paddings.left + paddings.right; + var vertPad = paddings.top + paddings.bottom; + + // Computed styles of width & height are being used because they are the + // only dimensions available to JS that contain non-rounded values. It could + // be possible to utilize the getBoundingClientRect if only it's data wasn't + // affected by CSS transformations let alone paddings, borders and scroll bars. + var width = toFloat(styles.width), + height = toFloat(styles.height); + + // Width & height include paddings and borders when the 'border-box' box + // model is applied (except for IE). + if (styles.boxSizing === 'border-box') { + // Following conditions are required to handle Internet Explorer which + // doesn't include paddings and borders to computed CSS dimensions. + // + // We can say that if CSS dimensions + paddings are equal to the "client" + // properties then it's either IE, and thus we don't need to subtract + // anything, or an element merely doesn't have paddings/borders styles. + if (Math.round(width + horizPad) !== clientWidth) { + width -= getBordersSize(styles, 'left', 'right') + horizPad; + } + + if (Math.round(height + vertPad) !== clientHeight) { + height -= getBordersSize(styles, 'top', 'bottom') + vertPad; + } + } + + // Following steps can't be applied to the document's root element as its + // client[Width/Height] properties represent viewport area of the window. + // Besides, it's as well not necessary as the itself neither has + // rendered scroll bars nor it can be clipped. + if (!isDocumentElement(target)) { + // In some browsers (only in Firefox, actually) CSS width & height + // include scroll bars size which can be removed at this step as scroll + // bars are the only difference between rounded dimensions + paddings + // and "client" properties, though that is not always true in Chrome. + var vertScrollbar = Math.round(width + horizPad) - clientWidth; + var horizScrollbar = Math.round(height + vertPad) - clientHeight; + + // Chrome has a rather weird rounding of "client" properties. + // E.g. for an element with content width of 314.2px it sometimes gives + // the client width of 315px and for the width of 314.7px it may give + // 314px. And it doesn't happen all the time. So just ignore this delta + // as a non-relevant. + if (Math.abs(vertScrollbar) !== 1) { + width -= vertScrollbar; + } + + if (Math.abs(horizScrollbar) !== 1) { + height -= horizScrollbar; + } + } + + return createRectInit(paddings.left, paddings.top, width, height); +} + +/** + * Checks whether provided element is an instance of the SVGGraphicsElement. + * + * @param {Element} target - Element to be checked. + * @returns {boolean} + */ +var isSVGGraphicsElement = (function () { + // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement + // interface. + if (typeof SVGGraphicsElement !== 'undefined') { + return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; }; + } + + // If it's so, then check that element is at least an instance of the + // SVGElement and that it has the "getBBox" method. + // eslint-disable-next-line no-extra-parens + return function (target) { return target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'; }; +})(); + +/** + * Checks whether provided element is a document element (). + * + * @param {Element} target - Element to be checked. + * @returns {boolean} + */ +function isDocumentElement(target) { + return target === getWindowOf(target).document.documentElement; +} + +/** + * Calculates an appropriate content rectangle for provided html or svg element. + * + * @param {Element} target - Element content rectangle of which needs to be calculated. + * @returns {DOMRectInit} + */ +function getContentRect(target) { + if (!isBrowser) { + return emptyRect; + } + + if (isSVGGraphicsElement(target)) { + return getSVGContentRect(target); + } + + return getHTMLElementContentRect(target); +} + +/** + * Creates rectangle with an interface of the DOMRectReadOnly. + * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly + * + * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions. + * @returns {DOMRectReadOnly} + */ +function createReadOnlyRect(ref) { + var x = ref.x; + var y = ref.y; + var width = ref.width; + var height = ref.height; + + // If DOMRectReadOnly is available use it as a prototype for the rectangle. + var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object; + var rect = Object.create(Constr.prototype); + + // Rectangle's properties are not writable and non-enumerable. + defineConfigurable(rect, { + x: x, y: y, width: width, height: height, + top: y, + right: x + width, + bottom: height + y, + left: x + }); + + return rect; +} + +/** + * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates. + * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit + * + * @param {number} x - X coordinate. + * @param {number} y - Y coordinate. + * @param {number} width - Rectangle's width. + * @param {number} height - Rectangle's height. + * @returns {DOMRectInit} + */ +function createRectInit(x, y, width, height) { + return { x: x, y: y, width: width, height: height }; +} + +/** + * Class that is responsible for computations of the content rectangle of + * provided DOM element and for keeping track of it's changes. + */ +var ResizeObservation = function(target) { + this.broadcastWidth = 0; + this.broadcastHeight = 0; + this.contentRect_ = createRectInit(0, 0, 0, 0); + + this.target = target; +}; + +/** + * Updates content rectangle and tells whether it's width or height properties + * have changed since the last broadcast. + * + * @returns {boolean} + */ + + +/** + * Reference to the last observed content rectangle. + * + * @private {DOMRectInit} + */ + + +/** + * Broadcasted width of content rectangle. + * + * @type {number} + */ +ResizeObservation.prototype.isActive = function () { + var rect = getContentRect(this.target); + + this.contentRect_ = rect; + + return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight; +}; + +/** + * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data + * from the corresponding properties of the last observed content rectangle. + * + * @returns {DOMRectInit} Last observed content rectangle. + */ +ResizeObservation.prototype.broadcastRect = function () { + var rect = this.contentRect_; + + this.broadcastWidth = rect.width; + this.broadcastHeight = rect.height; + + return rect; +}; + +var ResizeObserverEntry = function(target, rectInit) { + var contentRect = createReadOnlyRect(rectInit); + + // According to the specification following properties are not writable + // and are also not enumerable in the native implementation. + // + // Property accessors are not being used as they'd require to define a + // private WeakMap storage which may cause memory leaks in browsers that + // don't support this type of collections. + defineConfigurable(this, { target: target, contentRect: contentRect }); +}; + +var ResizeObserverSPI = function(callback, controller, callbackCtx) { + this.activeObservations_ = []; + this.observations_ = new MapShim(); + + if (typeof callback !== 'function') { + throw new TypeError('The callback provided as parameter 1 is not a function.'); + } + + this.callback_ = callback; + this.controller_ = controller; + this.callbackCtx_ = callbackCtx; +}; + +/** + * Starts observing provided element. + * + * @param {Element} target - Element to be observed. + * @returns {void} + */ + + +/** + * Registry of the ResizeObservation instances. + * + * @private {Map} + */ + + +/** + * Public ResizeObserver instance which will be passed to the callback + * function and used as a value of it's "this" binding. + * + * @private {ResizeObserver} + */ + +/** + * Collection of resize observations that have detected changes in dimensions + * of elements. + * + * @private {Array} + */ +ResizeObserverSPI.prototype.observe = function (target) { + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === 'undefined' || !(Element instanceof Object)) { + return; + } + + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + + var observations = this.observations_; + + // Do nothing if element is already being observed. + if (observations.has(target)) { + return; + } + + observations.set(target, new ResizeObservation(target)); + + this.controller_.addObserver(this); + + // Force the update of observations. + this.controller_.refresh(); +}; + +/** + * Stops observing provided element. + * + * @param {Element} target - Element to stop observing. + * @returns {void} + */ +ResizeObserverSPI.prototype.unobserve = function (target) { + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === 'undefined' || !(Element instanceof Object)) { + return; + } + + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + + var observations = this.observations_; + + // Do nothing if element is not being observed. + if (!observations.has(target)) { + return; + } + + observations.delete(target); + + if (!observations.size) { + this.controller_.removeObserver(this); + } +}; + +/** + * Stops observing all elements. + * + * @returns {void} + */ +ResizeObserverSPI.prototype.disconnect = function () { + this.clearActive(); + this.observations_.clear(); + this.controller_.removeObserver(this); +}; + +/** + * Collects observation instances the associated element of which has changed + * it's content rectangle. + * + * @returns {void} + */ +ResizeObserverSPI.prototype.gatherActive = function () { + var this$1 = this; + + this.clearActive(); + + this.observations_.forEach(function (observation) { + if (observation.isActive()) { + this$1.activeObservations_.push(observation); + } + }); +}; + +/** + * Invokes initial callback function with a list of ResizeObserverEntry + * instances collected from active resize observations. + * + * @returns {void} + */ +ResizeObserverSPI.prototype.broadcastActive = function () { + // Do nothing if observer doesn't have active observations. + if (!this.hasActive()) { + return; + } + + var ctx = this.callbackCtx_; + + // Create ResizeObserverEntry instance for every active observation. + var entries = this.activeObservations_.map(function (observation) { + return new ResizeObserverEntry(observation.target, observation.broadcastRect()); + }); + + this.callback_.call(ctx, entries, ctx); + this.clearActive(); +}; + +/** + * Clears the collection of active observations. + * + * @returns {void} + */ +ResizeObserverSPI.prototype.clearActive = function () { + this.activeObservations_.splice(0); +}; + +/** + * Tells whether observer has active observations. + * + * @returns {boolean} + */ +ResizeObserverSPI.prototype.hasActive = function () { + return this.activeObservations_.length > 0; +}; + +// Registry of internal observers. If WeakMap is not available use current shim +// for the Map collection as it has all required methods and because WeakMap +// can't be fully polyfilled anyway. +var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim(); + +/** + * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation + * exposing only those methods and properties that are defined in the spec. + */ +var ResizeObserver = function(callback) { + if (!(this instanceof ResizeObserver)) { + throw new TypeError('Cannot call a class as a function.'); + } + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + + var controller = ResizeObserverController.getInstance(); + var observer = new ResizeObserverSPI(callback, controller, this); + + observers.set(this, observer); +}; + +// Expose public methods of ResizeObserver. +['observe', 'unobserve', 'disconnect'].forEach(function (method) { + ResizeObserver.prototype[method] = function () { + return (ref = observers.get(this))[method].apply(ref, arguments); + var ref; + }; +}); + +var index = (function () { + // Export existing implementation if available. + if (typeof global$1.ResizeObserver !== 'undefined') { + return global$1.ResizeObserver; + } + + return ResizeObserver; +})(); + +/* harmony default export */ __webpack_exports__["default"] = (index); + +/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(12))) + +/***/ }), +/* 96 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _button = __webpack_require__(21); + +var _button2 = _interopRequireDefault(_button); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements UI Button + * @author NHN Ent. FE Development Lab + */ + + +/** + * Toolbar Button UI + * @extends {ToolbarItem} + */ +var ToolbarButton = function (_Button) { + _inherits(ToolbarButton, _Button); + + function ToolbarButton() { + _classCallCheck(this, ToolbarButton); + + return _possibleConstructorReturn(this, (ToolbarButton.__proto__ || Object.getPrototypeOf(ToolbarButton)).apply(this, arguments)); + } + + return ToolbarButton; +}(_button2.default); + +exports.default = ToolbarButton; + +/***/ }), +/* 97 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _toolbar = __webpack_require__(43); + +var _toolbar2 = _interopRequireDefault(_toolbar); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview implements DefaultToolbar + * @author NHN Ent. FE Development Lab + */ + + +var PopupDropdownToolbar = function (_LayerPopup) { + _inherits(PopupDropdownToolbar, _LayerPopup); + + /** + * constructor + * @param {object} options - popup options + */ + function PopupDropdownToolbar(options) { + _classCallCheck(this, PopupDropdownToolbar); + + options = _tuiCodeSnippet2.default.extend({ + header: false, + className: 'te-dropdown-toolbar' + }, options); + return _possibleConstructorReturn(this, (PopupDropdownToolbar.__proto__ || Object.getPrototypeOf(PopupDropdownToolbar)).call(this, options)); + } + + /** + * get toolbar instance it contains + * @returns {Toolbar} - toolbar instance + */ + + /** + * open event string + * @memberof PopupDropdownToolbar + * @static + * @type {ToolbarButton} + */ + + + _createClass(PopupDropdownToolbar, [{ + key: 'getToolbar', + value: function getToolbar() { + return this._toolbar; + } + + /** + * get toolbar items + * @returns {ToolbarItem[]} - toolbar items + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'getItems', + value: function getItems() { + return this.getToolbar().getItems(); + } + + /** + * get toolbar item at given index + * @param {number} index - item index + * @returns {ToolbarItem} - toolbar item at the index + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'getItem', + value: function getItem(index) { + return this.getToolbar().getItem(index); + } + + /** + * set toolbar items + * @param {ToolbarItem[]} items - toolbar items + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'setItems', + value: function setItems(items) { + this.getToolbar().setItems(items); + } + + /** + * add toolbar item + * @param {ToolbarItem|string|object} item - toolbar item + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'addItem', + value: function addItem(item) { + this.getToolbar().addItem(item); + } + + /** + * insert toolbar item + * @param {number} index - index at given item inserted + * @param {ToolbarItem|string|object} item - toolbar item + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'insertItem', + value: function insertItem(index, item) { + this.getToolbar().insertItem(index, item); + } + + /** + * get index of given item + * @param {ToolbarItem} item - toolbar item + * @returns {number} - index of given toolbar item + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'indexOfItem', + value: function indexOfItem(item) { + return this.getToolbar().indexOfItem(item); + } + + /** + * remove an item + * @param {number} index - item index to remove + * @param {boolean} destroy - destroy item or not + * @returns {ToolbarItem} - removed item + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'removeItem', + value: function removeItem(index, destroy) { + return this.getToolbar().removeItem(index, destroy); + } + + /** + * remove all toolbar items + * @memberof PopupDropdownToolbar + */ + + }, { + key: 'removeAllItems', + value: function removeAllItems() { + this.getToolbar().removeAllItems(); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupDropdownToolbar + * @protected + * @override + */ + + }, { + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupDropdownToolbar.prototype.__proto__ || Object.getPrototypeOf(PopupDropdownToolbar.prototype), '_initInstance', this).call(this, options); + + var $button = options.$button, + eventManager = options.eventManager; + + + this._$button = $button; + this._eventManager = eventManager; + this._toolbar = new _toolbar2.default(eventManager); + } + + /** + * initialize DOM, render popup + * @memberof PopupDropdownToolbar + * @protected + */ + + }, { + key: '_initDOM', + value: function _initDOM() { + _get(PopupDropdownToolbar.prototype.__proto__ || Object.getPrototypeOf(PopupDropdownToolbar.prototype), '_initDOM', this).call(this); + + this.setContent(this._toolbar.$el); + } + + /** + * bind editor events + * @memberof PopupDropdownToolbar + * @protected + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this2 = this; + + _get(PopupDropdownToolbar.prototype.__proto__ || Object.getPrototypeOf(PopupDropdownToolbar.prototype), '_initEditorEvent', this).call(this); + + this._eventManager.listen('focus', function () { + return _this2.hide(); + }); + this._eventManager.listen('closeAllPopup', function () { + return _this2.hide(); + }); + this._eventManager.listen(PopupDropdownToolbar.OPEN_EVENT, function () { + var isShown = _this2.isShow(); + _this2._eventManager.emit('closeAllPopup'); + if (!isShown) { + _this2.show(); + } + + // to give toolbar element enough width before the calculation + _this2.$el.css({ + left: '-1000px' + }); + var $button = _this2._$button; + var position = $button.position(); + var buttonOuterHeightWithMargin = $button.outerHeight(true); + var buttonMarginBottom = (buttonOuterHeightWithMargin - $button.outerHeight()) / 2; + var top = position.top + buttonOuterHeightWithMargin - buttonMarginBottom; + var left = position.left + $button.outerWidth(true) - _this2.$el.outerWidth(true); + + _this2.$el.css({ + top: top, + left: left + }); + }); + } + }]); + + return PopupDropdownToolbar; +}(_layerpopup2.default); + +Object.defineProperty(PopupDropdownToolbar, 'OPEN_EVENT', { + enumerable: true, + writable: true, + value: 'openDropdownToolbar' +}); +exports.default = PopupDropdownToolbar; + +/***/ }), +/* 98 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _uicontroller = __webpack_require__(14); + +var _uicontroller2 = _interopRequireDefault(_uicontroller); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements ui mode switch + * @author NHN Ent. FE Development Lab + */ + + +var MARKDOWN = 'markdown'; +var WYSIWYG = 'wysiwyg'; + +/** + * Class ModeSwitch + * UI Control for switch between Markdown and WYSIWYG + * @extends {UIController} + */ + +var ModeSwitch = function (_UIController) { + _inherits(ModeSwitch, _UIController); + + /** + * Creates an instance of ModeSwitch. + * @param {jQuery} $rootElement - root jquery element + * @param {string} initialType - initial type of editor + * @memberof ModeSwitch + */ + + + /** + * current mode + * @memberof ModeSwitch + * @type {String} + * @private + */ + + /** + * mode switch type + * @memberof ModeSwitch + * @property {string} MARKDOWN - Markdown + * @property {string} WYSIWYG - WYSIWYG + * @static + */ + function ModeSwitch($rootElement, initialType) { + _classCallCheck(this, ModeSwitch); + + var _this = _possibleConstructorReturn(this, (ModeSwitch.__proto__ || Object.getPrototypeOf(ModeSwitch)).call(this, { + tagName: 'div', + className: 'te-mode-switch' + })); + + Object.defineProperty(_this, '_buttons', { + enumerable: true, + writable: true, + value: {} + }); + + + _this._render($rootElement); + _this._switchType(_tuiCodeSnippet2.default.isExisty(initialType) ? initialType : MARKDOWN); + return _this; + } + + /** + * is the switch tab bar shown + * @returns {Boolean} - showing status + */ + + + /** + * root element + * @type {jQuery} + */ + + + /** + * mode switch buttons + * @memberof ModeSwitch + * @type {Object} + * @private + */ + + + _createClass(ModeSwitch, [{ + key: 'isShown', + value: function isShown() { + return this._$rootElement.css('display') === 'block'; + } + + /** + * show switch tab bar + * @memberof ModeSwitch + */ + + }, { + key: 'show', + value: function show() { + this._$rootElement.css('display', 'block'); + } + + /** + * hide switch tab bar + * @memberof ModeSwitch + */ + + }, { + key: 'hide', + value: function hide() { + this._$rootElement.css('display', 'none'); + } + }, { + key: '_render', + value: function _render($rootElement) { + this._buttons.$markdown = (0, _jquery2.default)(''); + this._buttons.$wysiwyg = (0, _jquery2.default)(''); + this.$el.append(this._buttons.$markdown); + this.$el.append(this._buttons.$wysiwyg); + + if ($rootElement) { + $rootElement.append(this.$el); + this._$rootElement = $rootElement; + } + + this.on('click .markdown', this._changeMarkdown.bind(this)); + this.on('click .wysiwyg', this._changeWysiwyg.bind(this)); + + this.show(); + } + }, { + key: '_changeMarkdown', + value: function _changeMarkdown() { + this._switchType(MARKDOWN); + } + }, { + key: '_changeWysiwyg', + value: function _changeWysiwyg() { + this._switchType(WYSIWYG); + } + }, { + key: '_setActiveButton', + value: function _setActiveButton(type) { + this._buttons.$markdown.removeClass('active'); + this._buttons.$wysiwyg.removeClass('active'); + this._buttons['$' + type].addClass('active'); + } + }, { + key: '_switchType', + value: function _switchType(type) { + if (this._type === type) { + return; + } + + this._type = type; + this._setActiveButton(type); + this.trigger('modeSwitched', this._type); + } + }]); + + return ModeSwitch; +}(_uicontroller2.default); + +Object.defineProperty(ModeSwitch, 'TYPE', { + enumerable: true, + writable: true, + value: { + MARKDOWN: MARKDOWN, + WYSIWYG: WYSIWYG + } +}); +exports.default = ModeSwitch; + +/***/ }), +/* 99 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements PopupAddLink + * @author NHN Ent. FE Development Lab + */ + + +var URL_REGEX = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})(\/([^\s]*))?$/; + +/** + * Class PopupAddLink + * It implements a link Add Popup + * @extends {LayerPopup} + */ + +var PopupAddLink = function (_LayerPopup) { + _inherits(PopupAddLink, _LayerPopup); + + /** + * Creates an instance of PopupAddLink. + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupAddLink + */ + function PopupAddLink(options) { + _classCallCheck(this, PopupAddLink); + + var POPUP_CONTENT = '\n \n \n \n \n
    \n \n \n
    \n '; + options = _tuiCodeSnippet2.default.extend({ + header: true, + title: _i18n2.default.get('Insert link'), + className: 'te-popup-add-link tui-editor-popup', + content: POPUP_CONTENT + }, options); + return _possibleConstructorReturn(this, (PopupAddLink.__proto__ || Object.getPrototypeOf(PopupAddLink)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupAddLink + * @protected + * @override + */ + + + _createClass(PopupAddLink, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupAddLink.prototype.__proto__ || Object.getPrototypeOf(PopupAddLink.prototype), '_initInstance', this).call(this, options); + + this._editor = options.editor; + this._eventManager = options.editor.eventManager; + } + + /** + * initialize DOM, render popup + * @memberof PopupAddLink + * @protected + * @override + */ + + }, { + key: '_initDOM', + value: function _initDOM() { + _get(PopupAddLink.prototype.__proto__ || Object.getPrototypeOf(PopupAddLink.prototype), '_initDOM', this).call(this); + + var el = this.$el.get(0); + this._inputText = el.querySelector('.te-link-text-input'); + this._inputURL = el.querySelector('.te-url-input'); + } + + /** + * bind DOM events + * @memberof PopupAddLink + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupAddLink.prototype.__proto__ || Object.getPrototypeOf(PopupAddLink.prototype), '_initDOMEvent', this).call(this); + + this.on('click .te-close-button', function () { + return _this2.hide(); + }); + this.on('click .te-ok-button', function () { + return _this2._addLink(); + }); + + this.on('shown', function () { + var inputText = _this2._inputText; + var inputURL = _this2._inputURL; + + var selectedText = _this2._editor.getSelectedText().trim(); + + inputText.value = selectedText; + if (URL_REGEX.exec(selectedText)) { + inputURL.value = selectedText; + } + + if (selectedText.length > 0 && inputURL.value.length < 1) { + inputURL.focus(); + } else { + inputText.focus(); + inputText.setSelectionRange(0, selectedText.length); + } + }); + + this.on('hidden', function () { + _this2._resetInputs(); + }); + } + + /** + * bind editor events + * @memberof PopupAddLink + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupAddLink.prototype.__proto__ || Object.getPrototypeOf(PopupAddLink.prototype), '_initEditorEvent', this).call(this); + + var eventManager = this._eventManager; + eventManager.listen('focus', function () { + return _this3.hide(); + }); + eventManager.listen('closeAllPopup', function () { + return _this3.hide(); + }); + eventManager.listen('openPopupAddLink', function () { + eventManager.emit('closeAllPopup'); + _this3.show(); + }); + } + }, { + key: '_addLink', + value: function _addLink() { + var _getValue2 = this._getValue(), + url = _getValue2.url, + linkText = _getValue2.linkText; + + this._clearValidationStyle(); + + if (linkText.length < 1) { + (0, _jquery2.default)(this._inputText).addClass('wrong'); + + return; + } + if (url.length < 1) { + (0, _jquery2.default)(this._inputURL).addClass('wrong'); + + return; + } + + this._eventManager.emit('command', 'AddLink', { + linkText: linkText, + url: url + }); + this.hide(); + } + }, { + key: '_getValue', + value: function _getValue() { + var url = this._inputURL.value; + var linkText = this._inputText.value; + + return { + url: url, + linkText: linkText + }; + } + }, { + key: '_clearValidationStyle', + value: function _clearValidationStyle() { + (0, _jquery2.default)(this._inputURL).removeClass('wrong'); + (0, _jquery2.default)(this._inputText).removeClass('wrong'); + } + }, { + key: '_resetInputs', + value: function _resetInputs() { + this._inputText.value = ''; + this._inputURL.value = ''; + this._clearValidationStyle(); + } + }]); + + return PopupAddLink; +}(_layerpopup2.default); + +exports.default = PopupAddLink; + +/***/ }), +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _tab = __webpack_require__(46); + +var _tab2 = _interopRequireDefault(_tab); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements PopupAddImage + * @author NHN Ent. FE Development Lab + */ + + +var CLASS_IMAGE_URL_INPUT = 'te-image-url-input'; +var CLASS_IMAGE_FILE_INPUT = 'te-image-file-input'; +var CLASS_ALT_TEXT_INPUT = 'te-alt-text-input'; +var CLASS_OK_BUTTON = 'te-ok-button'; +var CLASS_CLOSE_BUTTON = 'te-close-button'; +var CLASS_FILE_TYPE = 'te-file-type'; +var CLASS_URL_TYPE = 'te-url-type'; +var CLASS_TAB_SECTION = 'te-tab-section'; +var TYPE_UI = 'ui'; + +/** + * Class PopupAddImage + * It implements a Image Add Popup + * @extends {LayerPopup} + */ + +var PopupAddImage = function (_LayerPopup) { + _inherits(PopupAddImage, _LayerPopup); + + /** + * Creates an instance of PopupAddImage. + * @param {LayerPopupOption} options - layer popup option + * @memberof PopupAddImage + */ + function PopupAddImage(options) { + _classCallCheck(this, PopupAddImage); + + var POPUP_CONTENT = '\n
    \n
    \n \n \n
    \n
    \n \n \n
    \n \n \n
    \n \n \n
    \n '; + options = _tuiCodeSnippet2.default.extend({ + header: true, + title: _i18n2.default.get('Insert image'), + className: 'te-popup-add-image tui-editor-popup', + content: POPUP_CONTENT + }, options); + return _possibleConstructorReturn(this, (PopupAddImage.__proto__ || Object.getPrototypeOf(PopupAddImage)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupAddImage + * @protected + * @override + */ + + + _createClass(PopupAddImage, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupAddImage.prototype.__proto__ || Object.getPrototypeOf(PopupAddImage.prototype), '_initInstance', this).call(this, options); + + this.eventManager = options.eventManager; + } + + /** + * initialize DOM, render popup + * @memberof PopupAddImage + * @protected + * @override + */ + + }, { + key: '_initDOM', + value: function _initDOM() { + _get(PopupAddImage.prototype.__proto__ || Object.getPrototypeOf(PopupAddImage.prototype), '_initDOM', this).call(this); + + var $popup = this.$el; + + this._$imageUrlInput = $popup.find('.' + CLASS_IMAGE_URL_INPUT); + this._$imageFileInput = $popup.find('.' + CLASS_IMAGE_FILE_INPUT); + this._$altTextInput = $popup.find('.' + CLASS_ALT_TEXT_INPUT); + + var $fileTypeSection = $popup.find('.' + CLASS_FILE_TYPE); + var $urlTypeSection = $popup.find('.' + CLASS_URL_TYPE); + var $tabSection = this.$body.find('.' + CLASS_TAB_SECTION); + this.tab = new _tab2.default({ + initName: _i18n2.default.get('File'), + items: [_i18n2.default.get('File'), _i18n2.default.get('URL')], + sections: [$fileTypeSection, $urlTypeSection] + }); + $tabSection.append(this.tab.$el); + } + + /** + * bind DOM events + * @memberof PopupAddImage + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupAddImage.prototype.__proto__ || Object.getPrototypeOf(PopupAddImage.prototype), '_initDOMEvent', this).call(this); + + this.on('shown', function () { + return _this2._$imageUrlInput.focus(); + }); + this.on('hidden', function () { + return _this2._resetInputs(); + }); + + this.on('change .' + CLASS_IMAGE_FILE_INPUT, function () { + var filename = _this2._$imageFileInput.val().split('\\').pop(); + _this2._$altTextInput.val(filename); + }); + + this.on('click .' + CLASS_CLOSE_BUTTON, function () { + return _this2.hide(); + }); + this.on('click .' + CLASS_OK_BUTTON, function () { + var imageUrl = _this2._$imageUrlInput.val(); + var altText = _this2._$altTextInput.val(); + + if (imageUrl) { + _this2._applyImage(imageUrl, altText); + } else { + var _$imageFileInput$get = _this2._$imageFileInput.get(0), + files = _$imageFileInput$get.files; + + if (files.length) { + var imageFile = files.item(0); + var hookCallback = function hookCallback(url, text) { + return _this2._applyImage(url, altText || text); + }; + + _this2.eventManager.emit('addImageBlobHook', imageFile, hookCallback, TYPE_UI); + } + } + + _this2.hide(); + }); + + this.tab.on('itemClick', function () { + return _this2._resetInputs(); + }); + } + + /** + * bind editor events + * @memberof PopupAddImage + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupAddImage.prototype.__proto__ || Object.getPrototypeOf(PopupAddImage.prototype), '_initEditorEvent', this).call(this); + + this.eventManager.listen('focus', function () { + return _this3.hide(); + }); + this.eventManager.listen('closeAllPopup', function () { + return _this3.hide(); + }); + + this.eventManager.listen('openPopupAddImage', function () { + _this3.eventManager.emit('closeAllPopup'); + _this3.show(); + }); + } + }, { + key: '_applyImage', + value: function _applyImage(imageUrl, altText) { + this.eventManager.emit('command', 'AddImage', { + imageUrl: imageUrl, + altText: altText || 'image' + }); + this.hide(); + } + }, { + key: '_resetInputs', + value: function _resetInputs() { + this.$el.find('input').val(''); + } + }]); + + return PopupAddImage; +}(_layerpopup2.default); + +exports.default = PopupAddImage; + +/***/ }), +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements PopupTableUtils + * @author NHN Ent. FE Development Lab + */ + + +/** + * PopupTableUtils + * It implements table utils popup + * @extends {LayerPopup} + */ +var PopupTableUtils = function (_LayerPopup) { + _inherits(PopupTableUtils, _LayerPopup); + + /** + * Creates an instance of PopupTableUtils. + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupTableUtils + */ + function PopupTableUtils(options) { + _classCallCheck(this, PopupTableUtils); + + var POPUP_CONTENT = '\n \n \n \n \n
    \n \n \n \n
    \n \n '; + options = _tuiCodeSnippet2.default.extend({ + header: false, + className: 'te-popup-table-utils', + content: POPUP_CONTENT + }, options); + return _possibleConstructorReturn(this, (PopupTableUtils.__proto__ || Object.getPrototypeOf(PopupTableUtils)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupTableUtils + * @protected + * @override + */ + + + _createClass(PopupTableUtils, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupTableUtils.prototype.__proto__ || Object.getPrototypeOf(PopupTableUtils.prototype), '_initInstance', this).call(this, options); + this.eventManager = options.eventManager; + } + + /** + * bind DOM events + * @memberof PopupTableUtils + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupTableUtils.prototype.__proto__ || Object.getPrototypeOf(PopupTableUtils.prototype), '_initDOMEvent', this).call(this); + + this.on('click .te-table-add-row', function () { + return _this2.eventManager.emit('command', 'AddRow'); + }); + this.on('click .te-table-add-col', function () { + return _this2.eventManager.emit('command', 'AddCol'); + }); + this.on('click .te-table-remove-row', function () { + return _this2.eventManager.emit('command', 'RemoveRow'); + }); + this.on('click .te-table-col-align-left', function () { + return _this2.eventManager.emit('command', 'AlignCol', 'left'); + }); + this.on('click .te-table-col-align-center', function () { + return _this2.eventManager.emit('command', 'AlignCol', 'center'); + }); + this.on('click .te-table-col-align-right', function () { + return _this2.eventManager.emit('command', 'AlignCol', 'right'); + }); + this.on('click .te-table-remove-col', function () { + return _this2.eventManager.emit('command', 'RemoveCol'); + }); + this.on('click .te-table-remove', function () { + return _this2.eventManager.emit('command', 'RemoveTable'); + }); + } + + /** + * bind editor events + * @memberof PopupTableUtils + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupTableUtils.prototype.__proto__ || Object.getPrototypeOf(PopupTableUtils.prototype), '_initEditorEvent', this).call(this); + + this.eventManager.listen('focus', function () { + return _this3.hide(); + }); + this.eventManager.listen('mousedown', function () { + return _this3.hide(); + }); + this.eventManager.listen('closeAllPopup', function () { + return _this3.hide(); + }); + + this.eventManager.listen('openPopupTableUtils', function (event) { + var offset = _this3.$el.parent().offset(); + var x = event.clientX - offset.left; + var y = event.clientY - offset.top + (0, _jquery2.default)(window).scrollTop(); + + _this3.$el.css({ + position: 'absolute', + top: y + 5, // beside mouse pointer + left: x + 10 + }); + + _this3.eventManager.emit('closeAllPopup'); + _this3.show(); + }); + } + }]); + + return PopupTableUtils; +}(_layerpopup2.default); + +exports.default = PopupTableUtils; + +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements PopupAddTable + * @author NHN Ent. FE Development Lab + */ + + +var CLASS_TABLE_SELECTION = 'te-table-selection'; +var CLASS_TABLE_HEADER = 'te-table-header'; +var CLASS_TABLE_BODY = 'te-table-body'; +var CLASS_SELECTION_AREA = 'te-selection-area'; +var CLASS_DESCRIPTION = 'te-description'; + +var POPUP_CONTENT = '\n
    \n
    \n
    \n
    \n
    \n

    \n'; + +var CELL_WIDTH = 25; +var CELL_HEIGHT = 17; +var MIN_ROW_INDEX = 7; +var MAX_ROW_INDEX = 14; +var MIN_COL_INDEX = 5; +var MAX_COL_INDEX = 9; +var MIN_ROW_SELECTION_INDEX = 1; +var MIN_COL_SELECTION_INDEX = 1; +var HEADER_ROW_COUNT = 1; +var LAST_BORDER = 1; + +/** + * Class PopupAddTable + * It implements Popup to add a table + * @extends {LayerPopup} + */ + +var PopupAddTable = function (_LayerPopup) { + _inherits(PopupAddTable, _LayerPopup); + + /** + * Creates an instance of PopupAddTable. + * @param {LayerPopupOption} options - layer popup option + * @memberof PopupAddTable + */ + + /** + * Toolbar Button which the Popup is bound to. + * + * @memberof PopupAddTable + * @type {jQuery} + * @private + */ + function PopupAddTable(options) { + _classCallCheck(this, PopupAddTable); + + options = _tuiCodeSnippet2.default.extend({ + header: false, + className: 'te-popup-add-table', + content: POPUP_CONTENT + }, options); + return _possibleConstructorReturn(this, (PopupAddTable.__proto__ || Object.getPrototypeOf(PopupAddTable)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupAddTable + * @protected + * @override + */ + + + /** + * EventManager instance + * + * @memberof PopupAddTabe + * @type {EventManager} + * @private + */ + + + _createClass(PopupAddTable, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupAddTable.prototype.__proto__ || Object.getPrototypeOf(PopupAddTable.prototype), '_initInstance', this).call(this, options); + + this._selectedBound = {}; + this._tableBound = {}; + this._eventManager = options.eventManager; + this._$button = options.$button; + } + + /** + * initialize DOM, render popup + * @memberof PopupAddTable + * @protected + * @override + */ + + }, { + key: '_initDOM', + value: function _initDOM() { + _get(PopupAddTable.prototype.__proto__ || Object.getPrototypeOf(PopupAddTable.prototype), '_initDOM', this).call(this); + + this._cacheElements(); + this._setTableSizeByBound(MIN_COL_INDEX, MIN_ROW_INDEX); + } + + /** + * bind DOM events + * @memberof PopupAddTable + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent(options) { + var _this2 = this; + + _get(PopupAddTable.prototype.__proto__ || Object.getPrototypeOf(PopupAddTable.prototype), '_initDOMEvent', this).call(this, options); + + this.on('mousemove .' + CLASS_TABLE_SELECTION, function (ev) { + var x = ev.pageX - _this2._selectionOffset.left; + var y = ev.pageY - _this2._selectionOffset.top; + var bound = _this2._getSelectionBoundByOffset(x, y); + + _this2._resizeTableBySelectionIfNeed(bound.col, bound.row); + + _this2._setSelectionAreaByBound(bound.col, bound.row); + _this2._setDisplayText(bound.col, bound.row); + _this2._setSelectedBound(bound.col, bound.row); + }); + + this.on('click .' + CLASS_TABLE_SELECTION, function () { + var tableSize = _this2._getSelectedTableSize(); + _this2._eventManager.emit('command', 'Table', tableSize.col, tableSize.row); + }); + } + + /** + * bind editor events + * @memberof PopupAddTable + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupAddTable.prototype.__proto__ || Object.getPrototypeOf(PopupAddTable.prototype), '_initEditorEvent', this).call(this); + + this._eventManager.listen('focus', function () { + return _this3.hide(); + }); + this._eventManager.listen('closeAllPopup', function () { + return _this3.hide(); + }); + + this._eventManager.listen('openPopupAddTable', function () { + var $button = _this3._$button; + + var _$button$get = $button.get(0), + offsetTop = _$button$get.offsetTop, + offsetLeft = _$button$get.offsetLeft; + + _this3.$el.css({ + top: offsetTop + $button.outerHeight(), + left: offsetLeft + }); + _this3._eventManager.emit('closeAllPopup'); + _this3.show(); + _this3._selectionOffset = _this3.$el.find('.' + CLASS_TABLE_SELECTION).offset(); + }); + } + + /** + * _cacheElements + * Cache elements for use + * @private + */ + + }, { + key: '_cacheElements', + value: function _cacheElements() { + this.$header = this.$el.find('.' + CLASS_TABLE_HEADER); + this.$body = this.$el.find('.' + CLASS_TABLE_BODY); + this.$selection = this.$el.find('.' + CLASS_SELECTION_AREA); + this.$desc = this.$el.find('.' + CLASS_DESCRIPTION); + } + + /** + * _resizeTableBySelectionIfNeed + * Resize table if need + * @param {number} col column index + * @param {number} row row index + * @private + */ + + }, { + key: '_resizeTableBySelectionIfNeed', + value: function _resizeTableBySelectionIfNeed(col, row) { + var resizedBound = this._getResizedTableBound(col, row); + + if (resizedBound) { + this._setTableSizeByBound(resizedBound.col, resizedBound.row); + } + } + + /** + * _getResizedTableBound + * Get resized table bound if Need + * @param {number} col column index + * @param {number} row row index + * @returns {object} bound + * @private + */ + + }, { + key: '_getResizedTableBound', + value: function _getResizedTableBound(col, row) { + var resizedCol = void 0, + resizedRow = void 0, + resizedBound = void 0; + + if (col >= MIN_COL_INDEX && col < MAX_COL_INDEX) { + resizedCol = col + 1; + } else if (col < MIN_COL_INDEX) { + resizedCol = MIN_COL_INDEX; + } + + if (row >= MIN_ROW_INDEX && row < MAX_ROW_INDEX) { + resizedRow = row + 1; + } else if (row < MIN_ROW_INDEX) { + resizedRow = MIN_ROW_INDEX; + } + + if (this._isNeedResizeTable(resizedCol, resizedRow)) { + resizedBound = { + row: resizedRow || this._tableBound.row, + col: resizedCol || this._tableBound.col + }; + } + + return resizedBound; + } + + /** + * _isNeedResizeTable + * check if need resize table + * @param {number} col column index + * @param {number} row row index + * @returns {boolean} result + * @private + */ + + }, { + key: '_isNeedResizeTable', + value: function _isNeedResizeTable(col, row) { + return col && col !== this._tableBound.col || row && row !== this._tableBound.row; + } + + /** + * _getBoundByOffset + * Get bound by offset + * @param {number} x offset + * @param {number} y offset + * @returns {object} bound + * @private + */ + + }, { + key: '_getBoundByOffset', + value: function _getBoundByOffset(x, y) { + var row = parseInt(y / CELL_HEIGHT, 10); + var col = parseInt(x / CELL_WIDTH, 10); + + return { + row: row, + col: col + }; + } + + /** + * _getOffsetByBound + * Get offset by bound + * @param {number} col column index + * @param {number} row row index + * @returns {object} offset + * @private + */ + + }, { + key: '_getOffsetByBound', + value: function _getOffsetByBound(col, row) { + var x = col * CELL_WIDTH + CELL_WIDTH, + y = row * CELL_HEIGHT + CELL_HEIGHT; + + return { + x: x, + y: y + }; + } + + /** + * _setTableSizeByBound + * Set table size with bound + * @param {number} col column index + * @param {number} row row index + * @private + */ + + }, { + key: '_setTableSizeByBound', + value: function _setTableSizeByBound(col, row) { + var boundOffset = this._getOffsetByBound(col, row - HEADER_ROW_COUNT); + this._setTableSize(boundOffset.x, boundOffset.y); + this._tableBound.row = row; + this._tableBound.col = col; + } + + /** + * _getSelectionBoundByOffset + * Get selection bound that process with range by offset + * @param {number} x offset + * @param {number} y offset + * @returns {object} bound + * @private + */ + + }, { + key: '_getSelectionBoundByOffset', + value: function _getSelectionBoundByOffset(x, y) { + var bound = this._getBoundByOffset(x, y); + + if (bound.row < MIN_ROW_SELECTION_INDEX) { + bound.row = MIN_ROW_SELECTION_INDEX; + } else if (bound.row > this._tableBound.row) { + bound.row = this._tableBound.row; + } + + if (bound.col < MIN_COL_SELECTION_INDEX) { + bound.col = MIN_COL_SELECTION_INDEX; + } else if (bound.col > this._tableBound.col) { + bound.col = this._tableBound.col; + } + + return bound; + } + + /** + * _setSelectionAreaByBound + * Set selection area with bound + * @param {number} col column index + * @param {number} row row index + * @private + */ + + }, { + key: '_setSelectionAreaByBound', + value: function _setSelectionAreaByBound(col, row) { + var boundOffset = this._getOffsetByBound(col, row); + this._setSelectionArea(boundOffset.x, boundOffset.y); + } + + /** + * _setSelectedBound + * Set selected bound + * @param {number} col column index + * @param {number} row row index + * @private + */ + + }, { + key: '_setSelectedBound', + value: function _setSelectedBound(col, row) { + this._selectedBound.col = col; + this._selectedBound.row = row; + } + + /** + * _getSelectedTableSize + * Get selected table size + * @returns {object} bound + * @private + */ + + }, { + key: '_getSelectedTableSize', + value: function _getSelectedTableSize() { + return { + row: this._selectedBound.row + 1, + col: this._selectedBound.col + 1 + }; + } + + /** + * _setDisplayText + * Set selected table size text for display + * @param {number} col column index + * @param {number} row row index + * @private + */ + + }, { + key: '_setDisplayText', + value: function _setDisplayText(col, row) { + this.$desc.html(col + 1 + ' x ' + (row + 1)); + } + + /** + * _setTableSize + * Set table element size + * @param {number} x offset + * @param {number} y offset + * @private + */ + + }, { + key: '_setTableSize', + value: function _setTableSize(x, y) { + x += LAST_BORDER; + y += LAST_BORDER; + + this.$header.css({ + height: CELL_HEIGHT, + width: x + }); + + this.$body.css({ + height: y, + width: x + }); + + this.$el.css({ + width: x + 30 + }); + } + + /** + * _setSelectionArea + * Set selection element size + * @param {number} x offset + * @param {number} y offset + * @private + */ + + }, { + key: '_setSelectionArea', + value: function _setSelectionArea(x, y) { + x += LAST_BORDER; + y += LAST_BORDER; + + this.$selection.css({ + height: y, + width: x + }); + } + }]); + + return PopupAddTable; +}(_layerpopup2.default); + +PopupAddTable.CELL_WIDTH = CELL_WIDTH; +PopupAddTable.CELL_HEIGHT = CELL_HEIGHT; +PopupAddTable.MIN_ROW_SELECTION_INDEX = MIN_ROW_SELECTION_INDEX; +PopupAddTable.MIN_COL_SELECTION_INDEX = MIN_COL_SELECTION_INDEX; + +exports.default = PopupAddTable; + +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements PopupAddTable + * @author NHN Ent. FE Development Lab + */ + + +/** + * Class PopupHeading + * It implements Popup to add headings + * @extends {LayerPopup} + */ +var PopupAddHeading = function (_LayerPopup) { + _inherits(PopupAddHeading, _LayerPopup); + + /** + * Creates an instance of PopupAddHeading. + * @param {LayerPopupOption} options - layer popup option + * @memberof PopupAddHeading + */ + function PopupAddHeading(options) { + _classCallCheck(this, PopupAddHeading); + + var POPUP_CONTENT = '\n
      \n
    • ' + _i18n2.default.get('Heading') + ' 1

    • \n
    • ' + _i18n2.default.get('Heading') + ' 2

    • \n
    • ' + _i18n2.default.get('Heading') + ' 3

    • \n
    • ' + _i18n2.default.get('Heading') + ' 4

    • \n
    • ' + _i18n2.default.get('Heading') + ' 5
    • \n
    • ' + _i18n2.default.get('Heading') + ' 6
    • \n
    • ' + _i18n2.default.get('Paragraph') + '
    • \n
    \n '; + options = _tuiCodeSnippet2.default.extend({ + header: false, + className: 'te-heading-add', + content: POPUP_CONTENT + }, options); + return _possibleConstructorReturn(this, (PopupAddHeading.__proto__ || Object.getPrototypeOf(PopupAddHeading)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupAddHeading + * @protected + * @override + */ + + + _createClass(PopupAddHeading, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupAddHeading.prototype.__proto__ || Object.getPrototypeOf(PopupAddHeading.prototype), '_initInstance', this).call(this, options); + + this._eventManager = options.eventManager; + this._$button = options.$button; + } + + /** + * bind DOM events + * @memberof PopupAddHeading + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupAddHeading.prototype.__proto__ || Object.getPrototypeOf(PopupAddHeading.prototype), '_initDOMEvent', this).call(this); + + this.on('click li', function (ev) { + var $li = (0, _jquery2.default)(ev.target).closest('li'); + _this2._eventManager.emit('command', $li.data('type'), $li.data('value')); + }); + } + + /** + * bind editor events + * @memberof PopupAddHeading + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupAddHeading.prototype.__proto__ || Object.getPrototypeOf(PopupAddHeading.prototype), '_initEditorEvent', this).call(this); + + this._eventManager.listen('focus', this.hide.bind(this)); + this._eventManager.listen('closeAllPopup', this.hide.bind(this)); + this._eventManager.listen('openHeadingSelect', function () { + var $button = _this3._$button; + + var _$button$get = $button.get(0), + offsetTop = _$button$get.offsetTop, + offsetLeft = _$button$get.offsetLeft; + + _this3.$el.css({ + top: offsetTop + $button.outerHeight(), + left: offsetLeft + }); + + _this3._eventManager.emit('closeAllPopup'); + _this3.show(); + }); + } + }]); + + return PopupAddHeading; +}(_layerpopup2.default); + +exports.default = PopupAddHeading; + +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements popup code block languages + * @author NHN Ent. FE Development Lab + */ + + +var BUTTON_CLASS_PREFIX = 'te-popup-code-block-lang-'; + +/** + * Class Popup code block languages select list + * @extends {LayerPopup} + */ + +var PopupCodeBlockLanguages = function (_LayerPopup) { + _inherits(PopupCodeBlockLanguages, _LayerPopup); + + /** + * Creates an instance of PopupCodeBlockLanguages. + * @param {LayerPopupOption} options - layer popup option + * @memberof PopupCodeBlockLanguages + */ + function PopupCodeBlockLanguages(options) { + _classCallCheck(this, PopupCodeBlockLanguages); + + var popupButtonsHTML = []; + var _options = options, + languages = _options.languages; + + languages.forEach(function (lang) { + return popupButtonsHTML.push(''); + }); + + options = _tuiCodeSnippet2.default.extend({ + header: false, + className: 'te-popup-code-block-languages', + content: popupButtonsHTML.join('') + }, options); + return _possibleConstructorReturn(this, (PopupCodeBlockLanguages.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupCodeBlockLanguages + * @protected + * @override + */ + + + _createClass(PopupCodeBlockLanguages, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), '_initInstance', this).call(this, options); + + this._onSelectedLanguage = null; + this._onDismissed = null; + this._currentButton = null; + this._$buttons = null; + this._languages = options.languages; + + this.eventManager = options.eventManager; + } + + /** + * initialize DOM, render popup + * @memberof PopupCodeBlockLanguages + * @protected + * @override + */ + + }, { + key: '_initDOM', + value: function _initDOM(options) { + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), '_initDOM', this).call(this, options); + + this.$el.css('z-index', 10000); + + this._$buttons = this.$el.find('button'); + this._activateButtonByIndex(0); + } + + /** + * bind DOM events + * @memberof PopupCodeBlockLanguages + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), '_initDOMEvent', this).call(this); + + var handler = function handler(event) { + var language = (0, _jquery2.default)(event.target).data('lang'); + if (_this2._onSelectedLanguage) { + _this2._onSelectedLanguage(language); + } + _this2.hide(); + }; + this._languages.forEach(function (lang) { + return _this2.on('mousedown .' + BUTTON_CLASS_PREFIX + lang, handler); + }); + } + + /** + * bind editor events + * @memberof PopupCodeBlockLanguages + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), '_initEditorEvent', this).call(this); + + this.eventManager.listen('openPopupCodeBlockLanguages', function (data) { + _this3.show(data.callback); + var elementStyle = _this3.$el.get(0).style; + elementStyle.top = data.offset.top + 'px'; + elementStyle.left = data.offset.left + 'px'; + _this3.setCurrentLanguage(data.language); + + return _this3; + }); + this.eventManager.listen('focus', function () { + return _this3.hide(); + }); + this.eventManager.listen('mousedown', function () { + return _this3.hide(); + }); + this.eventManager.listen('closeAllPopup', function () { + return _this3.hide(); + }); + this.eventManager.listen('closePopupCodeBlockLanguages', function () { + return _this3.hide(); + }); + this.eventManager.listen('scroll', function () { + return _this3.hide(); + }); + } + + /** + * activate an item by index + * @param {number} index - item index + * @private + * @memberof PopupCodeBlockLanguages + */ + + }, { + key: '_activateButtonByIndex', + value: function _activateButtonByIndex(index) { + if (this._currentButton) { + (0, _jquery2.default)(this._currentButton).removeClass('active'); + } + this._currentButton = this._$buttons.get(index); + (0, _jquery2.default)(this._currentButton).addClass('active'); + this._currentButton.scrollIntoView(); + } + + /** + * move to prev language + * @memberof PopupCodeBlockLanguages + */ + + }, { + key: 'prev', + value: function prev() { + var index = this._$buttons.index(this._currentButton) - 1; + if (index < 0) { + index = this._$buttons.length - 1; + } + this._activateButtonByIndex(index); + } + + /** + * move to next language + * @memberof PopupCodeBlockLanguages + */ + + }, { + key: 'next', + value: function next() { + var index = this._$buttons.index(this._currentButton) + 1; + if (index >= this._$buttons.length) { + index = 0; + } + this._activateButtonByIndex(index); + } + + /** + * current language + * @public + * @memberof PopupCodeBlockLanguages + * @returns {string} language + */ + + }, { + key: 'getCurrentLanguage', + value: function getCurrentLanguage() { + var language = (0, _jquery2.default)(this._currentButton).data('lang'); + + return language; + } + + /** + * set current language + * @param {string} language - current language + * @memberof PopupCodeBlockLanguages + */ + + }, { + key: 'setCurrentLanguage', + value: function setCurrentLanguage(language) { + var item = this._$buttons.filter('.' + BUTTON_CLASS_PREFIX + language); + if (item.length > 0) { + var index = this._$buttons.index(item); + this._activateButtonByIndex(index); + } + } + + /** + * show popup + * @param {object} callback - to be called on language selected & dismissed + * @protected + * @memberof PopupCodeBlockLanguages + */ + + }, { + key: 'show', + value: function show(callback) { + this._onSelectedLanguage = callback.selected; + this._onDismissed = callback.dismissed; + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), 'show', this).call(this); + } + + /** + * hide popup + * @memberof PopupCodeBlockLanguages + * @protected + */ + + }, { + key: 'hide', + value: function hide() { + if (this._onDismissed) { + this._onDismissed(); + } + this._onSelectedLanguage = null; + this._onDismissed = null; + _get(PopupCodeBlockLanguages.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockLanguages.prototype), 'hide', this).call(this); + } + }]); + + return PopupCodeBlockLanguages; +}(_layerpopup2.default); + +exports.default = PopupCodeBlockLanguages; + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _layerpopup = __webpack_require__(7); + +var _layerpopup2 = _interopRequireDefault(_layerpopup); + +var _scrollSyncSplit = __webpack_require__(106); + +var _scrollSyncSplit2 = _interopRequireDefault(_scrollSyncSplit); + +var _codeBlockEditor = __webpack_require__(107); + +var _codeBlockEditor2 = _interopRequireDefault(_codeBlockEditor); + +var _codeBlockPreview = __webpack_require__(108); + +var _codeBlockPreview2 = _interopRequireDefault(_codeBlockPreview); + +var _codeBlockLanguagesCombo = __webpack_require__(109); + +var _codeBlockLanguagesCombo2 = _interopRequireDefault(_codeBlockLanguagesCombo); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements popup code block editor + * @author NHN Ent. FE Development Lab + */ + + +var CLASS_PREFIX = 'popup-editor-'; +var CLASS_OK_BUTTON = 'te-ok-button'; +var CLASS_CLOSE_BUTTON = 'te-close-button'; +var CLASS_POPUP_CLOSE_BUTTON = 'tui-popup-close-button'; +var TEMPLATE_HEADER_BUTTONS = '\n \n \n \n \n'; + +/** + * Class popup code block editor + * @extends {LayerPopup} + */ + +var PopupCodeBlockEditor = function (_LayerPopup) { + _inherits(PopupCodeBlockEditor, _LayerPopup); + + /** + * Creates an instance of PopupCodeBlockEditor. + * @param {LayerPopupOption} options - layer popup option + * @memberof PopupCodeBlockEditor + */ + function PopupCodeBlockEditor(options) { + _classCallCheck(this, PopupCodeBlockEditor); + + var TEMPLATE_CONTENT = '\n
    \n
    \n \n \n
    \n '; + options = _tuiCodeSnippet2.default.extend({ + header: true, + title: 'CodeBlock Editor', + content: TEMPLATE_CONTENT, + className: 'tui-popup-code-block-editor', + headerButtons: TEMPLATE_HEADER_BUTTONS, + modal: true + }, options); + return _possibleConstructorReturn(this, (PopupCodeBlockEditor.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor)).call(this, options)); + } + + /** + * init instance. + * store properties & prepare before initialize DOM + * @param {LayerPopupOption} options - layer popup options + * @memberof PopupCodeBlockEditor + * @protected + * @override + */ + + + _createClass(PopupCodeBlockEditor, [{ + key: '_initInstance', + value: function _initInstance(options) { + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), '_initInstance', this).call(this, options); + + this.eventManager = options.eventManager; + this.convertor = options.convertor; + } + + /** + * initialize DOM, render popup + * @memberof PopupCodeBlockEditor + * @protected + * @override + */ + + }, { + key: '_initDOM', + value: function _initDOM(options) { + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), '_initDOM', this).call(this, options); + + var el = this.$el.get(0); + this._body = el.querySelector('.' + CLASS_PREFIX + 'body'); + this._toggleFitButton = el.querySelector('.' + CLASS_PREFIX + 'toggle-fit'); + this._togglePreviewButton = el.querySelector('.' + CLASS_PREFIX + 'toggle-preview'); + this._toggleScrollButton = el.querySelector('.' + CLASS_PREFIX + 'toggle-scroll'); + this._okButton = el.querySelector('.' + CLASS_OK_BUTTON); + this._closeButton = el.querySelector('.' + CLASS_CLOSE_BUTTON); + + this._codeMirrorWrapper = this._createCodeBlockEditor(); + this._previewWrapper = this._createPreview(); + this._scrollSyncSplit = new _scrollSyncSplit2.default(this._body, this._codeMirrorWrapper, this._previewWrapper); + + this._updateFitWindowButton(); + this._updatePreviewButton(); + this._updateScrollButton(); + + this._codeBlockLanguagesCombo = this._createCodeBlockLanguagesCombo(); + } + + /** + * bind DOM events + * @memberof PopupCodeBlockEditor + * @protected + * @override + */ + + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this2 = this; + + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), '_initDOMEvent', this).call(this); + + this.on('scroll', function (ev) { + return ev.preventDefault(); + }); + this.on('click .' + CLASS_PREFIX + 'toggle-fit', function () { + return _this2._toggleFitToWindow(); + }); + this.on('click .' + CLASS_PREFIX + 'toggle-preview', function () { + return _this2._togglePreview(); + }); + this.on('click .' + CLASS_PREFIX + 'toggle-scroll', function () { + return _this2._toggleScroll(); + }); + this.on('click .' + CLASS_OK_BUTTON, function () { + return _this2._save(); + }); + this.on('click .' + CLASS_CLOSE_BUTTON, function () { + return _this2.hide(); + }); + this.on('click .' + CLASS_PREFIX + 'close', function () { + return _this2.hide(); + }); + this.on('click .' + CLASS_PREFIX + 'editor-wrapper', function (ev) { + if (ev.target === _this2._codeMirrorWrapper) { + _this2._focusEditor(true); + } + }); + } + + /** + * bind editor events + * @memberof PopupCodeBlockEditor + * @protected + * @abstract + */ + + }, { + key: '_initEditorEvent', + value: function _initEditorEvent() { + var _this3 = this; + + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), '_initEditorEvent', this).call(this); + + this.eventManager.listen('openPopupCodeBlockEditor', function (codeBlockElement) { + _this3.eventManager.emit('closeAllPopup'); + _this3.show(codeBlockElement); + + return _this3; + }); + this.eventManager.listen('closeAllPopup', this.hide.bind(this)); + this.eventManager.listen('closePopupCodeBlockEditor', this.hide.bind(this)); + } + }, { + key: '_createCodeBlockEditor', + value: function _createCodeBlockEditor() { + var codeMirrorWrapper = document.createElement('div'); + codeMirrorWrapper.className = CLASS_PREFIX + 'editor-wrapper'; + + this._codeBlockEditor = new _codeBlockEditor2.default(codeMirrorWrapper, this.eventManager); + + return codeMirrorWrapper; + } + }, { + key: '_createPreview', + value: function _createPreview() { + var previewWrapper = document.createElement('div'); + this._codeBlockPreview = new _codeBlockPreview2.default((0, _jquery2.default)(previewWrapper), this.eventManager, this.convertor, this._codeBlockEditor); + + return previewWrapper; + } + }, { + key: '_createCodeBlockLanguagesCombo', + value: function _createCodeBlockLanguagesCombo() { + var _this4 = this; + + var titleElement = this.getTitleElement(); + var codeBlockLanguagesCombo = new _codeBlockLanguagesCombo2.default(this.eventManager); + + codeBlockLanguagesCombo.setOnLanguageSelected(function (selectedLanguage) { + _this4._codeBlockEditor.setLanguage(selectedLanguage); + _this4._codeBlockEditor.refresh(); + _this4._focusEditor(); + }); + + titleElement.innerHTML = 'CodeBlock Editor'; + titleElement.appendChild(codeBlockLanguagesCombo.getElement()); + + return codeBlockLanguagesCombo; + } + }, { + key: '_updateFitWindowButton', + value: function _updateFitWindowButton() { + (0, _jquery2.default)(this._toggleFitButton).toggleClass('active', this.isFitToWindow()); + } + }, { + key: '_updatePreviewButton', + value: function _updatePreviewButton() { + (0, _jquery2.default)(this._togglePreviewButton).toggleClass('active', this._scrollSyncSplit.isSplitView()); + } + }, { + key: '_updateScrollButton', + value: function _updateScrollButton() { + if (this._scrollSyncSplit.isSplitView()) { + this._toggleScrollButton.style.display = 'inline-block'; + } else { + this._toggleScrollButton.style.display = 'none'; + } + (0, _jquery2.default)(this._toggleScrollButton).toggleClass('active', this._scrollSyncSplit.isScrollSynced()); + } + }, { + key: '_focusEditor', + value: function _focusEditor(cursorToEnd) { + this._codeBlockEditor.focus(); + if (cursorToEnd) { + this._codeBlockEditor.moveCursorToEnd(); + } else { + this._codeBlockEditor.moveCursorToStart(); + } + } + }, { + key: '_togglePreview', + value: function _togglePreview() { + this._scrollSyncSplit.toggleSplitView(); + this._updatePreviewButton(); + this._updateScrollButton(); + this._codeBlockEditor.refresh(); + } + }, { + key: '_toggleFitToWindow', + value: function _toggleFitToWindow() { + this.toggleFitToWindow(); + this._updateFitWindowButton(); + this._codeBlockEditor.refresh(); + } + }, { + key: '_toggleScroll', + value: function _toggleScroll() { + this._scrollSyncSplit.toggleScrollSync(); + this._updateScrollButton(); + } + + /** + * store code mirror text to wysiwyg code block + * @memberof PopupCodeBlockEditor + * @private + */ + + }, { + key: '_save', + value: function _save() { + this._codeBlockEditor.save(this._codeBlockElement); + this.hide(); + } + + /** + * load code mirror text from wysiwyg code block + * @param {HTMLElement} codeBlockElement - code block element instance to load code from + * @private + * @memberof PopupCodeBlockEditor + */ + + }, { + key: '_load', + value: function _load(codeBlockElement) { + this._codeBlockElement = codeBlockElement; + this._codeBlockEditor.load(codeBlockElement); + this._codeBlockLanguagesCombo.setLanguage(this._codeBlockEditor.getLanguage()); + this._focusEditor(); + this._codeBlockPreview.refresh(); + } + + /** + * show popup + * @param {HTMLElement} codeBlockElement - code block element + * @memberof PopupCodeBlockEditor + * @override + */ + + }, { + key: 'show', + value: function show(codeBlockElement) { + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), 'show', this).call(this); + + if (!codeBlockElement) { + throw new Error('should be called with codeBlockElement'); + } + this._load(codeBlockElement); + } + + /** + * hide popup + * @memberof PopupCodeBlockEditor + * @override + */ + + }, { + key: 'hide', + value: function hide() { + this.setFitToWindow(false); + + if (this._codeBlockEditor) { + this._codeBlockEditor.clear(); + } + if (this._codeBlockPreview) { + this._codeBlockPreview.clear(); + } + this._codeBlockElement = null; + + _get(PopupCodeBlockEditor.prototype.__proto__ || Object.getPrototypeOf(PopupCodeBlockEditor.prototype), 'hide', this).call(this); + } + }]); + + return PopupCodeBlockEditor; +}(_layerpopup2.default); + +exports.default = PopupCodeBlockEditor; + +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements scroll sync split + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CLASS_SPLIT_SCROLL = 'tui-split-scroll'; +var CLASS_SINGLE_CONTENT = 'single-content'; +var CLASS_SCROLL_SYNC = 'scroll-sync'; +var CLASS_SCROLL_WRAPPER = 'tui-split-scroll-wrapper'; +var CLASS_SCROLL_CONTENT = 'tui-split-scroll-content'; +var CLASS_SPLITTER = 'tui-splitter'; +var EVENT_REQUIRE_SCROLL_SYNC = 'requireScrollSync'; +var EVENT_REQUIRE_SCROLL_INTO_VIEW = 'requireScrollIntoView'; +var CLASS_CONTENT_LEFT = 'tui-split-content-left'; +var CLASS_CONTENT_RIGHT = 'tui-split-content-right'; +var CLASS_CONTENT = { + 'left': CLASS_CONTENT_LEFT, + 'right': CLASS_CONTENT_RIGHT +}; + +/** + * Class ScrollSyncSplit + */ + +var ScrollSyncSplit = function () { + /** + * Creates an instance of ScrollSyncSplit. + * @param {Element} baseElement - an element which attach a splitSyncSplit + * @param {Element} leftElement - an element to be on left side split view + * @param {Element} rightElement - an element to be on right side split view + * @param {object} options - options + * @param {boolean} [options.showScrollSyncButton=false] - show scroll sync button on top right corner + * @param {boolean} [options.scrollSync=true] - true for enable scroll sync + * @param {boolean} [options.splitView=true] - true for split, false for single view + * @memberof ScrollSyncSplit + */ + function ScrollSyncSplit(baseElement, leftElement, rightElement) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + _classCallCheck(this, ScrollSyncSplit); + + options = _tuiCodeSnippet2.default.extend({ + showScrollSyncButton: false, + scrollSync: true, + splitView: true + }, options); + this._baseElement = baseElement; + + /** + * left, right side content elements + */ + this._contentElements = []; + + this._initDom(leftElement, rightElement, options); + this._initDomEvent(); + } + + _createClass(ScrollSyncSplit, [{ + key: '_initDom', + value: function _initDom(leftElement, rightElement, options) { + var el = document.createElement('div'); + el.className = CLASS_SPLIT_SCROLL; + this._el = el; + + var scrollWrapper = document.createElement('div'); + scrollWrapper.className = CLASS_SCROLL_WRAPPER; + this._scrollWrapper = scrollWrapper; + this._setScrollSync(options.scrollSync); + this.setSplitView(options.splitView); + + var contentWrapper = document.createElement('div'); + contentWrapper.className = CLASS_SCROLL_CONTENT; + this._contentWrapper = contentWrapper; + + var splitter = document.createElement('div'); + splitter.className = CLASS_SPLITTER; + + this._baseElement.appendChild(el); + el.appendChild(scrollWrapper); + scrollWrapper.appendChild(contentWrapper); + scrollWrapper.appendChild(splitter); + this._setLeft(leftElement); + this._setRight(rightElement); + } + }, { + key: '_initDomEvent', + value: function _initDomEvent() { + this._contentWrapper.addEventListener('scroll', this.sync.bind(this)); + } + }, { + key: '_requireScrollIntoView', + value: function _requireScrollIntoView(event) { + var element = event.target; + + var _element$getBoundingC = element.getBoundingClientRect(), + targetTop = _element$getBoundingC.top, + targetBottom = _element$getBoundingC.bottom; + + var wrapperTop = void 0, + wrapperBottom = void 0, + wrapperElement = void 0; + + if (this.isScrollSynced()) { + wrapperElement = this._contentWrapper; + } else if ((0, _jquery2.default)(element).parents(this._contentElements.left).length) { + wrapperElement = this._contentElements.left; + } else if ((0, _jquery2.default)(element).parents(this._contentElements.right).length) { + wrapperElement = this._contentElements.right; + } else { + return; + } + + var _wrapperElement$getBo = wrapperElement.getBoundingClientRect(); + + wrapperTop = _wrapperElement$getBo.top; + wrapperBottom = _wrapperElement$getBo.bottom; + + + if (targetTop < wrapperTop) { + wrapperElement.scrollTop = wrapperElement.scrollTop + targetTop - wrapperTop; + } else if (targetBottom > wrapperBottom) { + wrapperElement.scrollTop = wrapperElement.scrollTop + targetBottom - wrapperBottom; + } + + this.sync(); + } + + /** + * set content element for given side + * @param {Element} element - content element + * @param {string} side - 'left' | 'right' + * @memberof ScrollSyncSplit + * @private + */ + + }, { + key: '_setContentElement', + value: function _setContentElement(element, side) { + var _this = this; + + var contentElement = this._contentElements[side]; + + if (contentElement) { + (0, _jquery2.default)(contentElement).off(EVENT_REQUIRE_SCROLL_INTO_VIEW); + this._contentWrapper.removeChild(contentElement); + } + (0, _jquery2.default)(element).addClass(CLASS_CONTENT[side]); + this._contentWrapper.appendChild(element); + (0, _jquery2.default)(element).on(EVENT_REQUIRE_SCROLL_INTO_VIEW, function (ev) { + return _this._requireScrollIntoView(ev); + }); + (0, _jquery2.default)(element).on(EVENT_REQUIRE_SCROLL_SYNC, function () { + return _this.sync(); + }); + + this._contentElements[side] = element; + + this.sync(); + } + + /** + * set left side element + * @param {Element} element - an element to be on left side split view + * @memberof ScrollSyncSplit + * @private + */ + + }, { + key: '_setLeft', + value: function _setLeft(element) { + this._setContentElement(element, 'left'); + } + + /** + * set right side element + * @param {Element} element - an element to be on right side split view + * @memberof ScrollSyncSplit + * @private + */ + + }, { + key: '_setRight', + value: function _setRight(element) { + this._setContentElement(element, 'right'); + } + }, { + key: '_setScrollSync', + value: function _setScrollSync(activate) { + (0, _jquery2.default)(this._el).toggleClass(CLASS_SCROLL_SYNC, activate); + } + + /** + * toggle multi scroll + * @memberof ScrollSyncSplit + */ + + }, { + key: 'toggleScrollSync', + value: function toggleScrollSync() { + (0, _jquery2.default)(this._el).toggleClass(CLASS_SCROLL_SYNC); + } + }, { + key: 'setSplitView', + value: function setSplitView(activate) { + (0, _jquery2.default)(this._el).toggleClass(CLASS_SINGLE_CONTENT, !activate); + } + + /** + * toggle split + * @memberof ScrollSyncSplit + */ + + }, { + key: 'toggleSplitView', + value: function toggleSplitView() { + (0, _jquery2.default)(this._el).toggleClass(CLASS_SINGLE_CONTENT); + } + + /** + * is scroll synced + * @returns {boolean} - true for synced, false for each scroll + * @memberof ScrollSyncSplit + */ + + }, { + key: 'isScrollSynced', + value: function isScrollSynced() { + return (0, _jquery2.default)(this._el).hasClass(CLASS_SCROLL_SYNC); + } + + /** + * is split view + * @returns {boolean} - true for split view, false for single view + * @memberof ScrollSyncSplit + */ + + }, { + key: 'isSplitView', + value: function isSplitView() { + return !(0, _jquery2.default)(this._el).hasClass(CLASS_SINGLE_CONTENT); + } + + /** + * sync scroll + * @memberof ScrollSyncSplit + */ + + }, { + key: 'sync', + value: function sync() { + if (!this._contentElements.left || !this._contentElements.right) { + return; + } + + var wrapperHeight = this._contentWrapper.clientHeight; + var scrollTop = this._contentWrapper.scrollTop; + + var leftElement = this._contentElements.left; + var rightElement = this._contentElements.right; + + var scrollingElement = leftElement.offsetHeight - wrapperHeight > 0 ? leftElement : rightElement; + var followingElement = scrollingElement === leftElement ? rightElement : leftElement; + + var scrollingElementHeight = scrollingElement.offsetHeight; + var scrollingElementScrollMax = Math.max(scrollingElementHeight - wrapperHeight, 0); + var followingElementHeight = Math.max(followingElement.offsetHeight, wrapperHeight); + var followingElementTopMax = scrollingElementHeight - followingElementHeight; + + scrollingElement.style.top = '0px'; + followingElement.style.top = scrollTop / scrollingElementScrollMax * followingElementTopMax + 'px'; + } + + /** + * scroll top + * @param {number} top - scroll top in pixel + * @memberof ScrollSyncSplit + */ + + }, { + key: 'scrollTop', + value: function scrollTop(top) { + this._contentWrapper.scrollTop = top; + } + }]); + + return ScrollSyncSplit; +}(); + +exports.default = ScrollSyncSplit; + +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _codeMirrorExt = __webpack_require__(30); + +var _codeMirrorExt2 = _interopRequireDefault(_codeMirrorExt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements code block editor + * @author NHN Ent. FE Development Lab + */ + + +var EVENT_LANGUAGE_CHANGED = 'language-changed'; + +/** + * Class Code Block Editor + * @extends {CodeMirrorExt} + */ + +var CodeBlockEditor = function (_CodeMirrorExt) { + _inherits(CodeBlockEditor, _CodeMirrorExt); + + /** + * Creates an instance of CodeBlockEditor. + * @param {HTMLElement} el - code block editor container element + * @param {EventManager} eventManager - event manager + * @memberof CodeBlockEditor + */ + function CodeBlockEditor(el, eventManager) { + _classCallCheck(this, CodeBlockEditor); + + var _this = _possibleConstructorReturn(this, (CodeBlockEditor.__proto__ || Object.getPrototypeOf(CodeBlockEditor)).call(this, el, { + singleCursorHeightPerLine: false, + theme: 'none' + })); + + _this._language = ''; + _this._eventManager = eventManager; + + _this._initEvent(); + return _this; + } + + _createClass(CodeBlockEditor, [{ + key: '_initEvent', + value: function _initEvent() { + var _this2 = this; + + this.on('cursorActivity', this._onRequireScrollIntoView.bind(this)); + this.on('beforeChange', function (cm, ev) { + if (ev.origin === 'paste') { + _this2._eventManager.emit('pasteBefore', { + source: 'codeblock', + data: ev + }); + } + }); + } + }, { + key: '_onRequireScrollIntoView', + value: function _onRequireScrollIntoView() { + var cursor = this.getCursor(); + var wrapper = this.getWrapperElement(); + + // CodeMirror cursorActivity event fires before actually attach a new line element to DOM + // we should proceed at next tick + setTimeout(function () { + var lineElement = wrapper.querySelector('pre:nth-child(' + (cursor.line + 1) + ')'); + (0, _jquery2.default)(lineElement).trigger('requireScrollIntoView'); + }, 0); + } + + /** + * load code from code block element + * @param {HTMLElement} codeBlockElement - code block element + * @memberof CodeBlockEditor + */ + + }, { + key: 'load', + value: function load(codeBlockElement) { + var el = codeBlockElement.cloneNode(true); + this.setLanguage(el.getAttribute('data-language') || ''); + this.setEditorCodeText(el.textContent); + } + + /** + * save code to code block element + * @param {HTMLElement} codeBlockElement - code block element + * @memberof CodeBlockEditor + */ + + }, { + key: 'save', + value: function save(codeBlockElement) { + codeBlockElement.innerHTML = ''; + codeBlockElement.textContent = this.getEditorCodeText(); + codeBlockElement.setAttribute('data-language', this._language); + (0, _jquery2.default)(codeBlockElement).trigger(EVENT_LANGUAGE_CHANGED); + } + + /** + * clear code and language + * @memberof CodeBlockEditor + */ + + }, { + key: 'clear', + value: function clear() { + this.setLanguage(''); + this.setEditorCodeText(''); + } + + /** + * get code language + * @returns {string} - code language + * @memberof CodeBlockEditor + */ + + }, { + key: 'getLanguage', + value: function getLanguage() { + return this._language; + } + + /** + * set code language + * @param {string} [language=''] - code language + * @memberof CodeBlockEditor + */ + + }, { + key: 'setLanguage', + value: function setLanguage() { + var language = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + + this._language = language; + } + + /** + * get code text + * @returns {string} - code text + * @memberof CodeBlockEditor + */ + + }, { + key: 'getEditorCodeText', + value: function getEditorCodeText() { + return this.getValue(); + } + + /** + * set code text + * @param {string} [code=''] - code text + * @memberof CodeBlockEditor + */ + + }, { + key: 'setEditorCodeText', + value: function setEditorCodeText() { + var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + + this.setValue(code); + } + + /** + * refresh. call if codemirror resized + * @memberof CodeBlockEditor + */ + + }, { + key: 'refresh', + value: function refresh() { + this.cm.refresh(); + } + }]); + + return CodeBlockEditor; +}(_codeMirrorExt2.default); + +exports.default = CodeBlockEditor; + +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _preview = __webpack_require__(33); + +var _preview2 = _interopRequireDefault(_preview); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @fileoverview Implements CodeBlockPreview + * @author NHN Ent. FE Development Lab + */ + + +var EVENT_REQUIRE_SCROLL_SYNC = 'requireScrollSync'; + +/** + * Class Code block preview + * @extends {Preview} + */ + +var CodeBlockPreview = function (_Preview) { + _inherits(CodeBlockPreview, _Preview); + + /** + * Creates an instance of CodeBlockPreview. + * @param {jQuery} $el - base element + * @param {EventManager} eventManager - event manager + * @param {Convertor} convertor - convertor + * @param {CodeBlockEditor} codeBlockEditor - code block editor + * @memberof CodeBlockPreview + */ + function CodeBlockPreview($el, eventManager, convertor, codeBlockEditor) { + _classCallCheck(this, CodeBlockPreview); + + var _this = _possibleConstructorReturn(this, (CodeBlockPreview.__proto__ || Object.getPrototypeOf(CodeBlockPreview)).call(this, $el, eventManager, convertor, true)); + + _this._codeBlockEditor = codeBlockEditor; + + _this._initEvent(); + return _this; + } + + _createClass(CodeBlockPreview, [{ + key: '_initEvent', + value: function _initEvent() { + var _this2 = this; + + this._codeBlockEditor.on('update', function () { + return _this2.lazyRunner.run('refresh'); + }); + } + + /** + * refresh preview + * @memberof CodeBlockPreview + * @override + */ + + }, { + key: 'refresh', + value: function refresh() { + var language = this._codeBlockEditor.getLanguage(); + var codeText = this._codeBlockEditor.getEditorCodeText(); + + _get(CodeBlockPreview.prototype.__proto__ || Object.getPrototypeOf(CodeBlockPreview.prototype), 'refresh', this).call(this, '```' + language + '\n' + codeText + '\n```'); + this.$el.trigger(EVENT_REQUIRE_SCROLL_SYNC); + } + + /** + * clear preview + * @memberof CodeBlockPreview + */ + + }, { + key: 'clear', + value: function clear() { + _get(CodeBlockPreview.prototype.__proto__ || Object.getPrototypeOf(CodeBlockPreview.prototype), 'render', this).call(this, ''); + } + }]); + + return CodeBlockPreview; +}(_preview2.default); + +exports.default = CodeBlockPreview; + +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * @fileoverview Implements UI code block languages combo + * @author NHN Ent. FE Development Lab + */ + + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +var _keyMapper = __webpack_require__(22); + +var _keyMapper2 = _interopRequireDefault(_keyMapper); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class CodeBlockLanguagesCombo + */ +var CodeBlockLanguagesCombo = function () { + /** + * Creates an instance of CodeBlockLanguagesCombo. + * @param {EventManager} eventManager - event manager instance + * @memberof CodeBlockLanguagesCombo + */ + function CodeBlockLanguagesCombo(eventManager) { + _classCallCheck(this, CodeBlockLanguagesCombo); + + this._eventManager = eventManager; + + this._initDOM(); + this._initDOMEvent(); + } + + _createClass(CodeBlockLanguagesCombo, [{ + key: '_initDOM', + value: function _initDOM() { + this._inputLanguage = (0, _jquery2.default)('').get(0); + this._wrapper = (0, _jquery2.default)('').get(0); + this._wrapper.appendChild(this._inputLanguage); + } + }, { + key: '_initDOMEvent', + value: function _initDOMEvent() { + var _this = this; + + this._inputLanguage.addEventListener('keydown', function (event) { + return _this._onKeyEvent(event); + }); + this._inputLanguage.addEventListener('focus', function () { + return _this._showPopupCodeBlockLanguages(); + }); + this._inputLanguage.addEventListener('focusout', function () { + return _this._onFocusOut(); + }); + this._wrapper.addEventListener('mousedown', function (ev) { + if (ev.target !== _this._wrapper) { + return; + } + ev.preventDefault(); + _this._toggleFocus(); + }); + } + + /** + * show popup + * @private + * @memberof CodeBlockGadget + */ + + }, { + key: '_showPopupCodeBlockLanguages', + value: function _showPopupCodeBlockLanguages() { + var _this2 = this; + + var clientRect = this._inputLanguage.getBoundingClientRect(); + (0, _jquery2.default)(this._wrapper).toggleClass('active', true); + this.active = true; + + this._popupCodeBlockLanguages = this._eventManager.emitReduce('openPopupCodeBlockLanguages', { + language: this._prevStoredLanguage, + offset: { + left: clientRect.left, + top: clientRect.bottom + }, + callback: { + selected: function selected(selectedLanguage) { + return _this2._onLanguageSelectedFromList(selectedLanguage); + }, + dismissed: function dismissed() { + _this2._popupCodeBlockLanguages = null; + } + } + }); + } + }, { + key: '_toggleFocus', + value: function _toggleFocus() { + var inputLanguage = this._inputLanguage; + if ((0, _jquery2.default)(this._wrapper).hasClass('active')) { + inputLanguage.blur(); + } else { + inputLanguage.focus(); + } + } + }, { + key: '_onFocusOut', + value: function _onFocusOut() { + (0, _jquery2.default)(this._wrapper).toggleClass('active', false); + this._inputLanguage.value = this._prevStoredLanguage; + this._hidePopupCodeBlockLanguages(); + } + }, { + key: '_onKeyEvent', + value: function _onKeyEvent(event) { + if (this._popupCodeBlockLanguages) { + switch (event.which) { + case _keyMapper2.default.keyCode('UP'): + this._popupCodeBlockLanguages.prev(); + event.preventDefault(); + break; + case _keyMapper2.default.keyCode('DOWN'): + this._popupCodeBlockLanguages.next(); + event.preventDefault(); + break; + case _keyMapper2.default.keyCode('ENTER'): + case _keyMapper2.default.keyCode('TAB'): + { + var language = this._popupCodeBlockLanguages.getCurrentLanguage(); + this._inputLanguage.value = language; + this._storeInputLanguage(); + event.preventDefault(); + break; + } + default: + this._popupCodeBlockLanguages.hide(); + } + } else if (event.which === _keyMapper2.default.keyCode('ENTER') || event.which === _keyMapper2.default.keyCode('TAB')) { + this._storeInputLanguage(); + event.preventDefault(); + } + } + }, { + key: '_onLanguageSelectedFromList', + value: function _onLanguageSelectedFromList(selectedLanguage) { + this._inputLanguage.value = selectedLanguage; + this._storeInputLanguage(); + } + + /** + * set a callback to be called on language selected + * @param {function} callback - callback function + * @memberof CodeBlockLanguagesCombo + */ + + }, { + key: 'setOnLanguageSelected', + value: function setOnLanguageSelected(callback) { + this._onLanguageSelected = callback; + } + + /** + * hide popup + * @private + * @memberof CodeBlockGadget + */ + + }, { + key: '_hidePopupCodeBlockLanguages', + value: function _hidePopupCodeBlockLanguages() { + this._eventManager.emit('closePopupCodeBlockLanguages'); + } + + /** + * set language + * @param {string} language - code block language + * @memberof CodeBlockLanguagesCombo + */ + + }, { + key: 'setLanguage', + value: function setLanguage(language) { + this._prevStoredLanguage = language; + this._inputLanguage.value = language; + } + + /** + * store selection(typed) language & hide popup + * @private + * @memberof CodeBlockGadget + */ + + }, { + key: '_storeInputLanguage', + value: function _storeInputLanguage() { + var selectedLanguage = this._inputLanguage.value; + + this.setLanguage(selectedLanguage); + if (this._onLanguageSelected) { + this._onLanguageSelected(selectedLanguage); + } + + this._hidePopupCodeBlockLanguages(); + } + + /** + * get element body + * @returns {HTMLElement} - CodeBlockLanguagesCombo body element + * @memberof CodeBlockLanguagesCombo + */ + + }, { + key: 'getElement', + value: function getElement() { + return this._wrapper; + } + }]); + + return CodeBlockLanguagesCombo; +}(); + +exports.default = CodeBlockLanguagesCombo; + +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var boldRangeRegex = /^[*_]{2,}[^*_]+[*_]{2,}$/; /** + * @fileoverview Implements Bold markdown command + * @author NHN Ent. FE Development Lab + */ + +var boldContentRegex = /[*_]{2,}([^*_]+)[*_]{2,}/g; + +/** + * Bold + * Add bold markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Bold + * @ignore + */ +var Bold = _commandManager2.default.command('markdown', /** @lends Bold */{ + name: 'Bold', + keyMap: ['CTRL+B', 'META+B'], + /** + * Command Handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var cursor = doc.getCursor(); + var selection = doc.getSelection(); + var isEmpty = !selection; + + // if selection is empty, expend selection to detect a syntax + if (isEmpty && cursor.ch > 1) { + var tmpSelection = this.expendSelection(doc, cursor); + selection = tmpSelection || selection; + } + + var isRemoved = this.isNeedRemove(selection); + var result = void 0; + if (isRemoved) { + result = this.remove(selection); + result = this._removeBoldSyntax(result); + } else { + result = this._removeBoldSyntax(selection); + result = this.append(result); + } + + doc.replaceSelection(result, 'around'); + + if (isEmpty && !isRemoved) { + this.setCursorToCenter(doc, cursor); + } + + cm.focus(); + }, + + + /** + * test it has bold + * @param {string} text - text selected + * @returns {boolean} - true if it has bold + */ + isNeedRemove: function isNeedRemove(text) { + return boldRangeRegex.test(text); + }, + + + /** + * apply bold + * @param {string} text - text selected + * @returns {string} - bold text + */ + append: function append(text) { + return '**' + text + '**'; + }, + + + /** + * remove bold + * @param {string} text - text selected + * @returns {string} - un-bold text + */ + remove: function remove(text) { + return text.substr(2, text.length - 4); + }, + + + /** + * expand selection + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @returns {string} - text selected + */ + expendSelection: function expendSelection(doc, cursor) { + var tmpSelection = doc.getSelection(); + var result = void 0; + var start = { + line: cursor.line, + ch: cursor.ch - 2 + }; + var end = { + line: cursor.line, + ch: cursor.ch + 2 + }; + + doc.setSelection(start, end); + + if (tmpSelection === '****' || tmpSelection === '____') { + result = tmpSelection; + } else { + doc.setSelection(cursor); + } + + return result; + }, + + + /** + * move cursor to center + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + */ + setCursorToCenter: function setCursorToCenter(doc, cursor) { + doc.setCursor(cursor.line, cursor.ch + 2); + }, + + + /** + * remove bold syntax in the middle of given text + * @param {string} text - text selected + * @returns {string} - text eliminated all bold in the middle of it's content + * @private + */ + _removeBoldSyntax: function _removeBoldSyntax(text) { + return text ? text.replace(boldContentRegex, '$1') : ''; + } +}); + +exports.default = Bold; + +/***/ }), +/* 111 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var boldItalicRangeRegex = /^[*_]{3,}[^*_]+[*_]{3,}$/; /** + * @fileoverview Implements Italic markdown command + * @author NHN Ent. FE Development Lab + */ + +var italicRangeRegex = /^[*_][^*_]+[*_]$/; +var italicContentRegex = /[*_]([^*_]+)[*_]/g; + +/** + * Italic + * Add italic markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Italic + * @ignore + */ +var Italic = _commandManager2.default.command('markdown', /** @lends Italic */{ + name: 'Italic', + keyMap: ['CTRL+I', 'META+I'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var cursor = doc.getCursor(); + var selection = doc.getSelection(); + var isEmpty = !selection; + var isWithBold = false; + var tmpSelection = void 0; + + // if selection is empty, expend selection to detect a syntax + if (isEmpty) { + if (cursor.ch > 2) { + tmpSelection = this.expendWithBoldSelection(doc, cursor); + + if (tmpSelection) { + isWithBold = 'with'; + } + } + + if (isWithBold !== 'with' && cursor.ch > 1) { + isWithBold = this.expendOnlyBoldSelection(doc, cursor); + } + + if (!isWithBold && cursor.ch > 0) { + this.expendSelection(doc, cursor); + selection = tmpSelection || selection; + } + } + + var isRemoved = this.isNeedRemove(selection); + var result = void 0; + if (isRemoved) { + result = this.remove(selection); + result = this._removeItalicSyntax(result); + } else { + result = this._removeItalicSyntax(selection); + result = this.append(result); + } + + doc.replaceSelection(result, 'around'); + + if (isEmpty) { + this.setCursorToCenter(doc, cursor, isRemoved); + } + + cm.focus(); + }, + + + /** + * isNeedRemove + * test given text has italic or bold + * @param {string} text - text to test + * @returns {boolean} - true if it has italic or bold + */ + isNeedRemove: function isNeedRemove(text) { + return italicRangeRegex.test(text) || boldItalicRangeRegex.test(text); + }, + + + /** + * apply italic + * @param {string} text - text to apply + * @returns {string} - italic text + */ + append: function append(text) { + return '_' + text + '_'; + }, + + + /** + * remove italic + * @param {string} text - text to remove italic syntax + * @returns {string} - italic syntax revmoed text + */ + remove: function remove(text) { + return text.substr(1, text.length - 2); + }, + + + /** + * expand selected area + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @returns {string} - text in range after it has been expaneded + */ + expendWithBoldSelection: function expendWithBoldSelection(doc, cursor) { + var tmpSelection = doc.getSelection(); + var result = void 0; + var start = { + line: cursor.line, + ch: cursor.ch - 3 + }; + var end = { + line: cursor.line, + ch: cursor.ch + 3 + }; + + doc.setSelection(start, end); + + if (tmpSelection === '******' || tmpSelection === '______') { + result = tmpSelection; + } else { + doc.setSelection(cursor); + } + + return result; + }, + + + /** + * expand only bold selection + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @returns {string} - text in area after it has been expaneded + */ + expendOnlyBoldSelection: function expendOnlyBoldSelection(doc, cursor) { + var tmpSelection = doc.getSelection(); + var result = false; + var start = { + line: cursor.line, + ch: cursor.ch - 2 + }; + var end = { + line: cursor.line, + ch: cursor.ch + 2 + }; + + doc.setSelection(start, end); + + if (tmpSelection === '****' || tmpSelection === '____') { + doc.setSelection(cursor); + result = 'only'; + } + + return result; + }, + + + /** + * expand only italic selection + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @returns {string} - text in area after it has been expaneded + */ + expendSelection: function expendSelection(doc, cursor) { + var tmpSelection = doc.getSelection(); + var result = void 0; + var start = { + line: cursor.line, + ch: cursor.ch - 2 + }; + var end = { + line: cursor.line, + ch: cursor.ch + 2 + }; + + doc.setSelection(start, end); + + if (tmpSelection === '****' || tmpSelection === '____') { + result = tmpSelection; + } else { + doc.setSelection(cursor); + } + + return result; + }, + + /** + * move cursor to center + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @param {boolean} isRemoved - whether it involes deletion + */ + setCursorToCenter: function setCursorToCenter(doc, cursor, isRemoved) { + var pos = isRemoved ? -1 : 1; + doc.setCursor(cursor.line, cursor.ch + pos); + }, + + + /** + * remove italic syntax in the middle of given text + * @param {string} text - text selected + * @returns {string} - text eliminated all italic in the middle of it's content + * @private + */ + _removeItalicSyntax: function _removeItalicSyntax(text) { + return text ? text.replace(italicContentRegex, '$1') : ''; + } +}); + +exports.default = Italic; + +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var strikeRangeRegex = /^~~[^~]+~~$/; /** + * @fileoverview Implements StrikeThrough markdown command + * @author NHN Ent. FE Development Lab + */ + +var strikeContentRegex = /~~([^~]+)~~/g; + +/** + * Strike + * Add strike markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Strike + * @ignore + */ +var Strike = _commandManager2.default.command('markdown', /** @lends Strike */{ + name: 'Strike', + keyMap: ['CTRL+S', 'META+S'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var cursor = doc.getCursor(); + var selection = doc.getSelection(); + var isNeedToRemove = this.hasStrikeSyntax(selection); + + var result = void 0; + + if (isNeedToRemove) { + result = this.remove(selection); + result = this._removeStrikeSyntax(result); + } else { + result = this._removeStrikeSyntax(selection); + result = this.append(result); + } + + doc.replaceSelection(result, 'around'); + + if (!selection && !isNeedToRemove) { + this.setCursorToCenter(doc, cursor, isNeedToRemove); + } + + cm.focus(); + }, + + + /** + * hasStrikeSyntax + * @param {string} text Source text + * @returns {boolean} Boolean value of strike syntax removal + */ + hasStrikeSyntax: function hasStrikeSyntax(text) { + return strikeRangeRegex.test(text); + }, + + + /** + * append strike + * @param {string} text - text to apply + * @returns {string} - strike through text + */ + append: function append(text) { + return '~~' + text + '~~'; + }, + + + /** + * remove strike + * @param {string} text - text to remove + * @returns {string} - strike removed text + */ + remove: function remove(text) { + return text.substr(2, text.length - 4); + }, + + + /** + * set cursor to center + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @param {boolean} isRemoved - whether it involes deletion + */ + setCursorToCenter: function setCursorToCenter(doc, cursor, isRemoved) { + var pos = isRemoved ? -2 : 2; + doc.setCursor(cursor.line, cursor.ch + pos); + }, + + + /** + * remove strike syntax in the middle of given text + * @param {string} text - text selected + * @returns {string} - text eliminated all strike in the middle of it's content + * @private + */ + _removeStrikeSyntax: function _removeStrikeSyntax(text) { + return text ? text.replace(strikeContentRegex, '$1') : ''; + } +}); + +exports.default = Strike; + +/***/ }), +/* 113 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var BlockquoteRegex = /^> ?/; + +/** + * Blockquote + * Add blockquote markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Blockquote + * @ignore + */ +/** +* @fileoverview Implements Blockquote markdown command +* @author NHN Ent. FE Development Lab +*/ +var Blockquote = _commandManager2.default.command('markdown', /** @lends Blockquote */{ + name: 'Blockquote', + keyMap: ['ALT+Q', 'ALT+Q'], + /** + * command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var range = mde.getCurrentRange(); + + var from = { + line: range.from.line, + ch: 0 + }; + + var to = { + line: range.to.line, + ch: doc.getLineHandle(range.to.line).text.length + }; + + var textToModify = doc.getRange(from, to); + var textLinesToModify = textToModify.split('\n'); + var isNeedToRemove = this._haveBlockquote(textLinesToModify); + var resultText = void 0; + + if (isNeedToRemove) { + resultText = this._removeBlockquote(textLinesToModify); + } else { + resultText = this._addBlockquote(textLinesToModify); + } + + doc.replaceRange(resultText.join('\n'), from, to); + + if (isNeedToRemove) { + var length = textLinesToModify.length; + if (this._isBlockquoteWithSpace(textLinesToModify[length - 1])) { + range.to.ch -= 2; + } else { + range.to.ch -= 1; + } + } else { + range.to.ch += 2; + } + + doc.setCursor(range.to); + + cm.focus(); + }, + + + /** + * check all text in textArr starts with '>' + * @param {Array} textArr - text array + * @returns {boolean} - true if all text in textArr starts with '>' + * @private + */ + _haveBlockquote: function _haveBlockquote(textArr) { + for (var i = 0; i < textArr.length; i += 1) { + if (!BlockquoteRegex.test(textArr[i])) { + return false; + } + } + + return true; + }, + + + /** + * add '> ' to all text in textArr + * @param {Array} textArr - text array + * @returns {Array} - new text array added '> ' + * @private + */ + _addBlockquote: function _addBlockquote(textArr) { + return textArr.map(function (text) { + return '> ' + text; + }); + }, + + + /** + * remove '> ' or '>' to all text in textArr + * @param {Array} textArr - text array + * @returns {Array} - new text array removed '> ' or '>' + * @private + */ + _removeBlockquote: function _removeBlockquote(textArr) { + return textArr.map(function (text) { + return text.replace(BlockquoteRegex, ''); + }); + }, + + + /** + * check text start '> ' + * @param {string} text - text + * @returns {boolean} - if text start '> ', true + * @private + */ + _isBlockquoteWithSpace: function _isBlockquoteWithSpace(text) { + return (/^> /.test(text) + ); + } +}); + +exports.default = Blockquote; + +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview Implements Heading markdown command + * @author NHN Ent. FE Development Lab + */ +var FIND_HEADING_RX = /^#+\s/g; + +/** + * Heading + * Add heading markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Heading + * @ignore + */ +var Heading = _commandManager2.default.command('markdown', /** @lends Heading */{ + name: 'Heading', + /** + * Command Handler + * @param {MarkdownEditor} mde MarkdownEditor instance + * @param {number} size heading size + */ + exec: function exec(mde, size) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var range = mde.getCurrentRange(); + + var from = { + line: range.from.line, + ch: 0 + }; + + var to = { + line: range.to.line, + ch: doc.getLineHandle(range.to.line).text.length + }; + + var lengthOfCurrentLineBefore = doc.getLine(to.line).length; + var textToModify = doc.getRange(from, to); + var textLinesToModify = textToModify.split('\n'); + + _tuiCodeSnippet2.default.forEachArray(textLinesToModify, function (line, index) { + textLinesToModify[index] = getHeadingMarkdown(line, size); + }); + + doc.replaceRange(textLinesToModify.join('\n'), from, to); + + range.to.ch += doc.getLine(to.line).length - lengthOfCurrentLineBefore; + + doc.setSelection(from, range.to); + + cm.focus(); + } +}); + +/** + * Get heading markdown + * @param {string} text Source test + * @param {number} size size + * @returns {string} + */ +function getHeadingMarkdown(text, size) { + var foundedHeading = text.match(FIND_HEADING_RX); + var heading = ''; + + do { + heading += '#'; + size -= 1; + } while (size > 0); + + if (foundedHeading) { + var _text$split = text.split(foundedHeading[0]); + + text = _text$split[1]; + } + + return heading + ' ' + text; +} + +exports.default = Heading; + +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Paragraph + * Convert selected lines to paragraph + * @extends Command + * @module markdownCommands/Paragraph + * @ignore + */ +/** + * @fileoverview Implements Paragraph markdown command + * @author NHN Ent. FE Development Lab + */ +var Paragraph = _commandManager2.default.command('markdown', /** @lends Paragraph */{ + name: 'Paragraph', + /** + * Command Handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var range = mde.getCurrentRange(); + var from = { + line: range.from.line, + ch: 0 + }; + var to = { + line: range.to.line, + ch: doc.getLineHandle(range.to.line).text.length + }; + + var lengthOfCurrentLineBefore = doc.getLine(to.line).length; + var textToModify = doc.getRange(from, to); + var textLines = textToModify.split('\n'); + + _tuiCodeSnippet2.default.forEachArray(textLines, function (line, index) { + textLines[index] = getParagraphMarkdown(line); + }); + + doc.replaceRange(textLines.join('\n'), from, to); + + range.to.ch += doc.getLine(to.line).length - lengthOfCurrentLineBefore; + + doc.setSelection(from, to); + + cm.focus(); + } +}); +/** + * Get paragraph markdown lineText + * @param {string} lineText line lineText + * @returns {string} + */ +function getParagraphMarkdown(lineText) { + var headingRx = /^(#{1,6}| *((?:\*|-|\d\.)(?: \[[ xX]])?)) /; + + return lineText.replace(headingRx, ''); +} + +exports.default = Paragraph; + +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * HR + * Add HR markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/HR + * @ignore + */ +var HR = _commandManager2.default.command('markdown', /** @lends HR */{ + name: 'HR', + keyMap: ['CTRL+L', 'META+L'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var replaceText = ''; + + var range = mde.getCurrentRange(); + + var from = { + line: range.from.line, + ch: range.from.ch + }; + + var to = { + line: range.to.line, + ch: range.to.ch + }; + + if (range.collapsed) { + replaceText = doc.getLine(from.line); + from.ch = 0; + to.ch = doc.getLineHandle(range.to.line).text.length; + } + + if (doc.getLine(from.line).length) { + replaceText += '\n\n* * *\n\n'; + } else { + replaceText += '\n* * *\n'; + } + + doc.replaceRange(replaceText, from, to); + + cm.focus(); + } +}); /** + * @fileoverview Implements HR markdown command + * @author NHN Ent. FE Development Lab + */ + +exports.default = HR; + +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _importManager = __webpack_require__(15); + +var _importManager2 = _interopRequireDefault(_importManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** +* @fileoverview Implements Addlink markdown command +* @author NHN Ent. FE Development Lab +*/ +var decodeURIGraceful = _importManager2.default.decodeURIGraceful, + encodeMarkdownCharacters = _importManager2.default.encodeMarkdownCharacters, + escapeMarkdownCharacters = _importManager2.default.escapeMarkdownCharacters; + +/** + * AddLink + * Add link markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/AddLink + * @ignore + */ + +var AddLink = _commandManager2.default.command('markdown', /** @lends AddLink */{ + name: 'AddLink', + /** + * command handler for AddLink + * @param {MarkdownEditor} mde - MarkdownEditor instance + * @param {object} data - data for image + */ + exec: function exec(mde, data) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var range = mde.getCurrentRange(); + + var from = { + line: range.from.line, + ch: range.from.ch + }; + + var to = { + line: range.to.line, + ch: range.to.ch + }; + + var linkText = data.linkText, + url = data.url; + + linkText = decodeURIGraceful(linkText); + linkText = escapeMarkdownCharacters(linkText); + url = encodeMarkdownCharacters(url); + + var replaceText = '[' + linkText + '](' + url + ')'; + + doc.replaceRange(replaceText, from, to); + + cm.focus(); + } +}); + +exports.default = AddLink; + +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _importManager = __webpack_require__(15); + +var _importManager2 = _interopRequireDefault(_importManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** +* @fileoverview Implments AddImage markdown command +* @author NHN Ent. FE Development Lab +*/ +var decodeURIGraceful = _importManager2.default.decodeURIGraceful, + encodeMarkdownCharacters = _importManager2.default.encodeMarkdownCharacters, + escapeMarkdownCharacters = _importManager2.default.escapeMarkdownCharacters; + +/** + * AddImage + * Add Image markdown syntax to markdown Editor + * @extends Command + * @module markdownCommands/AddImage + * @ignore + */ + +var AddImage = _commandManager2.default.command('markdown', /** @lends AddImage */{ + name: 'AddImage', + /** + * Command Handler + * @param {MarkdownEditor} mde MarkdownEditor instance + * @param {object} data data for image + */ + exec: function exec(mde, data) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + + var range = mde.getCurrentRange(); + + var from = { + line: range.from.line, + ch: range.from.ch + }; + + var to = { + line: range.to.line, + ch: range.to.ch + }; + + var altText = data.altText, + imageUrl = data.imageUrl; + + altText = decodeURIGraceful(altText); + altText = escapeMarkdownCharacters(altText); + imageUrl = encodeMarkdownCharacters(imageUrl); + var replaceText = '![' + altText + '](' + imageUrl + ')'; + + doc.replaceRange(replaceText, from, to, '+addImage'); + + cm.focus(); + } +}); + +exports.default = AddImage; + +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _listRegex = __webpack_require__(24); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview Implements UL markdown command + * @author NHN Ent. FE Development Lab + */ +var MD_UL_TASK_SYNTAX_RX = /([-*])( \[[ xX]]) /; +var MD_UL_OR_UL_TASK_SYNTAX_RX = /[\d]+\.( \[[ xX]])? /; + +/** + * UL + * Add unordered list markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/UL + * @ignore + */ +var UL = _commandManager2.default.command('markdown', /** @lends UL */{ + name: 'UL', + keyMap: ['CTRL+U', 'META+U'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var range = mde.getCurrentRange(); + var listManager = mde.componentManager.getManager('list'); + var lineRange = listManager.expandLineRangeIfNeed(doc, range, isOlOrTask); + var startLineNumber = lineRange.start; + var endLineNumber = lineRange.end; + var line = void 0, + currentLineStart = void 0; + + for (var i = startLineNumber; i <= endLineNumber; i += 1) { + currentLineStart = { + line: i, + ch: 0 + }; + + line = doc.getLine(i); + + if (listManager.isListOrParagraph(line)) { + if (isUlTask(line)) { + listManager.replaceLineText(doc, i, MD_UL_TASK_SYNTAX_RX, '$1 '); + } else if (isOlOrTask(line)) { + listManager.replaceLineText(doc, i, MD_UL_OR_UL_TASK_SYNTAX_RX, '* '); + } else if (!line.match(_listRegex.FIND_MD_UL_RX)) { + doc.replaceRange('* ', currentLineStart); + } + + if (i === endLineNumber) { + listManager.appendBlankLineIfNeed(cm, i, endLineNumber, startLineNumber); + } + } else { + break; + } + } + cm.focus(); + } +}); + +/** + * Return whether the given line is UL TASK + * @param {string} line Line text + * @returns {boolean} + */ +function isUlTask(line) { + return !!(line && line.match(_listRegex.FIND_MD_UL_TASK_RX)); +} + +/** + * Return whether passed line is OL or TASK or neither + * @param {string} line Line text + * @returns {boolean} + */ +function isOlOrTask(line) { + return !!(line && (line.match(_listRegex.FIND_MD_TASK_RX) || line.match(_listRegex.FIND_MD_OL_RX))); +} + +exports.default = UL; + +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _listRegex = __webpack_require__(24); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview Implements OL markdown command + * @author NHN Ent. FE Development Lab + */ + +var MD_LIST_OR_TASK_SYNTAX_RX = /([-*]|[\d]+\.)( \[[ xX]])? /; + +/** + * OL + * Add ordered list markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/OL + * @ignore + */ +var OL = _commandManager2.default.command('markdown', /** @lends OL */{ + name: 'OL', + keyMap: ['CTRL+O', 'META+O'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var range = mde.getCurrentRange(); + var listManager = mde.componentManager.getManager('list'); + var lineRange = listManager.expandLineRangeIfNeed(doc, range, isUlOrTask); + var startLineNumber = lineRange.start; + var endLineNumber = lineRange.end; + var ordinalNumber = 1; + var line = void 0, + currentLineStart = void 0; + + for (var i = startLineNumber; i <= endLineNumber; i += 1) { + currentLineStart = { + line: i, + ch: 0 + }; + + line = doc.getLine(i); + + if (listManager.isListOrParagraph(line)) { + if (isUlOrTask(line)) { + listManager.replaceLineText(doc, i, MD_LIST_OR_TASK_SYNTAX_RX, ordinalNumber + '. '); + } else if (!line.match(_listRegex.FIND_MD_OL_RX)) { + doc.replaceRange(ordinalNumber + '. ', currentLineStart); + } + + ordinalNumber += 1; + + if (i === endLineNumber) { + listManager.appendBlankLineIfNeed(cm, i, endLineNumber, startLineNumber); + } + } else { + break; + } + } + cm.focus(); + } +}); + +/** + * Return whether passed line is UL or TASK or neither + * @param {string} line Line text + * @returns {boolean} + */ +function isUlOrTask(line) { + return !!(line && (line.match(_listRegex.FIND_MD_TASK_RX) || line.match(_listRegex.FIND_MD_UL_RX))); +} + +exports.default = OL; + +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Indent + * Add Indent markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/inent + * @ignore + */ +var Indent = _commandManager2.default.command('markdown', /** @lends Indent */{ + name: 'Indent', + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + cm.execCommand('indentOrderedList'); + } +}); /** + * @fileoverview Implements Indent markdown command + * @author NHN Ent. FE Development Lab + */ + +exports.default = Indent; + +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Outdent + * Add Outdent markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/outdent + * @ignore + */ +var Outdent = _commandManager2.default.command('markdown', /** @lends Outdent */{ + name: 'Outdent', + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + cm.execCommand('indentLessOrderedList'); + } +}); /** + * @fileoverview Implements Outdent markdown command + * @author NHN Ent. FE Development Lab + */ + +exports.default = Outdent; + +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Table + * Add table markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Table + * @ignore + */ +var Table = _commandManager2.default.command('markdown', /** @lends Table */{ + name: 'Table', + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + * @param {number} col column count + * @param {number} row row count + * @param {Array} data initial table data + */ + exec: function exec(mde, col, row, data) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var table = '\n'; + + if (cm.getCursor().ch > 0) { + table += '\n'; + } + + table += makeHeader(col, data); + table += makeBody(col, row - 1, data); + + doc.replaceSelection(table); + + if (!data) { + cm.setCursor(cm.getCursor().line - row, 2); + } + + mde.focus(); + } +}); + +/** + * makeHeader + * make table header markdown string + * @param {number} col Column count + * @param {array} data Cell's text content + * @returns {string} markdown string + */ +/** + * @fileoverview Implements Table markdown command + * @author NHN Ent. FE Development Lab + */ + +function makeHeader(col, data) { + var header = '|'; + var border = '|'; + var index = 0; + + while (col) { + if (data) { + header += ' ' + data[index] + ' |'; + index += 1; + } else { + header += ' |'; + } + + border += ' --- |'; + + col -= 1; + } + + return header + '\n' + border + '\n'; +} + +/** + * makeBody + * make table body markdown string + * @param {number} col column count + * @param {number} row row count + * @param {Array} data initial table data + * @returns {string} html string + */ +function makeBody(col, row, data) { + var body = ''; + var index = col; + + for (var irow = 0; irow < row; irow += 1) { + body += '|'; + + for (var icol = 0; icol < col; icol += 1) { + if (data) { + body += ' ' + data[index] + ' |'; + index += 1; + } else { + body += ' |'; + } + } + + body += '\n'; + } + + body = body.replace(/\n$/g, ''); + + return body; +} +exports.default = Table; + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _listRegex = __webpack_require__(24); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview Implements Task markdown command + * @author NHN Ent. FE Development Lab + */ +var MD_UL_OR_OL_SYNTAX_RX = /([*-] |[\d]+\. )/; +var MD_TASK_SYNTAX_RX = /([*-] |[\d]+\. )(\[[ xX]] )/; + +/** + * Task + * @extends Command + * @module markdownCommands/Task + * @ignore + */ +var Task = _commandManager2.default.command('markdown', /** @lends Task */{ + name: 'Task', + keyMap: ['ALT+T', 'ALT+T'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var range = mde.getCurrentRange(); + var listManager = mde.componentManager.getManager('list'); + var lineRange = listManager.createSortedLineRange(range); + var startLineNumber = lineRange.start; + var endLineNumber = lineRange.end; + var line = void 0, + currentLineStart = void 0; + + for (var i = startLineNumber; i <= endLineNumber; i += 1) { + currentLineStart = { + line: i, + ch: 0 + }; + + line = doc.getLine(i); + + var hasTaskSyntax = !!line.match(MD_TASK_SYNTAX_RX); + + if (listManager.isListOrParagraph(line)) { + if (isOlOrUl(line) && hasTaskSyntax) { + listManager.replaceLineText(doc, i, MD_TASK_SYNTAX_RX, '$1'); + } else if (isOlOrUl(line) && !hasTaskSyntax) { + listManager.replaceLineText(doc, i, MD_UL_OR_OL_SYNTAX_RX, '$1[ ] '); + } else if (!line.match(_listRegex.FIND_MD_TASK_RX)) { + doc.replaceRange('* [ ] ', currentLineStart); + } + + if (i === endLineNumber) { + listManager.appendBlankLineIfNeed(cm, i, endLineNumber, startLineNumber); + } + } else { + break; + } + } + cm.focus(); + } +}); + +/** + * Return whether passed line is OL or UL or neither + * @param {string} line Line text + * @returns {boolean} + */ +function isOlOrUl(line) { + return !!(line && (line.match(_listRegex.FIND_MD_UL_RX) || line.match(_listRegex.FIND_MD_OL_RX))); +} + +exports.default = Task; + +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var codeRangeRegex = /^`([^`]+)`$/; /** + * @fileoverview Implements Code markdown command + * @author NHN Ent. FE Development Lab + */ + +var codeContentRegex = /`([^`]+)`/g; + +/** + * Code + * Add code markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/Code + * @ignore + */ +var Code = _commandManager2.default.command('markdown', /** @lends Code */{ + name: 'Code', + keyMap: ['SHIFT+CTRL+C', 'SHIFT+META+C'], + /** + * Command Handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var selection = doc.getSelection(); + var cursor = cm.getCursor(); + var hasSyntax = this.hasStrikeSyntax(selection); + + var result = void 0; + if (hasSyntax) { + result = this.remove(selection); + result = this._removeCodeSyntax(result); + } else { + result = this._removeCodeSyntax(selection); + result = this.append(result); + } + + doc.replaceSelection(result, 'around'); + + if (!selection && !hasSyntax) { + this.setCursorToCenter(doc, cursor, hasSyntax); + } + + cm.focus(); + }, + + + /** + * set cursor to center + * @param {CodeMirror.doc} doc - codemirror document + * @param {object} cursor - codemirror cursor + * @param {boolean} isRemoved - whether it involes deletion + */ + setCursorToCenter: function setCursorToCenter(doc, cursor, isRemoved) { + var pos = isRemoved ? -1 : 1; + doc.setCursor(cursor.line, cursor.ch + pos); + }, + + + /** + * has code syntax + * @param {string} text Source text + * @returns {boolean} true if the given text has a code syntax + */ + hasStrikeSyntax: function hasStrikeSyntax(text) { + return codeRangeRegex.test(text); + }, + + + /** + * apply Code + * @param {string} text - selected text + * @returns {string} - text after code syntax applied + */ + append: function append(text) { + return '`' + text + '`'; + }, + + + /** + * remove Code + * @param {string} text - selected text + * @returns {string} - text after code syntax removed + */ + remove: function remove(text) { + return text.substr(1, text.length - 2); + }, + + + /** + * remove bold syntax in the middle of given text + * @param {string} text - text selected + * @returns {string} - text eliminated all code in the middle of it's content + * @private + */ + _removeCodeSyntax: function _removeCodeSyntax(text) { + return text ? text.replace(codeContentRegex, '$1') : ''; + } +}); + +exports.default = Code; + +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * CodeBlock + * Add CodeBlock markdown syntax to markdown editor + * @extends Command + * @module markdownCommands/CodeBlock + * @ignore + */ +var CodeBlock = _commandManager2.default.command('markdown', /** @lends CodeBlock */{ + name: 'CodeBlock', + keyMap: ['SHIFT+CTRL+P', 'SHIFT+META+P'], + /** + * Command handler + * @param {MarkdownEditor} mde MarkdownEditor instance + */ + exec: function exec(mde) { + var cm = mde.getEditor(); + var doc = cm.getDoc(); + var range = mde.getCurrentRange(); + var replaceText = ['```', doc.getSelection(), '```']; + var cursorOffset = 1; + // insert a line break to the front if the selection starts in the middle of a text + if (range.from.ch !== 0) { + replaceText.unshift(''); + cursorOffset += 1; + } + // insert a line break to the end if the selection has trailing text + if (range.to.ch !== doc.getLine(range.to.line).length) { + replaceText.push(''); + } + doc.replaceSelection(replaceText.join('\n')); + + cm.setCursor(range.from.line + cursorOffset, 0); + + cm.focus(); + } +}); /** + * @fileoverview Implements CodeBlock markdown command + * @author NHN Ent. FE Development Lab + */ +exports.default = CodeBlock; + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Bold + * Add bold to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Bold + * @ignore + */ +var Bold = _commandManager2.default.command('wysiwyg', /** @lends Bold */{ + name: 'Bold', + keyMap: ['CTRL+B', 'META+B'], + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var tableSelectionManager = wwe.componentManager.getManager('tableSelection'); + + wwe.focus(); + + if (sq.hasFormat('table') && tableSelectionManager.getSelectedCells().length) { + tableSelectionManager.styleToSelectedCells(styleBold); + + var range = sq.getSelection(); + range.collapse(true); + sq.setSelection(range); + } else { + styleBold(sq); + } + } +}); + +/** + * Style bold. + * @param {object} sq - squire editor instance + */ +/** + * @fileoverview Implements bold WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +function styleBold(sq) { + if (sq.hasFormat('b') || sq.hasFormat('strong')) { + sq.changeFormat(null, { tag: 'b' }); + } else if (!sq.hasFormat('a') && !sq.hasFormat('PRE')) { + if (sq.hasFormat('code')) { + sq.changeFormat(null, { tag: 'code' }); + } + sq.bold(); + } +} + +exports.default = Bold; + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Italic + * Add Italic to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Italic + * @ignore + */ +var Italic = _commandManager2.default.command('wysiwyg', /** @lends Italic */{ + name: 'Italic', + keyMap: ['CTRL+I', 'META+I'], + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var tableSelectionManager = wwe.componentManager.getManager('tableSelection'); + + wwe.focus(); + + if (sq.hasFormat('table') && tableSelectionManager.getSelectedCells().length) { + tableSelectionManager.styleToSelectedCells(styleItalic); + + var range = sq.getSelection(); + range.collapse(true); + sq.setSelection(range); + } else { + styleItalic(sq); + } + } +}); + +/** + * Style italic. + * @param {object} sq - squire editor instance + */ +/** + * @fileoverview Implements italic WysiwygCommand + * @author NHN Ent. FE Development Lab + */ + +function styleItalic(sq) { + if (sq.hasFormat('i') || sq.hasFormat('em')) { + sq.changeFormat(null, { tag: 'i' }); + } else if (!sq.hasFormat('a') && !sq.hasFormat('PRE')) { + if (sq.hasFormat('code')) { + sq.changeFormat(null, { tag: 'code' }); + } + sq.italic(); + } +} + +exports.default = Italic; + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Strike + * Add strike to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Strike + * @ignore + */ +var Strike = _commandManager2.default.command('wysiwyg', /** @lends Strike */{ + name: 'Strike', + keyMap: ['CTRL+S', 'META+S'], + /** + * command handler + * @param {WysiwygEditor} wwe WysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var tableSelectionManager = wwe.componentManager.getManager('tableSelection'); + + wwe.focus(); + + if (sq.hasFormat('table') && tableSelectionManager.getSelectedCells().length) { + tableSelectionManager.styleToSelectedCells(styleStrike); + + var range = sq.getSelection(); + range.collapse(true); + sq.setSelection(range); + } else { + styleStrike(sq); + } + } +}); + +/** + * Style strike. + * @param {object} sq - squire editor instance + */ +/** + * @fileoverview Implements strike WysiwygCommand + * @author NHN Ent. FE Development Lab + */ + +function styleStrike(sq) { + if (sq.hasFormat('S')) { + sq.changeFormat(null, { tag: 'S' }); + } else if (!sq.hasFormat('a') && !sq.hasFormat('PRE')) { + if (sq.hasFormat('code')) { + sq.changeFormat(null, { tag: 'code' }); + } + sq.strikethrough(); + } +} + +exports.default = Strike; + +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Blockquote + * Add Blockquote to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Blockquote + * @ignore + */ +var Blockquote = _commandManager2.default.command('wysiwyg', /** @lends Blockquote */{ + name: 'Blockquote', + keyMap: ['ALT+Q', 'ALT+Q'], + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + + wwe.focus(); + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + if (sq.hasFormat('BLOCKQUOTE')) { + sq.decreaseQuoteLevel(); + } else { + sq.increaseQuoteLevel(); + } + } + } +}); /** + * @fileoverview Implements block quote WysiwygCommand + * @author NHN Ent. FE Development Lab + */ + +exports.default = Blockquote; + +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _importManager = __webpack_require__(15); + +var _importManager2 = _interopRequireDefault(_importManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * @fileoverview Implements AddImage wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var decodeURIGraceful = _importManager2.default.decodeURIGraceful, + encodeMarkdownCharacters = _importManager2.default.encodeMarkdownCharacters; + +/** + * AddImage + * Add Image markdown syntax to wysiwyg Editor + * @extends Command + * @module wysiwygCommands/AddImage + * @ignore + */ + +var AddImage = _commandManager2.default.command('wysiwyg', /** @lends AddImage */{ + name: 'AddImage', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + * @param {object} data data for image + */ + exec: function exec(wwe, data) { + var sq = wwe.getEditor(); + var altText = data.altText, + imageUrl = data.imageUrl; + + altText = decodeURIGraceful(altText); + imageUrl = encodeMarkdownCharacters(imageUrl); + + wwe.focus(); + + if (!sq.hasFormat('PRE')) { + sq.insertImage(imageUrl, { 'alt': altText }); + } + } +}); + +exports.default = AddImage; + +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _importManager = __webpack_require__(15); + +var _importManager2 = _interopRequireDefault(_importManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var decodeURIGraceful = _importManager2.default.decodeURIGraceful, + encodeMarkdownCharacters = _importManager2.default.encodeMarkdownCharacters; + +/** + * AddLink + * Add link markdown syntax to wysiwyg Editor + * @extends Command + * @module wysiwygCommands/AddLink + * @ignore + */ +/** + * @fileoverview Implements AddLink wysiwyg command + * @author NHN Ent. FE Development Lab + */ + +var AddLink = _commandManager2.default.command('wysiwyg', /** @lends AddLink */{ + name: 'AddLink', + /** + * command handler + * @param {WysiwygEditor} wwe - wysiwygEditor instance + * @param {object} data - data for image + */ + exec: function exec(wwe, data) { + var sq = wwe.getEditor(); + var url = data.url, + linkText = data.linkText; + + linkText = decodeURIGraceful(linkText); + url = encodeMarkdownCharacters(url); + + wwe.focus(); + + if (!sq.hasFormat('PRE')) { + sq.removeAllFormatting(); + + if (sq.getSelectedText()) { + sq.makeLink(url); + } else { + var link = sq.createElement('A', { href: url }); + (0, _jquery2.default)(link).text(linkText); + sq.insertElement(link); + } + } + } +}); + +exports.default = AddLink; + +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * HR + * Add horizontal line markdown syntax to wysiwyg Editor + * @extends Command + * @module wysiwygCommands/HR + * @ignore + */ +/** + * @fileoverview Implements HR wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var HR = _commandManager2.default.command('wysiwyg', /** @lends HR */{ + name: 'HR', + keyMap: ['CTRL+L', 'META+L'], + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var currentNode = void 0, + nextBlockNode = void 0, + previousSibling = void 0; + + if (range.collapsed && !sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + currentNode = _domUtils2.default.getChildNodeByOffset(range.startContainer, range.startOffset); + nextBlockNode = _domUtils2.default.getTopNextNodeUnder(currentNode, wwe.get$Body()[0]); + + if (!nextBlockNode) { + nextBlockNode = sq.createDefaultBlock(); + wwe.get$Body().append(nextBlockNode); + } + + var hr = sq.createElement('HR'); + + sq.modifyBlocks(function (frag) { + frag.appendChild(hr); + + return frag; + }); + + previousSibling = hr.previousSibling; + + if (previousSibling && _domUtils2.default.isTextNode(previousSibling) && _domUtils2.default.getTextLength(previousSibling) === 0) { + hr.parentNode.removeChild(previousSibling); + } + + range.selectNodeContents(nextBlockNode); + range.collapse(true); + + sq.setSelection(range); + } + + wwe.focus(); + } +}); + +exports.default = HR; + +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Heading + * Convert selected root level contents to heading with size wysiwyg Editor + * @extends Command + * @module wysiwygCommands/Heading + * @ignore + */ +/** + * @fileoverview Implements Heading wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var Heading = _commandManager2.default.command('wysiwyg', /** @lends Heading */{ + name: 'Heading', + /** + * Command handler + * @param {WysiwygEditor} wwe WYSIWYGEditor instance + * @param {Number} size size + */ + exec: function exec(wwe, size) { + var sq = wwe.getEditor(); + var blockTagName = 'h1, h2, h3, h4, h5, h6, div'; + + wwe.focus(); + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + sq.modifyBlocks(function (fragment) { + (0, _jquery2.default)(fragment).children(blockTagName).each(function (index, block) { + var headingHTML = ''; + var $block = (0, _jquery2.default)(block); + + if ($block.is('DIV')) { + $block.wrap(headingHTML); + } else { + var $wrapperHeading = (0, _jquery2.default)(headingHTML); + + $wrapperHeading.insertBefore(block); + $wrapperHeading.html($block.html()); + $block.remove(); + } + }); + + return fragment; + }); + } + } +}); + +exports.default = Heading; + +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Paragraph + * Convert selected contents to paragraph only heading and list + * @extends Command + * @module wysiwygCommands/Paragraph + * @ignore + */ +/** + * @fileoverview Implements Paragraph wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var Paragraph = _commandManager2.default.command('wysiwyg', /** @lends Paragraph */{ + name: 'Paragraph', + /** + * Command handler + * @param {WysiwygEditor} wwe WYSIWYGEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + + wwe.focus(); + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + sq.modifyBlocks(function (fragment) { + var $newFragment = (0, _jquery2.default)(document.createDocumentFragment()); + + (0, _jquery2.default)(fragment).children().each(function (index, block) { + if (block.nodeName.match(/h\d/i)) { + $newFragment.append((0, _jquery2.default)(block).children()); + } else if (block.nodeName.match(/ul|ol/i)) { + (0, _jquery2.default)(block).find('li').each(function (i, listItem) { + $newFragment.append((0, _jquery2.default)(listItem).children()); + }); + } else { + $newFragment.append(block); + } + }); + + return $newFragment[0]; + }); + } + } +}); + +exports.default = Paragraph; + +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * UL + * Add UL to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/UL + * @ignore + */ +/** + * @fileoverview Implements ul WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +var UL = _commandManager2.default.command('wysiwyg', /** @lends UL */{ + name: 'UL', + keyMap: ['CTRL+U', 'META+U'], + /** + * Command Handler + * @param {WysiwygEditor} wwe WYSIWYGEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var listManager = wwe.componentManager.getManager('list'); + var startContainer = range.startContainer, + endContainer = range.endContainer, + startOffset = range.startOffset, + endOffset = range.endOffset; + + + wwe.focus(); + sq.saveUndoState(range); + + var lines = listManager.getLinesOfSelection(startContainer, endContainer); + + var newLIs = []; + for (var i = 0; i < lines.length; i += 1) { + var newLI = this._changeFormatToUnorderedListIfNeed(wwe, lines[i]); + if (newLI) { + newLIs.push(newLI); + } + } + + if (newLIs.length) { + var newStartContainer = _domUtils2.default.containsNode(newLIs[0], startContainer) ? startContainer : newLIs[0]; + var newEndContainer = _domUtils2.default.containsNode(newLIs[newLIs.length - 1], endContainer) ? endContainer : newLIs[newLIs.length - 1]; + + wwe.setSelectionByContainerAndOffset(newStartContainer, startOffset, newEndContainer, endOffset); + } + }, + + + /** + * Change format to unordered list if need + * @param {WysiwygEditor} wwe Wysiwyg editor instance + * @param {HTMLElement} target Element target for change + * @returns {HTMLElement} newly created list + * @private + */ + _changeFormatToUnorderedListIfNeed: function _changeFormatToUnorderedListIfNeed(wwe, target) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var taskManager = wwe.componentManager.getManager('task'); + var newLI = void 0; + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + range.setStart(target, 0); + range.collapse(true); + sq.setSelection(range); + + if (sq.hasFormat('LI')) { + wwe.saveSelection(range); + taskManager.unformatTask(range.startContainer); + sq.replaceParent(range.startContainer, 'ol', 'ul'); + wwe.restoreSavedSelection(); + } else { + wwe.unwrapBlockTag(); + sq.makeUnorderedList(); + } + + newLI = sq.getSelection().startContainer; + } + + return newLI; + } +}); + +exports.default = UL; + +/***/ }), +/* 137 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * OL + * Add OL to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/OL + * @ignore + */ +/** + * @fileoverview Implements ol WysiwygCommand + * @author NHN Ent. FE Development Lab + */ + +var OL = _commandManager2.default.command('wysiwyg', /** @lends OL */{ + name: 'OL', + keyMap: ['CTRL+O', 'META+O'], + /** + * Command Handler + * @param {WysiwygEditor} wwe WYSIWYGEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var listManager = wwe.componentManager.getManager('list'); + var startContainer = range.startContainer, + startOffset = range.startOffset, + endContainer = range.endContainer, + endOffset = range.endOffset; + + + wwe.focus(); + sq.saveUndoState(range); + + var lines = listManager.getLinesOfSelection(startContainer, endContainer); + + var newLIs = []; + for (var i = 0; i < lines.length; i += 1) { + var newLI = this._changeFormatToOrderedListIfNeed(wwe, lines[i]); + if (newLI) { + newLIs.push(newLI); + } + } + + if (newLIs.length) { + var newStartContainer = _domUtils2.default.containsNode(newLIs[0], startContainer) ? startContainer : newLIs[0]; + var newEndContainer = _domUtils2.default.containsNode(newLIs[newLIs.length - 1], endContainer) ? endContainer : newLIs[newLIs.length - 1]; + + wwe.setSelectionByContainerAndOffset(newStartContainer, startOffset, newEndContainer, endOffset); + } + }, + + + /** + * Change format to unordered list if need + * @param {WysiwygEditor} wwe Wysiwyg editor instance + * @param {HTMLElement} target Element target for change + * @returns {HTMLElement} newly created list item + * @private + */ + _changeFormatToOrderedListIfNeed: function _changeFormatToOrderedListIfNeed(wwe, target) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var taskManager = wwe.componentManager.getManager('task'); + var newLI = void 0; + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + range.setStart(target, 0); + range.collapse(true); + sq.setSelection(range); + + if (sq.hasFormat('LI')) { + wwe.saveSelection(range); + taskManager.unformatTask(range.startContainer); + sq.replaceParent(range.startContainer, 'ul', 'ol'); + wwe.restoreSavedSelection(); + } else { + wwe.unwrapBlockTag(); + sq.makeOrderedList(); + } + + newLI = sq.getSelection().startContainer; + } + + return newLI; + } +}); + +exports.default = OL; + +/***/ }), +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Table + * Add table to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Table + * @ignore + */ +var Table = _commandManager2.default.command('wysiwyg', /** @lends Table */{ + name: 'Table', + /** + * Command Handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + * @param {number} col column count + * @param {number} row row count + * @param {Array} data initial table data + */ + exec: function exec(wwe, col, row, data) { + var sq = wwe.getEditor(); + var tableIDClassName = wwe.componentManager.getManager('table').getTableIDClassName(); + var tableHTMLString = void 0; + + if (!sq.getSelection().collapsed || sq.hasFormat('TABLE') || sq.hasFormat('PRE')) { + wwe.focus(); + + return; + } + + tableHTMLString = ''; + tableHTMLString += makeHeader(col, data); + tableHTMLString += makeBody(col, row - 1, data); + tableHTMLString += '
    '; + + sq.insertHTML(tableHTMLString); + + wwe.focus(); + + if (!data) { + focusToFirstTh(sq, wwe.get$Body().find('.' + tableIDClassName)); + } + } +}); + +/** + * Focus to first th + * @param {Squire} sq Squire instance + * @param {jQuery} $table jQuery wrapped table element + */ +/** + * @fileoverview Implements table WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +function focusToFirstTh(sq, $table) { + var range = sq.getSelection(); + + range.selectNodeContents($table.find('th')[0]); + range.collapse(true); + sq.setSelection(range); +} + +/** + * makeHeader + * make table header html string + * @param {number} col column count + * @param {string} data cell data + * @returns {string} html string + */ +function makeHeader(col, data) { + var header = ''; + var index = 0; + + while (col) { + header += ''; + + if (data) { + header += data[index]; + index += 1; + } + + header += ''; + col -= 1; + } + + header += ''; + + return header; +} + +/** + * makeBody + * make table body html string + * @param {number} col column count + * @param {number} row row count + * @param {string} data cell data + * @returns {string} html string + */ +function makeBody(col, row, data) { + var body = ''; + var index = col; + + for (var irow = 0; irow < row; irow += 1) { + body += ''; + + for (var icol = 0; icol < col; icol += 1) { + body += ''; + + if (data) { + body += data[index]; + index += 1; + } + + body += ''; + } + + body += ''; + } + + body += ''; + + return body; +} + +exports.default = Table; + +/***/ }), +/* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * AddRow + * Add Row to selected table + * @extends Command + * @module wysiwygCommands/TableAddRow + * @ignore + */ +var TableAddRow = _commandManager2.default.command('wysiwyg', /** @lends AddRow */{ + name: 'AddRow', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var selectedRowLength = getSelectedRowsLength(wwe); + var $tr = void 0, + $newRow = void 0; + + wwe.focus(); + + if (sq.hasFormat('TD')) { + sq.saveUndoState(range); + $tr = (0, _jquery2.default)(range.startContainer).closest('tr'); + for (var i = 0; i < selectedRowLength; i += 1) { + $newRow = getNewRow($tr); + $newRow.insertAfter($tr); + } + + focusToFirstTd(sq, $newRow); + } else if (sq.hasFormat('TH')) { + sq.saveUndoState(range); + $tr = (0, _jquery2.default)(range.startContainer).parents('thead').next('tbody').children('tr').eq(0); + for (var _i = 0; _i < selectedRowLength; _i += 1) { + $newRow = getNewRow($tr); + $newRow.insertBefore($tr); + } + + focusToFirstTd(sq, $newRow); + } + } +}); + +/** + * get number of selected rows + * @param {WysiwygEditor} wwe - wysiwygEditor instance + * @returns {number} - number of selected rows + * @ignore + */ +/** + * @fileoverview Implements table add row WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +function getSelectedRowsLength(wwe) { + var selectionMgr = wwe.componentManager.getManager('tableSelection'); + var $selectedCells = selectionMgr.getSelectedCells(); + var length = 1; + + if ($selectedCells.length > 1) { + var first = $selectedCells.first().get(0); + var last = $selectedCells.last().get(0); + var range = selectionMgr.getSelectionRangeFromTable(first, last); + length = range.to.row - range.from.row + 1; + } + + return length; +} + +/** + * Get new row of given row + * @param {jQuery} $tr - jQuery wrapped table row + * @returns {jQuery} - new cloned jquery element + * @ignore + */ +function getNewRow($tr) { + var cloned = $tr.clone(); + var htmlString = _tuiCodeSnippet2.default.browser.msie ? '' : '
    '; + + cloned.find('td').html(htmlString); + + return cloned; +} + +/** + * Focus to first table cell + * @param {Squire} sq - Squire instance + * @param {jQuery} $tr - jQuery wrapped table row + * @ignore + */ +function focusToFirstTd(sq, $tr) { + var range = sq.getSelection(); + + range.selectNodeContents($tr.find('td')[0]); + range.collapse(true); + sq.setSelection(range); +} + +exports.default = TableAddRow; + +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * AddCol + * Add col to selected table + * @extends Command + * @module wysiwygCommands/TableAddCol + * @ignore + */ +/** + * @fileoverview Implements table add column WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +var TableAddCol = _commandManager2.default.command('wysiwyg', /** @lends AddCol */{ + name: 'AddCol', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var numberOfCols = getNumberOfCols(wwe); + var $cell = void 0; + + wwe.focus(); + + if (sq.hasFormat('TR')) { + sq.saveUndoState(range); + + $cell = getCellByRange(range); + addColToCellAfter($cell, numberOfCols); + + focusToNextCell(sq, $cell); + } + } +}); + +/** + * get number of selected cols + * @param {WysiwygEditor} wwe - wysiwyg editor instance + * @returns {number} - number of selected cols + * @ignore + */ +function getNumberOfCols(wwe) { + var selectionMgr = wwe.componentManager.getManager('tableSelection'); + var $selectedCells = selectionMgr.getSelectedCells(); + var length = 1; + + if ($selectedCells.length > 0) { + var maxLength = $selectedCells.get(0).parentNode.querySelectorAll('td, th').length; + length = Math.min(maxLength, $selectedCells.length); + } + + return length; +} + +/** + * Get cell by range object + * @param {Range} range - range + * @returns {jQuery} - jQuery html element + * @ignore + */ +function getCellByRange(range) { + var cell = range.startContainer; + + if (_domUtils2.default.getNodeName(cell) === 'TD' || _domUtils2.default.getNodeName(cell) === 'TH') { + cell = (0, _jquery2.default)(cell); + } else { + cell = (0, _jquery2.default)(cell).parentsUntil('tr'); + } + + return cell; +} + +/** + * Add column to after the current cell + * @param {jQuery} $cell - jQuery wrapped table cell + * @param {number} [numberOfCols=1] - number of cols + * @ignore + */ +function addColToCellAfter($cell) { + var numberOfCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + var index = $cell.index(); + var cellToAdd = void 0; + + $cell.parents('table').find('tr').each(function (n, tr) { + var isTBody = _domUtils2.default.getNodeName(tr.parentNode) === 'TBODY'; + var isMSIE = _tuiCodeSnippet2.default.browser.msie; + var cell = tr.children[index]; + for (var i = 0; i < numberOfCols; i += 1) { + if (isTBody) { + cellToAdd = document.createElement('td'); + } else { + cellToAdd = document.createElement('th'); + } + if (!isMSIE) { + cellToAdd.appendChild(document.createElement('br')); + } + (0, _jquery2.default)(cellToAdd).insertAfter(cell); + } + }); +} + +/** + * Focus to next cell + * @param {Squire} sq - Squire instance + * @param {jQuery} $cell - jQuery wrapped table cell + * @ignore + */ +function focusToNextCell(sq, $cell) { + var range = sq.getSelection(); + + range.selectNodeContents($cell.next()[0]); + range.collapse(true); + + sq.setSelection(range); +} + +exports.default = TableAddCol; + +/***/ }), +/* 141 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * RemoveRow + * remove Row to selected table + * @extends Command + * @module wysiwygCommands/TableRemoveRow + * @ignore + */ +/** + * @fileoverview Implements table remove row WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +var TableRemoveRow = _commandManager2.default.command('wysiwyg', /** @lends RemoveRow */{ + name: 'RemoveRow', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var $table = (0, _jquery2.default)(range.startContainer).parents('table'); + var selectionMgr = wwe.componentManager.getManager('tableSelection'); + var tableMgr = wwe.componentManager.getManager('table'); + var $tr = getTrs(range, selectionMgr, $table); + var tbodyRowLength = $table.find('tbody tr').length; + + wwe.focus(); + + if ((sq.hasFormat('TD') || sq.hasFormat('TABLE')) && tbodyRowLength > 1) { + sq.saveUndoState(range); + var $nextFocus = $tr.last().next()[0] ? $tr.last().next() : $tr.first().prev(); + + if ($nextFocus.length) { + focusToFirstTd(sq, range, $nextFocus, tableMgr); + } + $tr.remove(); + } + selectionMgr.removeClassAttrbuteFromAllCellsIfNeed(); + } +}); + +/** + * Focus to first TD in given TR + * @param {SquireExt} sq Squire instance + * @param {Range} range Range object + * @param {jQuery} $tr jQuery wrapped TR + * @param {object} tableMgr Table manager + */ +function focusToFirstTd(sq, range, $tr, tableMgr) { + var nextFocusCell = $tr.find('td').get(0); + range.setStart(nextFocusCell, 0); + range.collapse(true); + + tableMgr.setLastCellNode(nextFocusCell); + sq.setSelection(range); +} + +/** + * Get start, end row index from current range + * @param {HTMLElement} firstSelectedCell Range object + * @param {object} rangeInformation Range information object + * @param {jQuery} $table jquery wrapped TABLE + * @returns {jQuery} + */ +function getSelectedRows(firstSelectedCell, rangeInformation, $table) { + var tbodyRowLength = $table.find('tbody tr').length; + var isStartContainerInThead = (0, _jquery2.default)(firstSelectedCell).parents('thead').length; + var startRowIndex = rangeInformation.from.row; + var endRowIndex = rangeInformation.to.row; + + if (isStartContainerInThead) { + startRowIndex += 1; + } + + var isWholeTbodySelected = (startRowIndex === 1 || isStartContainerInThead) && endRowIndex === tbodyRowLength; + + if (isWholeTbodySelected) { + endRowIndex -= 1; + } + + return $table.find('tr').slice(startRowIndex, endRowIndex + 1); +} + +/** + * Get TRs + * @param {Range} range Range object + * @param {object} selectionMgr Table selection manager + * @param {jQuery} $table current table + * @returns {jQuery} + */ +function getTrs(range, selectionMgr, $table) { + var $selectedCells = selectionMgr.getSelectedCells(); + var rangeInformation = void 0, + trs = void 0; + + if ($selectedCells.length) { + rangeInformation = selectionMgr.getSelectionRangeFromTable($selectedCells.first().get(0), $selectedCells.last().get(0)); + trs = getSelectedRows($selectedCells.first()[0], rangeInformation, $table); + } else { + var cell = (0, _jquery2.default)(range.startContainer).closest('td,th').get(0); + rangeInformation = selectionMgr.getSelectionRangeFromTable(cell, cell); + trs = getSelectedRows(cell, rangeInformation, $table); + } + + return trs; +} +exports.default = TableRemoveRow; + +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * RemoveCol + * remove Row to selected table + * @extends Command + * @module wysiwygCommands/TableRemoveCol + * @ignore + */ +var TableRemoveCol = _commandManager2.default.command('wysiwyg', /** @lends RemoveCol */{ + name: 'RemoveCol', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var $table = (0, _jquery2.default)(range.startContainer).parents('table'); + var tableMgr = wwe.componentManager.getManager('table'); + var selectionMgr = wwe.componentManager.getManager('tableSelection'); + var hasMultipleCols = (0, _jquery2.default)(range.startContainer).closest('table').find('thead tr th').length > 1; + + wwe.focus(); + // IE 800a025e error on removing part of selection range. collapse + range.collapse(true); + sq.setSelection(range); + + if (sq.hasFormat('TR', null, range) && hasMultipleCols) { + var tbodyColLength = $table.find('tbody tr:first td').length; + var $selectedCellsByManager = selectionMgr.getSelectedCells(); + + if ($selectedCellsByManager.length < tbodyColLength) { + sq.saveUndoState(range); + var $nextFocus = void 0; + + if ($selectedCellsByManager.length > 1) { + var $tailCell = $selectedCellsByManager.last(); + var $headCell = $selectedCellsByManager.first(); + $nextFocus = $tailCell.next().length ? $tailCell.next() : $headCell.prev(); + + removeMultipleColsByCells($selectedCellsByManager); + } else { + var $cell = getCellByRange(range); + $nextFocus = $cell.next().length ? $cell.next() : $cell.prev(); + + removeColByCell($cell); + } + + focusToCell(sq, $nextFocus, tableMgr); + } + } + } +}); + +/** + * Get cell by range object + * @param {Range} range range + * @returns {HTMLElement|Node} + */ +/** + * @fileoverview Implements table remove column WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +function getCellByRange(range) { + var cell = range.startContainer; + + if (_domUtils2.default.getNodeName(cell) === 'TD' || _domUtils2.default.getNodeName(cell) === 'TH') { + cell = (0, _jquery2.default)(cell); + } else { + cell = (0, _jquery2.default)(cell).parentsUntil('tr'); + } + + return cell; +} + +/** + * Remove columns by given cells + * @param {jQuery} $cells - jQuery table cells + */ +function removeMultipleColsByCells($cells) { + var numberOfCells = $cells.length; + for (var i = 0; i < numberOfCells; i += 1) { + var $cellToDelete = $cells.eq(i); + if ($cellToDelete.length > 0) { + removeColByCell($cells.eq(i)); + } + } +} + +/** + * Remove column by given cell + * @param {jQuery} $cell - jQuery wrapped table cell + */ +function removeColByCell($cell) { + var index = $cell.index(); + + $cell.parents('table').find('tr').each(function (n, tr) { + (0, _jquery2.default)(tr).children().eq(index).remove(); + }); +} + +/** + * Focus to given cell + * @param {Squire} sq - Squire instance + * @param {jQuery} $cell - jQuery wrapped table cell + * @param {object} tableMgr - Table manager instance + */ +function focusToCell(sq, $cell, tableMgr) { + var nextFocusCell = $cell.get(0); + + if ($cell.length && _jquery2.default.contains(document, $cell)) { + var range = sq.getSelection(); + range.selectNodeContents($cell[0]); + range.collapse(true); + sq.setSelection(range); + + tableMgr.setLastCellNode(nextFocusCell); + } +} + +exports.default = TableRemoveCol; + +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * AlignCol + * Align selected column's text content to given direction + * @extends Command + * @module wysiwygCommands/TableAlignCol + * @ignore + */ +var TableAlignCol = _commandManager2.default.command('wysiwyg', /** @lends AlignCol */{ + name: 'AlignCol', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + * @param {string} alignDirection Align direction + */ + exec: function exec(wwe, alignDirection) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + var selectionMgr = wwe.componentManager.getManager('tableSelection'); + var rangeInformation = getRangeInformation(range, selectionMgr); + + wwe.focus(); + + if (sq.hasFormat('TR')) { + sq.saveUndoState(range); + + var $table = (0, _jquery2.default)(range.startContainer).parents('table'); + + var selectionInformation = getSelectionInformation($table, rangeInformation); + + setAlignAttributeToTableCells($table, alignDirection, selectionInformation); + } + selectionMgr.removeClassAttrbuteFromAllCellsIfNeed(); + } +}); + +/** + * Set Column align + * @param {jQuery} $table jQuery wrapped TABLE + * @param {string} alignDirection 'left' or 'center' or 'right' + * @param {{ + * startColumnIndex: number, + * endColumnIndex: number, + * isDivided: boolean + * }} selectionInformation start, end column index and boolean value for whether range divided or not + */ +/** + * @fileoverview Implements table align column WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +function setAlignAttributeToTableCells($table, alignDirection, selectionInformation) { + var isDivided = selectionInformation.isDivided || false; + var start = selectionInformation.startColumnIndex; + var end = selectionInformation.endColumnIndex; + var columnLength = $table.find('tr').eq(0).find('td,th').length; + + $table.find('tr').each(function (n, tr) { + (0, _jquery2.default)(tr).children('td,th').each(function (index, cell) { + if (isDivided && (start <= index && index <= columnLength || index <= end)) { + (0, _jquery2.default)(cell).attr('align', alignDirection); + } else if (start <= index && index <= end) { + (0, _jquery2.default)(cell).attr('align', alignDirection); + } + }); + }); +} + +/** + * Return start, end column index and boolean value for whether range divided or not + * @param {jQuery} $table jQuery wrapped TABLE + * @param {{startColumnIndex: number, endColumnIndex: number}} rangeInformation Range information + * @returns {{startColumnIndex: number, endColumnIndex: number, isDivided: boolean}} + */ +function getSelectionInformation($table, rangeInformation) { + var columnLength = $table.find('tr').eq(0).find('td,th').length; + var from = rangeInformation.from, + to = rangeInformation.to; + + var startColumnIndex = void 0, + endColumnIndex = void 0, + isDivided = void 0; + + if (from.row === to.row) { + startColumnIndex = from.cell; + endColumnIndex = to.cell; + } else if (from.row < to.row) { + if (from.cell <= to.cell) { + startColumnIndex = 0; + endColumnIndex = columnLength - 1; + } else { + startColumnIndex = from.cell; + endColumnIndex = to.cell; + isDivided = true; + } + } + + return { + startColumnIndex: startColumnIndex, + endColumnIndex: endColumnIndex, + isDivided: isDivided + }; +} + +/** + * Get range information + * @param {Range} range Range object + * @param {object} selectionMgr Table selection manager + * @returns {object} + */ +function getRangeInformation(range, selectionMgr) { + var $selectedCells = selectionMgr.getSelectedCells(); + var rangeInformation = void 0, + startCell = void 0; + + if ($selectedCells.length) { + rangeInformation = selectionMgr.getSelectionRangeFromTable($selectedCells.first().get(0), $selectedCells.last().get(0)); + } else { + var startContainer = range.startContainer; + + startCell = _domUtils2.default.isTextNode(startContainer) ? (0, _jquery2.default)(startContainer).parent('td,th')[0] : startContainer; + rangeInformation = selectionMgr.getSelectionRangeFromTable(startCell, startCell); + } + + return rangeInformation; +} + +exports.default = TableAlignCol; + +/***/ }), +/* 144 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * RemoveTable + * Remove selected table + * @extends Command + * @module wysiwygCommands/TableRemove + * @ignore + */ +/** + * @fileoverview Implements table remove WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +var TableRemove = _commandManager2.default.command('wysiwyg', /** @lends RemoveTable */{ + name: 'RemoveTable', + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + + if (sq.hasFormat('TABLE')) { + sq.saveUndoState(range); + var $table = (0, _jquery2.default)(range.startContainer).closest('table'); + + $table.remove(); + } + + wwe.focus(); + } +}); + +exports.default = TableRemove; + +/***/ }), +/* 145 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Indent + * Indent list or task to wysiwyg Editor + * @extends Command + * @module wysiwygCommands/indent + * @ignore + */ +/** + * @fileoverview Implements Indent wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var Indent = _commandManager2.default.command('wysiwyg', /** @lends Indent */{ + name: 'Indent', + /** + * Command Handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var listManager = wwe.componentManager.getManager('list'); + var range = wwe.getEditor().getSelection(); + var $node = (0, _jquery2.default)(range.startContainer).closest('li'); + var prevClasses = void 0, + nodeClasses = void 0, + nextClasses = void 0; + + var $prev = $node.prev(); + + if ($prev.length && $node.length) { + var $next = $node.find('li').eq(0); + + wwe.getEditor().saveUndoState(); + + nodeClasses = $node.attr('class'); + prevClasses = $prev.attr('class'); + nextClasses = $next.attr('class'); + + $node.removeAttr('class'); + $prev.removeAttr('class'); + + if ($next.length && !$next.children('div').length) { + $next.removeAttr('class'); + } + + wwe.getEditor().increaseListLevel(); + listManager.mergeList($node.get(0)); + + $node.attr('class', nodeClasses); + $prev.attr('class', prevClasses); + $next.attr('class', nextClasses); + } + } +}); + +exports.default = Indent; + +/***/ }), +/* 146 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Outdent + * Outdent list or task to wysiwyg Editor + * @extends Command + * @module wysiwygCommands/Outdent + * @ignore + */ +/** + * @fileoverview Implements Outdent wysiwyg command + * @author NHN Ent. FE Development Lab + */ +var Outdent = _commandManager2.default.command('wysiwyg', /** @lends Outdent */{ + name: 'Outdent', + + /** + * Command Handler + * @param {WysiwygEditor} wwe WysiwygEditor instance + */ + exec: function exec(wwe) { + var $node = getCurrent$Li(wwe); + + if ($node.length && isExecutable($node)) { + wwe.getEditor().saveUndoState(); + + var nodeClasses = $node.attr('class'); + wwe.getEditor().decreaseListLevel(); + + $node = getCurrent$Li(wwe); + $node.attr('class', nodeClasses); + } + } +}); + +/** + * test if outdent the given list item + * arbitrary list allows list item to be in any position + * while markdown spec does not + * @param {jQuery} $currentLiNode - jQuery list item element + * @returns {boolean} - true to executable + * @ignore + */ +function isExecutable($currentLiNode) { + return !$currentLiNode.next().is('OL,UL'); +} + +/** + * Get list item element of current selection + * @param {object} wwe Wysiwyg editor instance + * @returns {jQuery} + * @ignore + */ +function getCurrent$Li(wwe) { + var range = wwe.getEditor().getSelection(); + + return (0, _jquery2.default)(range.startContainer).closest('li'); +} + +exports.default = Outdent; + +/***/ }), +/* 147 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Task + * Add Task to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Task + * @ignore + */ +var Task = _commandManager2.default.command('wysiwyg', /** @lends Task */{ + name: 'Task', + keyMap: ['ALT+T', 'ALT+T'], + /** + * Command Handler + * @param {WysiwygEditor} wwe WYSIWYGEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var listManager = wwe.componentManager.getManager('list'); + var startContainer = range.startContainer, + endContainer = range.endContainer, + startOffset = range.startOffset, + endOffset = range.endOffset; + + + wwe.focus(); + + sq.saveUndoState(range); + + var lines = listManager.getLinesOfSelection(startContainer, endContainer); + + var newLIs = []; + for (var i = 0; i < lines.length; i += 1) { + var newLI = this._changeFormatToTaskIfNeed(wwe, lines[i]); + if (newLI) { + newLIs.push(newLI); + } + } + + if (newLIs.length) { + var newStartContainer = _domUtils2.default.containsNode(newLIs[0], startContainer) ? startContainer : newLIs[0]; + var newEndContainer = _domUtils2.default.containsNode(newLIs[newLIs.length - 1], endContainer) ? endContainer : newLIs[newLIs.length - 1]; + + wwe.setSelectionByContainerAndOffset(newStartContainer, startOffset, newEndContainer, endOffset); + } + }, + + + /** + * Change format to unordered list and return current li element if need + * @param {WysiwygEditor} wwe Wysiwyg editor instance + * @param {HTMLElement} target Element target for change + * @returns {HTMLElement} newly created list + * @private + */ + _changeFormatToTaskIfNeed: function _changeFormatToTaskIfNeed(wwe, target) { + var sq = wwe.getEditor(); + var range = sq.getSelection(); + var taskManager = wwe.componentManager.getManager('task'); + var newLI = void 0; + + if (!sq.hasFormat('TABLE') && !sq.hasFormat('PRE')) { + range.setStart(target, 0); + range.collapse(true); + sq.setSelection(range); + + if (!sq.hasFormat('li')) { + sq.makeUnorderedList(); + target = sq.getSelection().startContainer; + } + + if ((0, _jquery2.default)(target).hasClass('task-list-item')) { + taskManager.unformatTask(target); + } else { + taskManager.formatTask(target); + } + + newLI = sq.getSelection().startContainer; + } + + return newLI; + } +}); /** + * @fileoverview Implements Task WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +exports.default = Task; + +/***/ }), +/* 148 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +var _domUtils = __webpack_require__(4); + +var _domUtils2 = _interopRequireDefault(_domUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Code + * Add bold to selected wysiwyg editor content + * @extends Command + * @module wysiwygCommands/Code + * @ignore + */ +/** + * @fileoverview Implements code WysiwygCommand + * @author NHN Ent. FE Development Lab + */ +var Code = _commandManager2.default.command('wysiwyg', /** @lends Code */{ + name: 'Code', + keyMap: ['SHIFT+CTRL+C', 'SHIFT+META+C'], + /** + * command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + */ + exec: function exec(wwe) { + var sq = wwe.getEditor(); + var tableSelectionManager = wwe.componentManager.getManager('tableSelection'); + var _styleCode = _tuiCodeSnippet2.default.bind(styleCode, null, wwe.getEditor()); + + wwe.focus(); + + if (sq.hasFormat('table') && tableSelectionManager.getSelectedCells().length) { + tableSelectionManager.styleToSelectedCells(_styleCode); + + var range = sq.getSelection(); + range.collapse(true); + sq.setSelection(range); + } else { + _styleCode(sq); + } + } +}); + +/** + * removeUnnecessaryCodeInNextToRange + * Remove unnecessary code tag next to range, code tag made by squire + * @param {Range} range range object + */ +function removeUnnecessaryCodeInNextToRange(range) { + if (_domUtils2.default.getNodeName(range.startContainer.nextSibling) === 'CODE' && _domUtils2.default.getTextLength(range.startContainer.nextSibling) === 0) { + (0, _jquery2.default)(range.startContainer.nextSibling).remove(); + } +} + +/** + * Style code. + * @param {object} editor - editor instance + * @param {object} sq - squire editor instance + */ +function styleCode(editor, sq) { + if (!sq.hasFormat('PRE') && sq.hasFormat('code')) { + sq.changeFormat(null, { tag: 'code' }); + removeUnnecessaryCodeInNextToRange(editor.getSelection().cloneRange()); + } else if (!sq.hasFormat('a') && !sq.hasFormat('PRE')) { + if (sq.hasFormat('b')) { + sq.removeBold(); + } else if (sq.hasFormat('i')) { + sq.removeItalic(); + } + + sq.changeFormat({ tag: 'code' }); + + var range = sq.getSelection().cloneRange(); + range.setStart(range.endContainer, range.endOffset); + range.collapse(true); + + sq.setSelection(range); + } +} + +exports.default = Code; + +/***/ }), +/* 149 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _tuiCodeSnippet = __webpack_require__(1); + +var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet); + +var _commandManager = __webpack_require__(2); + +var _commandManager2 = _interopRequireDefault(_commandManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var CODEBLOCK_CLASS_TEMP = 'te-content-codeblock-temp'; /** + * @fileoverview Implements code block WysiwygCommand + * @author NHN Ent. FE Development Lab + */ + +var CODEBLOCK_ATTR_NAME = 'data-te-codeblock'; + +/** + * CodeBlock + * Add CodeBlock to wysiwygEditor + * @extends Command + * @module wysiwygCommands/Codeblock + * @ignore + */ +var CodeBlock = _commandManager2.default.command('wysiwyg', /** @lends CodeBlock */{ + name: 'CodeBlock', + keyMap: ['SHIFT+CTRL+P', 'SHIFT+META+P'], + /** + * Command handler + * @param {WysiwygEditor} wwe wysiwygEditor instance + * @param {string} type of language + */ + exec: function exec(wwe, type) { + var sq = wwe.getEditor(); + var range = sq.getSelection().cloneRange(); + if (!sq.hasFormat('PRE') && !sq.hasFormat('TABLE')) { + var attr = CODEBLOCK_ATTR_NAME + ' class = "' + CODEBLOCK_CLASS_TEMP + '"'; + + if (type) { + attr += ' data-language="' + type + '"'; + } + + var codeBlockBody = getCodeBlockBody(range, wwe); + sq.insertHTML('
    ' + codeBlockBody + '
    '); + + focusToFirstCode(wwe.get$Body().find('.' + CODEBLOCK_CLASS_TEMP), wwe); + } + + wwe.focus(); + } +}); + +/** + * focusToFirstCode + * Focus to first code tag content of pre tag + * @param {jQuery} $pre pre tag + * @param {WysiwygEditor} wwe wysiwygEditor + */ +function focusToFirstCode($pre, wwe) { + var range = wwe.getEditor().getSelection().cloneRange(); + $pre.removeClass(CODEBLOCK_CLASS_TEMP); + + range.setStartBefore($pre.get(0).firstChild); + range.collapse(true); + + wwe.getEditor().setSelection(range); +} +/** + * getCodeBlockBody + * get text wrapped by code + * @param {object} range range object + * @param {object} wwe wysiwyg editor + * @returns {string} + */ +function getCodeBlockBody(range, wwe) { + var mgr = wwe.componentManager.getManager('codeblock'); + var codeBlock = void 0; + if (range.collapsed) { + codeBlock = '
    '; + } else { + var contents = range.extractContents(); + var nodes = _tuiCodeSnippet2.default.toArray(contents.childNodes); + var tempDiv = (0, _jquery2.default)('
    ').append(mgr.prepareToPasteOnCodeblock(nodes)); + codeBlock = tempDiv.html(); + } + + return codeBlock; +} + +exports.default = CodeBlock; + +/***/ }), +/* 150 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['en', 'en_US'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Write', + 'Preview': 'Preview', + 'Headings': 'Headings', + 'Paragraph': 'Paragraph', + 'Bold': 'Bold', + 'Italic': 'Italic', + 'Strike': 'Strike', + 'Code': 'Inline code', + 'Line': 'Line', + 'Blockquote': 'Blockquote', + 'Unordered list': 'Unordered list', + 'Ordered list': 'Ordered list', + 'Task': 'Task', + 'Indent': 'Indent', + 'Outdent': 'Outdent', + 'Insert link': 'Insert link', + 'Insert CodeBlock': 'Insert codeBlock', + 'Insert table': 'Insert table', + 'Insert image': 'Insert image', + 'Heading': 'Heading', + 'Image URL': 'Image URL', + 'Select image file': 'Select image file', + 'Description': 'Description', + 'OK': 'OK', + 'More': 'More', + 'Cancel': 'Cancel', + 'File': 'File', + 'URL': 'URL', + 'Link text': 'Link text', + 'Add row': 'Add row', + 'Add col': 'Add col', + 'Remove row': 'Remove row', + 'Remove col': 'Remove col', + 'Align left': 'Align left', + 'Align center': 'Align center', + 'Align right': 'Align right', + 'Remove table': 'Remove table', + 'Would you like to paste as table?': 'Would you like to paste as table?', + 'Text color': 'Text color', + 'Auto scroll enabled': 'Auto scroll enabled', + 'Auto scroll disabled': 'Auto scroll disabled', + 'Cannot paste values ​​other than a table in the cell selection state': 'Cannot paste values ​​other than a table in the cell selection state.', + 'Choose language': 'Choose language' +}); /** + * @fileoverview I18N for English + * @author NHN Ent. FE Development Lab + */ + +/***/ }), +/* 151 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['ko', 'ko_KR'], { + 'Markdown': '마크다운', + 'WYSIWYG': '위지윅', + 'Write': '편집하기', + 'Preview': '미리보기', + 'Headings': '제목크기', + 'Paragraph': '본문', + 'Bold': '굵게', + 'Italic': '기울임꼴', + 'Strike': '취소선', + 'Code': '인라인 코드', + 'Line': '문단나눔', + 'Blockquote': '인용구', + 'Unordered list': '글머리 기호', + 'Ordered list': '번호 매기기', + 'Task': '체크박스', + 'Indent': '들여쓰기', + 'Outdent': '내어쓰기', + 'Insert link': '링크 삽입', + 'Insert CodeBlock': '코드블럭 삽입', + 'Insert table': '표 삽입', + 'Insert image': '이미지 삽입', + 'Heading': '제목', + 'Image URL': '이미지 주소', + 'Select image file': '이미지 파일을 선택하세요.', + 'Description': '설명', + 'OK': '확인', + 'More': '더 보기', + 'Cancel': '취소', + 'File': '파일', + 'URL': '주소', + 'Link text': '링크 텍스트', + 'Add row': '행 추가', + 'Add col': '열 추가', + 'Remove row': '행 삭제', + 'Remove col': '열 삭제', + 'Align left': '왼쪽 정렬', + 'Align center': '가운데 정렬', + 'Align right': '오른쪽 정렬', + 'Remove table': '표 삭제', + 'Would you like to paste as table?': '표형태로 붙여 넣겠습니까?', + 'Text color': '글자 색상', + 'Auto scroll enabled': '자동 스크롤 켜짐', + 'Auto scroll disabled': '자동 스크롤 꺼짐', + 'Cannot paste values ​​other than a table in the cell selection state.': '셀 선택 상태에서는 테이블 이외의 값은 붙여넣을 수 없습니다.', + 'Choose language': '언어 선택' +}); /** + * @fileoverview I18N for Korean + * @author NHN Ent. FE Development Lab + */ + +/***/ }), +/* 152 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['zh', 'zh_CN'], { + 'Markdown': 'Markdown', + 'WYSIWYG': '所见即所得', + 'Write': '编辑', + 'Preview': '预览', + 'Headings': '标题', + 'Paragraph': '文本', + 'Bold': '加粗', + 'Italic': '斜体字', + 'Strike': '删除线', + 'Code': '内嵌代码', + 'Line': '水平线', + 'Blockquote': '引用块', + 'Unordered list': '无序列表', + 'Ordered list': '有序列表', + 'Task': '任务', + 'Indent': '缩进', + 'Outdent': '减少缩进', + 'Insert link': '插入链接', + 'Insert CodeBlock': '插入代码块', + 'Insert table': '插入表格', + 'Insert image': '插入图片', + 'Heading': '标题', + 'Image URL': '图片网址', + 'Select image file': '选择图片文件', + 'Description': '说明', + 'OK': '确认', + 'More': '更多', + 'Cancel': '取消', + 'File': '文件', + 'URL': 'URL', + 'Link text': '链接文本', + 'Add row': '添加行', + 'Add col': '添加列', + 'Remove row': '删除行', + 'Remove col': '删除列', + 'Align left': '左对齐', + 'Align center': '居中对齐', + 'Align right': '右对齐', + 'Remove table': '删除表格', + 'Would you like to paste as table?': '需要粘贴为表格吗?', + 'Text color': '文字颜色', + 'Auto scroll enabled': '自动滚动已启用', + 'Auto scroll disabled': '自动滚动已禁用', + 'Cannot paste values ​​other than a table in the cell selection state': '在选中单元格状态下无法将值粘贴到表格以外。', + 'Choose language': '选择语言' +}); /** + * @fileoverview I18N for Chinese + * @author NHN Ent. FE Development Lab + */ + +/***/ }), +/* 153 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['ja', 'ja_JP'], { + 'Markdown': 'マークダウン', + 'WYSIWYG': 'WYSIWYG', + 'Write': '編集する', + 'Preview': 'プレビュー', + 'Headings': '見出し', + 'Paragraph': '本文', + 'Bold': '太字', + 'Italic': 'イタリック', + 'Strike': 'ストライク', + 'Code': 'インラインコード', + 'Line': 'ライン', + 'Blockquote': '引用', + 'Unordered list': '番号なしリスト', + 'Ordered list': '順序付きリスト', + 'Task': 'タスク', + 'Indent': 'インデント', + 'Outdent': 'アウトデント', + 'Insert link': 'リンク挿入', + 'Insert CodeBlock': 'コードブロック挿入', + 'Insert table': 'テーブル挿入', + 'Insert image': '画像挿入', + 'Heading': '見出し', + 'Image URL': 'イメージURL', + 'Select image file': '画像ファイル選択', + 'Description': 'ディスクリプション ', + 'OK': 'はい', + 'More': 'もっと', + 'Cancel': 'キャンセル', + 'File': 'ファイル', + 'URL': 'URL', + 'Link text': 'リンクテキスト', + 'Add row': '行追加', + 'Add col': '列追加', + 'Remove row': '行削除', + 'Remove col': '列削除', + 'Align left': '左揃え', + 'Align center': '中央揃え', + 'Align right': '右揃え', + 'Remove table': 'テーブル削除', + 'Would you like to paste as table?': 'テーブルを貼り付けますか?', + 'Text color': '文字色相', + 'Auto scroll enabled': '自動スクロールが有効', + 'Auto scroll disabled': '自動スクロールを無効に', + 'Cannot paste values ​​other than a table in the cell selection state': '表以外の値をセル選択状態に貼り付けることはできません。', + 'Choose language': '言語選択' +}); /** + * @fileoverview I18N for Japanese + * @author NHN Ent. FE Development Lab + */ + +/***/ }), +/* 154 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['nl', 'nl_NL'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Write', + 'Preview': 'Preview', + 'Headings': 'Koppen', + 'Paragraph': 'tekst', + 'Bold': 'Vet', + 'Italic': 'Cursief', + 'Strike': 'Doorhalen', + 'Code': 'Inline Code', + 'Line': 'Regel', + 'Blockquote': 'Citaatblok', + 'Unordered list': 'Opsomming', + 'Ordered list': 'Genummerde opsomming', + 'Task': 'Taak', + 'Indent': 'Inspringen', + 'Outdent': 'Outdent', + 'Insert link': 'Link invoegen', + 'Insert CodeBlock': 'Codeblok toevoegen', + 'Insert table': 'Tabel invoegen', + 'Insert image': 'Afbeelding invoegen', + 'Heading': 'Kop', + 'Image URL': 'Afbeelding URL', + 'Select image file': 'Selecteer een afbeelding', + 'Description': 'Omschrijving', + 'OK': 'OK', + 'More': 'verder', + 'Cancel': 'Annuleren', + 'File': 'Bestand', + 'URL': 'URL', + 'Link text': 'Link tekst', + 'Add row': 'Rij toevoegen', + 'Add col': 'Kolom toevoegen', + 'Remove row': 'Rij verwijderen', + 'Remove col': 'Kolom verwijderen', + 'Align left': 'Links uitlijnen', + 'Align center': 'Centreren', + 'Align right': 'Rechts uitlijnen', + 'Remove table': 'Verwijder tabel', + 'Would you like to paste as table?': 'Wil je dit als tabel plakken?', + 'Text color': 'Tekstkleur', + 'Auto scroll enabled': 'Autoscroll ingeschakeld', + 'Auto scroll disabled': 'Autoscroll uitgeschakeld', + 'Cannot paste values ​​other than a table in the cell selection state': 'Kan geen waardes anders dan de tabel in de cell plakken', + 'Choose language': 'Kies een taal' +}); /** + * @fileoverview I18N for Dutch + * @author NHN Ent. FE Development Lab + */ + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['es', 'es_ES'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Escribir', + 'Preview': 'Vista previa', + 'Headings': 'Encabezados', + 'Paragraph': 'Párrafo', + 'Bold': 'Negrita', + 'Italic': 'Itálica', + 'Strike': 'Tachado', + 'Code': 'Código', + 'Line': 'Línea', + 'Blockquote': 'Cita', + 'Unordered list': 'Lista desordenada', + 'Ordered list': 'Lista ordenada', + 'Task': 'Tarea', + 'Indent': 'Sangría', + 'Outdent': 'Saliendo', + 'Insert link': 'Insertar enlace', + 'Insert CodeBlock': 'Insertar bloque de código', + 'Insert table': 'Insertar tabla', + 'Insert image': 'Insertar imagen', + 'Heading': 'Encabezado', + 'Image URL': 'URL de la imagen', + 'Select image file': 'Seleccionar archivo de imagen', + 'Description': 'Descripción', + 'OK': 'Aceptar', + 'More': 'Más', + 'Cancel': 'Cancelar', + 'File': 'Archivo', + 'URL': 'URL', + 'Link text': 'Texto del enlace', + 'Add row': 'Agregar fila', + 'Add col': 'Agregar columna', + 'Remove row': 'Eliminar fila', + 'Remove col': 'Eliminar columna', + 'Align left': 'Alinear a la izquierda', + 'Align center': 'Centrar', + 'Align right': 'Alinear a la derecha', + 'Remove table': 'Eliminar tabla', + 'Would you like to paste as table?': '¿Desea pegar como tabla?', + 'Text color': 'Color del texto', + 'Auto scroll enabled': 'Desplazamiento automático habilitado', + 'Auto scroll disabled': 'Desplazamiento automático deshabilitado', + 'Cannot paste values ​​other than a table in the cell selection state': 'Sólo se pueden pegar tablas en el modo de selección de celdas', + 'Choose language': 'Elegir idioma' +}); /** + * @fileoverview I18N for Spanish + * @author Enrico Lamperti + */ + +/***/ }), +/* 156 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['de', 'de_DE'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Verfassen', + 'Preview': 'Vorschau', + 'Headings': 'Überschriften', + 'Paragraph': 'Text', + 'Bold': 'Fett', + 'Italic': 'Kursiv', + 'Strike': 'Durchgestrichen', + 'Code': 'Code', + 'Line': 'Trennlinie', + 'Blockquote': 'Blocktext', + 'Unordered list': 'Aufzählung', + 'Ordered list': 'Nummerierte Aufzählung', + 'Task': 'Aufgabe', + 'Indent': 'Einrücken', + 'Outdent': 'Ausrücken', + 'Insert link': 'Link einfügen', + 'Insert CodeBlock': 'Codeblock einfügen', + 'Insert table': 'Tabelle einfügen', + 'Insert image': 'Grafik einfügen', + 'Heading': 'Titel', + 'Image URL': 'Bild URL', + 'Select image file': 'Grafik auswählen', + 'Description': 'Beschreibung', + 'OK': 'OK', + 'More': 'Mehr', + 'Cancel': 'Abbrechen', + 'File': 'Datei', + 'URL': 'URL', + 'Link text': 'Anzuzeigender Text', + 'Add row': 'Zeile hinzufügen', + 'Add col': 'Spalte hinzufügen', + 'Remove row': 'Zeile entfernen', + 'Remove col': 'Spalte entfernen', + 'Align left': 'Links ausrichten', + 'Align center': 'Zentrieren', + 'Align right': 'Rechts ausrichten', + 'Remove table': 'Tabelle entfernen', + 'Would you like to paste as table?': 'Möchten Sie eine Tabelle einfügen?', + 'Text color': 'Textfarbe', + 'Auto scroll enabled': 'Autoscrollen aktiviert', + 'Auto scroll disabled': 'Autoscrollen deaktiviert', + 'Cannot paste values ​​other than a table in the cell selection state': 'Im Zellenauswahlstatus können keine anderen Werte als eine Tabelle eingefügt werden', + 'Choose language': 'Sprache auswählen' +}); /** + * @fileoverview I18N for German + * @author Jann-Niklas Kiepert + */ + +/***/ }), +/* 157 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['ru', 'ru_RU'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Написать', + 'Preview': 'Предварительный просмотр', + 'Headings': 'Заголовки', + 'Paragraph': 'Абзац', + 'Bold': 'Жирный', + 'Italic': 'Курсив', + 'Strike': 'Зачеркнутый', + 'Code': 'Встроенный код', + 'Line': 'Строка', + 'Blockquote': 'Блок цитирования', + 'Unordered list': 'Неупорядоченный список', + 'Ordered list': 'Упорядоченный список', + 'Task': 'Задача', + 'Indent': 'отступ', + 'Outdent': 'Выступ', + 'Insert link': 'Вставить ссылку', + 'Insert CodeBlock': 'Вставить код', + 'Insert table': 'Вставить таблицу', + 'Insert image': 'Вставить изображение', + 'Heading': 'Заголовок', + 'Image URL': 'URL изображения', + 'Select image file': 'Выбрать файл изображения', + 'Description': 'Описание', + 'OK': 'Хорошо', + 'More': 'еще', + 'Cancel': 'Отмена', + 'File': 'Файл', + 'URL': 'URL', + 'Link text': 'Текст ссылки', + 'Add row': 'Добавить ряд', + 'Add col': 'Добавить столбец', + 'Remove row': 'Удалить ряд', + 'Remove col': 'Удалить столбец', + 'Align left': 'Выровнять по левому краю', + 'Align center': 'Выровнять по центру', + 'Align right': 'Выровнять по правому краю', + 'Remove table': 'Удалить таблицу', + 'Would you like to paste as table?': 'Вы хотите вставить в виде таблицы?', + 'Text color': 'Цвет текста', + 'Auto scroll enabled': 'Автоматическая прокрутка включена', + 'Auto scroll disabled': 'Автоматическая прокрутка отключена', + 'Cannot paste values ​​other than a table in the cell selection state': 'Вы не можете вставлять значения, отличные от таблицы, в состоянии выбора ячейки.', + 'Choose language': 'Выбрать язык' +}); /** + * @fileoverview I18N for Russian + * @author Stepan Samko + */ + +/***/ }), +/* 158 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['fr', 'fr_FR'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Écrire', + 'Preview': 'Aperçu', + 'Headings': 'En-têtes', + 'Paragraph': 'Paragraphe', + 'Bold': 'Gras', + 'Italic': 'Italique', + 'Strike': 'Barré', + 'Code': 'Code en ligne', + 'Line': 'Ligne', + 'Blockquote': 'Citation', + 'Unordered list': 'Liste non-ordonnée', + 'Ordered list': 'Liste ordonnée', + 'Task': 'Tâche', + 'Indent': 'Retrait', + 'Outdent': 'Sortir', + 'Insert link': 'Insérer un lien', + 'Insert CodeBlock': 'Insérer un bloc de code', + 'Insert table': 'Insérer un tableau', + 'Insert image': 'Insérer une image', + 'Heading': 'En-tête', + 'Image URL': 'URL de l\'image', + 'Select image file': 'Sélectionnez un fichier image', + 'Description': 'Description', + 'OK': 'OK', + 'More': 'de plus', + 'Cancel': 'Annuler', + 'File': 'Fichier', + 'URL': 'URL', + 'Link text': 'Texte du lien', + 'Add row': 'Ajouter une ligne', + 'Add col': 'Ajouter une colonne', + 'Remove row': 'Supprimer une ligne', + 'Remove col': 'Supprimer une colonne', + 'Align left': 'Aligner à gauche', + 'Align center': 'Aligner au centre', + 'Align right': 'Aligner à droite', + 'Remove table': 'Supprimer le tableau', + 'Would you like to paste as table?': 'Voulez-vous coller ce contenu en tant que tableau ?', + 'Text color': 'Couleur du texte', + 'Auto scroll enabled': 'Défilement automatique activé', + 'Auto scroll disabled': 'Défilement automatique désactivé', + 'Cannot paste values ​​other than a table in the cell selection state': 'Impossible de coller autre chose qu\'un tableau dans la sélection de la cellule.', + 'Choose language': 'Choix de la langue' +}); /** + * @fileoverview I18N for French + * @author Stanislas Michalak + */ + +/***/ }), +/* 159 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['uk', 'uk_UA'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Написати', + 'Preview': 'Попередній перегляд', + 'Headings': 'Заголовки', + 'Paragraph': 'Абзац', + 'Bold': 'Жирний', + 'Italic': 'Курсив', + 'Strike': 'Закреслений', + 'Code': 'Вбудований код', + 'Line': 'Лінія', + 'Blockquote': 'Блок цитування', + 'Unordered list': 'Невпорядкований список', + 'Ordered list': 'Упорядкований список', + 'Task': 'Завдання', + 'Indent': 'відступ', + 'Outdent': 'застарілий', + 'Insert link': 'Вставити посилання', + 'Insert CodeBlock': 'Вставити код', + 'Insert table': 'Вставити таблицю', + 'Insert image': 'Вставити зображення', + 'Heading': 'Заголовок', + 'Image URL': 'URL зображення', + 'Select image file': 'Вибрати файл зображення', + 'Description': 'Опис', + 'OK': 'OK', + 'More': 'ще', + 'Cancel': 'Скасувати', + 'File': 'Файл', + 'URL': 'URL', + 'Link text': 'Текст посилання', + 'Add row': 'Додати ряд', + 'Add col': 'Додати стовпчик', + 'Remove row': 'Видалити ряд', + 'Remove col': 'Видалити стовпчик', + 'Align left': 'Вирівняти по лівому краю', + 'Align center': 'Вирівняти по центру', + 'Align right': 'Вирівняти по правому краю', + 'Remove table': 'Видалити таблицю', + 'Would you like to paste as table?': 'Ви хочете вставити у вигляді таблиці?', + 'Text color': 'Колір тексту', + 'Auto scroll enabled': 'Автоматична прокрутка включена', + 'Auto scroll disabled': 'Автоматична прокрутка відключена', + 'Cannot paste values ​​other than a table in the cell selection state': 'Ви не можете вставляти значення, відмінні від таблиці, в стані вибору комірки.', + 'Choose language': 'Вибрати мову' +}); /** + * @fileoverview I18N for Ukrainian + * @author Nikolya + */ + +/***/ }), +/* 160 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['tr', 'tr_TR'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Düzenle', + 'Preview': 'Ön izleme', + 'Headings': 'Başlıklar', + 'Paragraph': 'Paragraf', + 'Bold': 'Kalın', + 'Italic': 'İtalik', + 'Strike': 'Altı çizgili', + 'Code': 'Satır içi kod', + 'Line': 'Çizgi', + 'Blockquote': 'Alıntı', + 'Unordered list': 'Sıralanmamış liste', + 'Ordered list': 'Sıralı liste', + 'Task': 'Görev kutusu', + 'Indent': 'Girintiyi arttır', + 'Outdent': 'Girintiyi azalt', + 'Insert link': 'Bağlantı ekle', + 'Insert CodeBlock': 'Kod bloku ekle', + 'Insert table': 'Tablo ekle', + 'Insert image': 'İmaj ekle', + 'Heading': 'Başlık', + 'Image URL': 'İmaj URL', + 'Select image file': 'İmaj dosyası seç', + 'Description': 'Açıklama', + 'OK': 'Onay', + 'More': 'Daha Fazla', + 'Cancel': 'İptal', + 'File': 'Dosya', + 'URL': 'URL', + 'Link text': 'Bağlantı yazısı', + 'Add row': 'Satır ekle', + 'Add col': 'Sütun ekle', + 'Remove row': 'Satır sil', + 'Remove col': 'Sütun sil', + 'Align left': 'Sola hizala', + 'Align center': 'Merkeze hizala', + 'Align right': 'Sağa hizala', + 'Remove table': 'Tabloyu kaldır', + 'Would you like to paste as table?': 'Tablo olarak yapıştırmak ister misiniz?', + 'Text color': 'Metin rengi', + 'Auto scroll enabled': 'Otomatik kaydırma açık', + 'Auto scroll disabled': 'Otomatik kaydırma kapalı', + 'Cannot paste values ​​other than a table in the cell selection state': 'Hücre seçimi sırasında tablo dışında veriler yapıştırılamaz.', + 'Choose language': 'Dil seçiniz' +}); /** + * @fileoverview I18N for Turkish + * @author Mesut Gölcük + */ + +/***/ }), +/* 161 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['fi', 'fi_FI'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Kirjoita', + 'Preview': 'Esikatselu', + 'Headings': 'Otsikot', + 'Paragraph': 'Kappale', + 'Bold': 'Lihavointi', + 'Italic': 'Kursivointi', + 'Strike': 'Yliviivaus', + 'Code': 'Koodi', + 'Line': 'Vaakaviiva', + 'Blockquote': 'Lainaus', + 'Unordered list': 'Luettelo', + 'Ordered list': 'Numeroitu luettelo', + 'Task': 'Tehtävä', + 'Indent': 'Suurenna sisennystä', + 'Outdent': 'Pienennä sisennystä', + 'Insert link': 'Lisää linkki', + 'Insert CodeBlock': 'Lisää koodia', + 'Insert table': 'Lisää taulukko', + 'Insert image': 'Lisää kuva', + 'Heading': 'Otsikko', + 'Image URL': 'Kuvan URL', + 'Select image file': 'Valitse kuvatiedosto', + 'Description': 'Kuvaus', + 'OK': 'OK', + 'More': 'Lisää', + 'Cancel': 'Peruuta', + 'File': 'Tiedosto', + 'URL': 'URL', + 'Link text': 'Linkkiteksti', + 'Add row': 'Lisää rivi', + 'Add col': 'Lisää sarake', + 'Remove row': 'Poista rivi', + 'Remove col': 'Poista sarake', + 'Align left': 'Tasaus vasemmalle', + 'Align center': 'Keskitä', + 'Align right': 'Tasaus oikealle', + 'Remove table': 'Poista taulukko', + 'Would you like to paste as table?': 'Haluatko liittää taulukkomuodossa?', + 'Text color': 'Tekstin väri', + 'Auto scroll enabled': 'Automaattinen skrollaus käytössä', + 'Auto scroll disabled': 'Automaattinen skrollaus pois käytöstä', + 'Cannot paste values other than a table in the cell selection state': 'Vain taulukko voidaan liittää solunvalintatilassa.', + 'Choose language': 'Valitse kieli' +}); /** + * @fileoverview I18N for Finnish + * @author Tomi Mynttinen + */ + +/***/ }), +/* 162 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['cs', 'cs_CZ'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Napsat', + 'Preview': 'Náhled', + 'Headings': 'Nadpisy', + 'Paragraph': 'Odstavec', + 'Bold': 'Tučné', + 'Italic': 'Kurzíva', + 'Strike': 'Přeškrtnuté', + 'Code': 'Kód', + 'Line': 'Vodorovná čára', + 'Blockquote': 'Citace', + 'Unordered list': 'Seznam s odrážkami', + 'Ordered list': 'Číslovaný seznam', + 'Task': 'Úkol', + 'Indent': 'Zvětšit odsazení', + 'Outdent': 'Zmenšit odsazení', + 'Insert link': 'Vložit odkaz', + 'Insert CodeBlock': 'Vložit blok kódu', + 'Insert table': 'Vložit tabulku', + 'Insert image': 'Vložit obrázek', + 'Heading': 'Nadpis', + 'Image URL': 'URL obrázku', + 'Select image file': 'Vybrat obrázek', + 'Description': 'Popis', + 'OK': 'OK', + 'More': 'Více', + 'Cancel': 'Zrušit', + 'File': 'Soubor', + 'URL': 'URL', + 'Link text': 'Text odkazu', + 'Add row': 'Přidat řádek', + 'Add col': 'Přidat sloupec', + 'Remove row': 'Odebrat řádek', + 'Remove col': 'Odebrat sloupec', + 'Align left': 'Zarovnat vlevo', + 'Align center': 'Zarovnat na střed', + 'Align right': 'Zarovnat vpravo', + 'Remove table': 'Odstranit tabulku', + 'Would you like to paste as table?': 'Chcete vložit jako tabulku?', + 'Text color': 'Barva textu', + 'Auto scroll enabled': 'Automatické rolování zapnuto', + 'Auto scroll disabled': 'Automatické rolování vypnuto', + 'Cannot paste values ​​other than a table in the cell selection state': 'Nelze vkládat jiné hodnoty než tabulka ve stavu výběru buněk', + 'Choose language': 'Vybrat jazyk' +}); /** + * @fileoverview I18N for Czech + * @author Dmitrij Tkačenko + */ + +/***/ }), +/* 163 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['ar', 'ar_AR'], { + 'Markdown': 'لغة ترميز', + 'WYSIWYG': 'ما تراه هو ما تحصل عليه', + 'Write': 'يكتب', + 'Preview': 'عرض مسبق', + 'Headings': 'العناوين', + 'Paragraph': 'فقرة', + 'Bold': 'خط عريض', + 'Italic': 'خط مائل', + 'Strike': 'إضراب', + 'Code': 'رمز', + 'Line': 'خط', + 'Blockquote': 'فقرة مقتبسة', + 'Unordered list': 'قائمة غير مرتبة', + 'Ordered list': 'قائمة مرتبة', + 'Task': 'مهمة', + 'Indent': 'المسافة البادئة', + 'Outdent': 'المسافة الخارجة', + 'Insert link': 'أدخل الرابط', + 'Insert CodeBlock': 'أدخل الكود', + 'Insert table': 'أدخل جدول', + 'Insert image': 'أدخل صورة', + 'Heading': 'عنوان', + 'Image URL': 'رابط الصورة', + 'Select image file': 'حدد ملف الصورة', + 'Description': 'وصف', + 'OK': 'موافقة', + 'More': 'أكثر', + 'Cancel': 'إلغاء', + 'File': 'ملف', + 'URL': 'رابط', + 'Link text': 'نص الرابط', + 'Add row': 'ضف سطر', + 'Add col': 'ضف عمود', + 'Remove row': 'حذف سطر', + 'Remove col': 'حذف عمود', + 'Align left': 'محاذاة اليسار', + 'Align center': 'محاذاة الوسط', + 'Align right': 'محاذاة اليمين', + 'Remove table': 'حذف الجدول', + 'Would you like to paste as table?': 'هل تريد اللصق كجدول', + 'Text color': 'لون النص', + 'Auto scroll enabled': 'التحريك التلقائي ممكّن', + 'Auto scroll disabled': 'التحريك التلقائي معطّل', + 'Cannot paste values ​​other than a table in the cell selection state': 'لا يمكن اللصق في الجدول إلا في وجود خلايا مختارة', + 'Choose language': 'اختر اللغة' +}); /** + * @fileoverview I18N for Arabic + * @author Amira Salah + */ + +/***/ }), +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _i18n = __webpack_require__(3); + +var _i18n2 = _interopRequireDefault(_i18n); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_i18n2.default.setLanguage(['pl', 'pl_PL'], { + 'Markdown': 'Markdown', + 'WYSIWYG': 'WYSIWYG', + 'Write': 'Napisz', + 'Preview': 'Podgląd', + 'Headings': 'Nagłówki', + 'Paragraph': 'Akapit', + 'Bold': 'Pogrubienie', + 'Italic': 'Kursywa', + 'Strike': 'Przekreślenie', + 'Code': 'Fragment kodu', + 'Line': 'Linia', + 'Blockquote': 'Cytat', + 'Unordered list': 'Lista nieuporządkowana', + 'Ordered list': 'Lista uporządkowana', + 'Task': 'Zadanie', + 'Indent': 'Utwórz wcięcie', + 'Outdent': 'Usuń wcięcie', + 'Insert link': 'Umieść odnośnik', + 'Insert CodeBlock': 'Umieść blok kodu', + 'Insert table': 'Umieść tabelę', + 'Insert image': 'Umieść obraz', + 'Heading': 'Nagłówek', + 'Image URL': 'Adres URL obrazu', + 'Select image file': 'Wybierz plik obrazu', + 'Description': 'Opis', + 'OK': 'OK', + 'More': 'Więcej', + 'Cancel': 'Anuluj', + 'File': 'Plik', + 'URL': 'URL', + 'Link text': 'Tekst odnośnika', + 'Add row': 'Dodaj rząd', + 'Add col': 'Dodaj kolumnę', + 'Remove row': 'Usuń rząd', + 'Remove col': 'Usuń kolumnę', + 'Align left': 'Wyrównaj do lewej', + 'Align center': 'Wyśrodkuj', + 'Align right': 'Wyrównaj do prawej', + 'Remove table': 'Usuń tabelę', + 'Would you like to paste as table?': 'Czy chcesz wkleić tekst jako tabelę?', + 'Text color': 'Kolor tekstu', + 'Auto scroll enabled': 'Włączono automatyczne przewijanie', + 'Auto scroll disabled': 'Wyłączono automatyczne przewijanie', + 'Cannot paste values ​​other than a table in the cell selection state': 'Nie można wkleić wartości innej niż tabela w trybie wyboru komórki.', + 'Choose language': 'Wybierz język' +}); /** + * @fileoverview I18N for Polish + * @author Marcin Mikołajczak + */ + +/***/ }), +/* 165 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +/* eslint-disable */ +/* + CSV-JS - A Comma-Separated Values parser for JS + + Built to rfc4180 standard, with options for adjusting strictness: + - optional carriage returns for non-microsoft sources + - automatically type-cast numeric an boolean values + - relaxed mode which: ignores blank lines, ignores gargabe following quoted tokens, does not enforce a consistent record length + + Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php + + 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. + + Author Greg Kindel (twitter @gkindel), 2014 + */ +/** + * @modifier NHN Ent. FE Development Lab + */ + +(function (global) { + 'use strict'; + /** + * @name CSV + * @namespace + * @ignore + */ + // implemented as a singleton because JS is single threaded + + var CSV = {}; + CSV.RELAXED = false; + CSV.IGNORE_RECORD_LENGTH = false; + CSV.IGNORE_QUOTES = false; + CSV.LINE_FEED_OK = true; + CSV.CARRIAGE_RETURN_OK = true; + CSV.DETECT_TYPES = true; + CSV.IGNORE_QUOTE_WHITESPACE = true; + CSV.DEBUG = false; + + CSV.COLUMN_SEPARATOR = ","; + + CSV.ERROR_EOF = "UNEXPECTED_END_OF_FILE"; + CSV.ERROR_CHAR = "UNEXPECTED_CHARACTER"; + CSV.ERROR_EOL = "UNEXPECTED_END_OF_RECORD"; + CSV.WARN_SPACE = "UNEXPECTED_WHITESPACE"; // not per spec, but helps debugging + + var QUOTE = "\"", + CR = "\r", + LF = "\n", + SPACE = " ", + TAB = "\t"; + + // states + var PRE_TOKEN = 0, + MID_TOKEN = 1, + POST_TOKEN = 2, + POST_RECORD = 4; + /** + * @name CSV.parse + * @function + * @description rfc4180 standard csv parse + * with options for strictness and data type conversion + * By default, will automatically type-cast numeric an boolean values. + * @param {String} str A CSV string + * @return {Array} An array records, each of which is an array of scalar values. + * @example + * // simple + * var rows = CSV.parse("one,two,three\nfour,five,six") + * // rows equals [["one","two","three"],["four","five","six"]] + * @example + * // Though not a jQuery plugin, it is recommended to use with the $.ajax pipe() method: + * $.get("csv.txt") + * .pipe( CSV.parse ) + * .done( function(rows) { + * for( var i =0; i < rows.length; i++){ + * console.log(rows[i]) + * } + * }); + * @see http://www.ietf.org/rfc/rfc4180.txt + */ + CSV.parse = function (str) { + var result = CSV.result = []; + CSV.COLUMN_SEPARATOR = CSV.COLUMN_SEPARATOR instanceof RegExp ? new RegExp('^' + CSV.COLUMN_SEPARATOR.source) : CSV.COLUMN_SEPARATOR; + + CSV.offset = 0; + CSV.str = str; + CSV.record_begin(); + + CSV.debug("parse()", str); + + var c; + while (1) { + // pull char + c = str[CSV.offset++]; + CSV.debug("c", c); + + // detect eof + if (c == null) { + if (CSV.escaped) { + CSV.error(CSV.ERROR_EOF); + } + + if (CSV.record) { + CSV.token_end(); + CSV.record_end(); + } + + CSV.debug("...bail", c, CSV.state, CSV.record); + CSV.reset(); + break; + } + + if (CSV.record == null) { + // if relaxed mode, ignore blank lines + if (CSV.RELAXED && (c == LF || c == CR && str[CSV.offset + 1] == LF)) { + continue; + } + CSV.record_begin(); + } + + // pre-token: look for start of escape sequence + if (CSV.state == PRE_TOKEN) { + + if ((c === SPACE || c === TAB) && CSV.next_nonspace() == QUOTE) { + if (CSV.RELAXED || CSV.IGNORE_QUOTE_WHITESPACE) { + continue; + } else { + // not technically an error, but ambiguous and hard to debug otherwise + CSV.warn(CSV.WARN_SPACE); + } + } + + if (c == QUOTE && !CSV.IGNORE_QUOTES) { + CSV.debug("...escaped start", c); + CSV.escaped = true; + CSV.state = MID_TOKEN; + continue; + } + CSV.state = MID_TOKEN; + } + + // mid-token and escaped, look for sequences and end quote + if (CSV.state == MID_TOKEN && CSV.escaped) { + if (c == QUOTE) { + if (str[CSV.offset] == QUOTE) { + CSV.debug("...escaped quote", c); + CSV.token += QUOTE; + CSV.offset++; + } else { + CSV.debug("...escaped end", c); + CSV.escaped = false; + CSV.state = POST_TOKEN; + } + } else { + CSV.token += c; + CSV.debug("...escaped add", c, CSV.token); + } + continue; + } + + // fall-through: mid-token or post-token, not escaped + if (c == CR) { + if (str[CSV.offset] == LF) CSV.offset++;else if (!CSV.CARRIAGE_RETURN_OK) CSV.error(CSV.ERROR_CHAR); + CSV.token_end(); + CSV.record_end(); + } else if (c == LF) { + if (!(CSV.LINE_FEED_OK || CSV.RELAXED)) CSV.error(CSV.ERROR_CHAR); + CSV.token_end(); + CSV.record_end(); + } else if (CSV.test_regex_separator(str) || CSV.COLUMN_SEPARATOR == c) { + CSV.token_end(); + } else if (CSV.state == MID_TOKEN) { + CSV.token += c; + CSV.debug("...add", c, CSV.token); + } else if (c === SPACE || c === TAB) { + if (!CSV.IGNORE_QUOTE_WHITESPACE) CSV.error(CSV.WARN_SPACE); + } else if (!CSV.RELAXED) { + CSV.error(CSV.ERROR_CHAR); + } + } + return result; + }; + + /** + * @name CSV.stream + * @function + * @description stream a CSV file + * @example + * node -e "c=require('CSV-JS');require('fs').createReadStream('csv.txt').pipe(c.stream()).pipe(c.stream.json()).pipe(process.stdout)" + * @ignore + */ + CSV.stream = function () { + var stream = __webpack_require__(47); + var s = new stream.Transform({ objectMode: true }); + s.EOL = '\n'; + s.prior = ""; + s.emitter = function (s) { + return function (e) { + s.push(CSV.parse(e + s.EOL)); + }; + }(s); + + s._transform = function (chunk, encoding, done) { + var lines = this.prior == "" ? chunk.toString().split(this.EOL) : (this.prior + chunk.toString()).split(this.EOL); + this.prior = lines.pop(); + lines.forEach(this.emitter); + done(); + }; + + s._flush = function (done) { + if (this.prior != "") { + this.emitter(this.prior); + this.prior = ""; + } + done(); + }; + return s; + }; + + CSV.test_regex_separator = function (str) { + if (!(CSV.COLUMN_SEPARATOR instanceof RegExp)) { + return false; + } + + var match; + str = str.slice(CSV.offset - 1); + match = CSV.COLUMN_SEPARATOR.exec(str); + if (match) { + CSV.offset += match[0].length - 1; + } + + return match !== null; + }; + + CSV.stream.json = function () { + var os = __webpack_require__(178); + var stream = __webpack_require__(47); + var s = new streamTransform({ objectMode: true }); + s._transform = function (chunk, encoding, done) { + s.push(JSON.stringify(chunk.toString()) + os.EOL); + done(); + }; + return s; + }; + + CSV.reset = function () { + CSV.state = null; + CSV.token = null; + CSV.escaped = null; + CSV.record = null; + CSV.offset = null; + CSV.result = null; + CSV.str = null; + }; + + CSV.next_nonspace = function () { + var i = CSV.offset; + var c; + while (i < CSV.str.length) { + c = CSV.str[i++]; + if (!(c == SPACE || c === TAB)) { + return c; + } + } + return null; + }; + + CSV.record_begin = function () { + CSV.escaped = false; + CSV.record = []; + CSV.token_begin(); + CSV.debug("record_begin"); + }; + + CSV.record_end = function () { + CSV.state = POST_RECORD; + if (!(CSV.IGNORE_RECORD_LENGTH || CSV.RELAXED) && CSV.result.length > 0 && CSV.record.length != CSV.result[0].length) { + CSV.error(CSV.ERROR_EOL); + } + CSV.result.push(CSV.record); + CSV.debug("record end", CSV.record); + CSV.record = null; + }; + + CSV.resolve_type = function (token) { + if (token.match(/^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/)) { + token = parseFloat(token); + } else if (token.match(/^(true|false)$/i)) { + token = Boolean(token.match(/true/i)); + } else if (token === "undefined") { + token = undefined; + } else if (token === "null") { + token = null; + } + return token; + }; + + CSV.token_begin = function () { + CSV.state = PRE_TOKEN; + // considered using array, but http://www.sitepen.com/blog/2008/05/09/string-performance-an-analysis/ + CSV.token = ""; + }; + + CSV.token_end = function () { + if (CSV.DETECT_TYPES) { + CSV.token = CSV.resolve_type(CSV.token); + } + CSV.record.push(CSV.token); + CSV.debug("token end", CSV.token); + CSV.token_begin(); + }; + + CSV.debug = function () { + if (CSV.DEBUG) console.log(arguments); + }; + + CSV.dump = function (msg) { + return [msg, "at char", CSV.offset, ":", CSV.str.substr(CSV.offset - 50, 50).replace(/\r/mg, "\\r").replace(/\n/mg, "\\n").replace(/\t/mg, "\\t")].join(" "); + }; + + CSV.error = function (err) { + var msg = CSV.dump(err); + CSV.reset(); + throw msg; + }; + + CSV.warn = function (err) { + if (!CSV.DEBUG) { + return; + } + + var msg = CSV.dump(err); + try { + console.warn(msg); + return; + } catch (e) {} + + try { + console.log(msg); + } catch (e) {} + }; + + // Node, PhantomJS, etc + // eg. var CSV = require("CSV"); CSV.parse(...); + if (typeof module != 'undefined' && module.exports) { + module.exports = CSV; + } + + // CommonJS http://wiki.commonjs.org/wiki/Modules + // eg. var CSV = require("CSV").CSV; CSV.parse(...); + else if (true) { + exports.CSV = CSV; + } + + // AMD https://github.com/amdjs/amdjs-api/wiki/AMD + // eg. require(['./csv.js'], function (CSV) { CSV.parse(...); } ); + else if (typeof define == 'function' && _typeof(define.amd) == 'object') { + define([], function () { + return CSV; + }); + } + + // standard js global + // eg. CSV.parse(...); + else if (global) { + global.CSV = CSV; + } +})(undefined); + +/***/ }), +/* 166 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function placeHoldersCount (b64) { + var len = b64.length + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 +} + +function byteLength (b64) { + // base64 is 4/3 + up to two characters of the original data + return (b64.length * 3 / 4) - placeHoldersCount(b64) +} + +function toByteArray (b64) { + var i, l, tmp, placeHolders, arr + var len = b64.length + placeHolders = placeHoldersCount(b64) + + arr = new Arr((len * 3 / 4) - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len + + var L = 0 + + for (i = 0; i < l; i += 4) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] + arr[L++] = (tmp >> 16) & 0xFF + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[L++] = tmp & 0xFF + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var output = '' + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + output += lookup[tmp >> 2] + output += lookup[(tmp << 4) & 0x3F] + output += '==' + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) + output += lookup[tmp >> 10] + output += lookup[(tmp >> 4) & 0x3F] + output += lookup[(tmp << 2) & 0x3F] + output += '=' + } + + parts.push(output) + + return parts.join('') +} + + +/***/ }), +/* 167 */ +/***/ (function(module, exports) { + +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + + +/***/ }), +/* 168 */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), +/* 169 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/**/ + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Buffer = __webpack_require__(20).Buffer; +/**/ + +function copyBuffer(src, target, offset) { + src.copy(target, offset); +} + +module.exports = function () { + function BufferList() { + _classCallCheck(this, BufferList); + + this.head = null; + this.tail = null; + this.length = 0; + } + + BufferList.prototype.push = function push(v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + }; + + BufferList.prototype.unshift = function unshift(v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + }; + + BufferList.prototype.shift = function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + }; + + BufferList.prototype.clear = function clear() { + this.head = this.tail = null; + this.length = 0; + }; + + BufferList.prototype.join = function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; + }; + + BufferList.prototype.concat = function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + if (this.length === 1) return this.head.data; + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + return ret; + }; + + return BufferList; +}(); + +/***/ }), +/* 170 */ +/***/ (function(module, exports, __webpack_require__) { + +var apply = Function.prototype.apply; + +// DOM APIs, for completeness + +exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); +}; +exports.setInterval = function() { + return new Timeout(apply.call(setInterval, window, arguments), clearInterval); +}; +exports.clearTimeout = +exports.clearInterval = function(timeout) { + if (timeout) { + timeout.close(); + } +}; + +function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; +} +Timeout.prototype.unref = Timeout.prototype.ref = function() {}; +Timeout.prototype.close = function() { + this._clearFn.call(window, this._id); +}; + +// Does not start the time, just sets up the members needed. +exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; +}; + +exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; +}; + +exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } +}; + +// setimmediate attaches itself to the global object +__webpack_require__(171); +exports.setImmediate = setImmediate; +exports.clearImmediate = clearImmediate; + + +/***/ }), +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { + "use strict"; + + if (global.setImmediate) { + return; + } + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + var doc = global.document; + var registerImmediate; + + function setImmediate(callback) { + // Callback can either be a function or a string + if (typeof callback !== "function") { + callback = new Function("" + callback); + } + // Copy function arguments + var args = new Array(arguments.length - 1); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i + 1]; + } + // Store and register the task + var task = { callback: callback, args: args }; + tasksByHandle[nextHandle] = task; + registerImmediate(nextHandle); + return nextHandle++; + } + + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function run(task) { + var callback = task.callback; + var args = task.args; + switch (args.length) { + case 0: + callback(); + break; + case 1: + callback(args[0]); + break; + case 2: + callback(args[0], args[1]); + break; + case 3: + callback(args[0], args[1], args[2]); + break; + default: + callback.apply(undefined, args); + break; + } + } + + function runIfPresent(handle) { + // From the spec: "Wait until any invocations of this algorithm started before this one have completed." + // So if we're currently running a task, we'll need to delay this invocation. + if (currentlyRunningATask) { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // "too much recursion" error. + setTimeout(runIfPresent, 0, handle); + } else { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + run(task); + } finally { + clearImmediate(handle); + currentlyRunningATask = false; + } + } + } + } + + function installNextTickImplementation() { + registerImmediate = function(handle) { + process.nextTick(function () { runIfPresent(handle); }); + }; + } + + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + var oldOnMessage = global.onmessage; + global.onmessage = function() { + postMessageIsAsynchronous = false; + }; + global.postMessage("", "*"); + global.onmessage = oldOnMessage; + return postMessageIsAsynchronous; + } + } + + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages + + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + runIfPresent(+event.data.slice(messagePrefix.length)); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); + } + + registerImmediate = function(handle) { + global.postMessage(messagePrefix + handle, "*"); + }; + } + + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + var handle = event.data; + runIfPresent(handle); + }; + + registerImmediate = function(handle) { + channel.port2.postMessage(handle); + }; + } + + function installReadyStateChangeImplementation() { + var html = doc.documentElement; + registerImmediate = function(handle) { + // Create a