diff --git a/.gitignore b/.gitignore index 896e2e9d85..6a0c21d66f 100644 --- a/.gitignore +++ b/.gitignore @@ -101,7 +101,7 @@ preserve.belle /tests/Umbraco.Tests.UnitTests/[Uu]mbraco/[Dd]ata/TEMP/ # Ignore auto-generated schema -/src/Umbraco.Cms.Targets/appsettings-schema.json +/src/Umbraco.Cms.Targets/tasks/ /src/Umbraco.Cms.Targets/appsettings-schema.*.json /src/Umbraco.Web.UI/appsettings-schema.json /src/Umbraco.Web.UI/appsettings-schema.*.json diff --git a/Directory.Build.props b/Directory.Build.props index dd6f8126b1..37b2e66977 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ net7.0 - preview + latest Umbraco HQ Umbraco Copyright © Umbraco $([System.DateTime]::Today.ToString('yyyy')) @@ -41,7 +41,7 @@ - + diff --git a/src/JsonSchema/AppSettings.cs b/src/JsonSchema/AppSettings.cs deleted file mode 100644 index f9c7c224be..0000000000 --- a/src/JsonSchema/AppSettings.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using Umbraco.Cms.Core.Configuration; -using Umbraco.Cms.Core.Configuration.Models; - -namespace JsonSchema; - -internal class AppSettings -{ - // ReSharper disable once InconsistentNaming - public CmsDefinition? CMS { get; set; } - - /// - /// Configurations for the Umbraco CMS - /// - public class CmsDefinition - { - public ContentSettings? Content { get; set; } - - public CoreDebugSettings? Debug { get; set; } - - public ExceptionFilterSettings? ExceptionFilter { get; set; } - - public ModelsBuilderSettings? ModelsBuilder { get; set; } - - public GlobalSettings? Global { get; set; } - - public HealthChecksSettings? HealthChecks { get; set; } - - public HostingSettings? Hosting { get; set; } - - public ImagingSettings? Imaging { get; set; } - - public IndexCreatorSettings? Examine { get; set; } - - public KeepAliveSettings? KeepAlive { get; set; } - - public LoggingSettings? Logging { get; set; } - - public NuCacheSettings? NuCache { get; set; } - - public RequestHandlerSettings? RequestHandler { get; set; } - - public RuntimeSettings? Runtime { get; set; } - - public SecuritySettings? Security { get; set; } - - public TourSettings? Tours { get; set; } - - public TypeFinderSettings? TypeFinder { get; set; } - - public WebRoutingSettings? WebRouting { get; set; } - - public UmbracoPluginSettings? Plugins { get; set; } - - public UnattendedSettings? Unattended { get; set; } - - public RichTextEditorSettings? RichTextEditor { get; set; } - - public RuntimeMinificationSettings? RuntimeMinification { get; set; } - - public BasicAuthSettings? BasicAuth { get; set; } - - public PackageMigrationSettings? PackageMigration { get; set; } - - public LegacyPasswordMigrationSettings? LegacyPasswordMigration { get; set; } - - public ContentDashboardSettings? ContentDashboard { get; set; } - - public HelpPageSettings? HelpPage { get; set; } - - public InstallDefaultDataSettings? DefaultDataCreation { get; set; } - - public DataTypesSettings? DataTypes { get; set; } - - public LicensesSettings? Licenses { get; set; } - } -} diff --git a/src/JsonSchema/NamespacePrefixedSchemaNameGenerator.cs b/src/JsonSchema/NamespacePrefixedSchemaNameGenerator.cs deleted file mode 100644 index 137dd551cf..0000000000 --- a/src/JsonSchema/NamespacePrefixedSchemaNameGenerator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using System; -using NJsonSchema.Generation; - -namespace JsonSchema -{ - internal class NamespacePrefixedSchemaNameGenerator : DefaultSchemaNameGenerator - { - public override string Generate(Type type) => type.Namespace?.Replace(".", string.Empty) + base.Generate(type); - } -} diff --git a/src/JsonSchema/Options.cs b/src/JsonSchema/Options.cs deleted file mode 100644 index 7f4ed511a9..0000000000 --- a/src/JsonSchema/Options.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using CommandLine; - -namespace JsonSchema -{ - internal class Options - { - [Option('m', "mainOutputFile", Required = false, HelpText = "Set path of the main output file.", Default = "../../../../Umbraco.Web.UI/appsettings-schema.json")] - public string MainOutputFile { get; set; } = null!; - - [Option('f', "cmsOutputFile", Required = false, HelpText = "Set path of the cms output file.", Default = "../../../../Umbraco.Web.UI/appsettings-schema.umbraco.json")] - public string CmsOutputFile { get; set; } = null!; - } -} diff --git a/src/JsonSchema/Program.cs b/src/JsonSchema/Program.cs deleted file mode 100644 index 12246ceecb..0000000000 --- a/src/JsonSchema/Program.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using System; -using System.IO; -using System.Threading.Tasks; -using CommandLine; - -namespace JsonSchema -{ - internal class Program - { - public static async Task Main(string[] args) - { - try - { - await Parser.Default.ParseArguments(args) - .WithParsedAsync(Execute); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - private static async Task Execute(Options options) - { - var generator = new UmbracoJsonSchemaGenerator(); - - var cmsSchema = await generator.GenerateCmsFile(); - await WriteSchemaToFile(cmsSchema, options.CmsOutputFile); - - var schema = await generator.GenerateMainFile(); - await WriteSchemaToFile(schema, options.MainOutputFile); - } - - private static async Task WriteSchemaToFile(string schema, string filePath) - { - var mainPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, filePath)); - Console.WriteLine("Path to use {0}", mainPath); - Directory.CreateDirectory(Path.GetDirectoryName(mainPath)!); - Console.WriteLine("Ensured directory exists"); - await File.WriteAllTextAsync(mainPath, schema); - - Console.WriteLine("File written at {0}", mainPath); - } - } -} diff --git a/src/JsonSchema/UmbracoJsonSchemaGenerator.cs b/src/JsonSchema/UmbracoJsonSchemaGenerator.cs deleted file mode 100644 index eeec48bcd7..0000000000 --- a/src/JsonSchema/UmbracoJsonSchemaGenerator.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using Microsoft.Extensions.FileProviders; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using NJsonSchema.Generation; -using Umbraco.Cms.Core.Configuration.Models; - -namespace JsonSchema; - -/// -/// Generator of the JsonSchema for AppSettings.json including A specific Umbraco version. -/// -public class UmbracoJsonSchemaGenerator -{ - private static readonly HttpClient s_client = new(); - private readonly JsonSchemaGenerator _innerGenerator; - - /// - /// Initializes a new instance of the class. - /// - public UmbracoJsonSchemaGenerator() - => _innerGenerator = new JsonSchemaGenerator(new UmbracoJsonSchemaGeneratorSettings()); - - /// - /// Generates a json representing the JsonSchema for AppSettings.json including A specific Umbraco version.. - /// - public async Task GenerateMainFile() - { - JObject officialSchema = await GetOfficialAppSettingsSchema(); - JObject externalFilePoints = GenerateSchemaWithExternalDefinitions(); - - officialSchema.Merge(externalFilePoints); - - return officialSchema.ToString(); - } - - - /// - /// Generates the CMS file - /// - /// - public Task GenerateCmsFile() - { - JObject cmsSchema = GenerateUmbracoSchema(); - - return Task.FromResult(cmsSchema.ToString()); - } - - - - private JObject GenerateSchemaWithExternalDefinitions() - { - var fileProvider = new EmbeddedFileProvider(GetType().Assembly); - - IFileInfo schema = fileProvider.GetFileInfo("appsettings-schema.json"); - - using (Stream? stream = schema.CreateReadStream()) - using (var reader = new StreamReader(stream)) - { - return JsonConvert.DeserializeObject(reader.ReadToEnd())!; - } - } - - private async Task GetOfficialAppSettingsSchema() - { - HttpResponseMessage response = await s_client.GetAsync("https://json.schemastore.org/appsettings.json") - .ConfigureAwait(false); - - var result = await response.Content.ReadAsStringAsync(); - - return JsonConvert.DeserializeObject(result)!; - } - - private JObject GenerateUmbracoSchema() - { - NJsonSchema.JsonSchema schema = _innerGenerator.Generate(typeof(AppSettings)); - - // TODO: when the "UmbracoPath" setter is removed from "GlobalSettings" (scheduled for V12), remove this line as well - schema.Definitions["UmbracoCmsCoreConfigurationModelsGlobalSettings"]?.Properties?.Remove(nameof(GlobalSettings.UmbracoPath));return JsonConvert.DeserializeObject(schema.ToJson())!; - } -} diff --git a/src/JsonSchema/UmbracoJsonSchemaGeneratorSettings.cs b/src/JsonSchema/UmbracoJsonSchemaGeneratorSettings.cs deleted file mode 100644 index 46625aeb2c..0000000000 --- a/src/JsonSchema/UmbracoJsonSchemaGeneratorSettings.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using NJsonSchema.Generation; - -namespace JsonSchema -{ - /// - public class UmbracoJsonSchemaGeneratorSettings : JsonSchemaGeneratorSettings - { - /// - /// Initializes a new instance of the class. - /// - public UmbracoJsonSchemaGeneratorSettings() - { - AlwaysAllowAdditionalObjectProperties = true; - SerializerSettings = new JsonSerializerSettings() - { - ContractResolver = new WritablePropertiesOnlyResolver() - }; - DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull; - SchemaNameGenerator = new NamespacePrefixedSchemaNameGenerator(); - SerializerSettings.Converters.Add(new StringEnumConverter()); - IgnoreObsoleteProperties = true; - GenerateExamples = true; - } - - private class WritablePropertiesOnlyResolver : DefaultContractResolver - { - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - IList props = base.CreateProperties(type, memberSerialization); - return props.Where(p => p.Writable).ToList(); - } - } - } -} diff --git a/src/JsonSchema/appsettings-schema.json b/src/JsonSchema/appsettings-schema.json deleted file mode 100644 index 44b006b853..0000000000 --- a/src/JsonSchema/appsettings-schema.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "properties": { - "Umbraco": { - "description": "The container of all Umbraco content", - "oneOf": [ - { - "type": "null" - }, - { - "properties": { - "CMS": { - "description": "Configuration of Umbraco CMS", - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "appsettings-schema.Umbraco.Cms.json#/definitions/JsonSchemaCmsDefinition" - } - ] - }, - "Forms": { - "description": "Configuration of Umbraco Forms", - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "appsettings-schema.Umbraco.Forms.json#/definitions/JsonSchemaFormsDefinition" - } - ] - }, - "Deploy": { - "description": "Configuration of Umbraco Deploy", - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "appsettings-schema.Umbraco.Deploy.json#/definitions/JsonSchemaDeployDefinition" - } - ] - }, - "Workflow": { - "description": "Configuration of Umbraco Workflow", - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "appsettings-schema.Umbraco.Workflow.json#/definitions/JsonSchemaWorkflowDefinition" - } - ] - } - } - } - ] - } - } -} diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexListExamineController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/AllIndexerController.cs similarity index 82% rename from src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexListExamineController.cs rename to src/Umbraco.Cms.ManagementApi/Controllers/Indexer/AllIndexerController.cs index 7fdad56404..0f3769d175 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexListExamineController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/AllIndexerController.cs @@ -6,15 +6,15 @@ using Umbraco.Cms.ManagementApi.ViewModels.Pagination; using Umbraco.Cms.ManagementApi.ViewModels.Search; using Umbraco.Extensions; -namespace Umbraco.Cms.ManagementApi.Controllers.Search; +namespace Umbraco.Cms.ManagementApi.Controllers.Indexer; [ApiVersion("1.0")] -public class IndexListSearchController : SearchControllerBase +public class AllIndexerController : IndexerControllerBase { private readonly IExamineManager _examineManager; private readonly IIndexViewModelFactory _indexViewModelFactory; - public IndexListSearchController( + public AllIndexerController( IExamineManager examineManager, IIndexViewModelFactory indexViewModelFactory) { @@ -26,10 +26,10 @@ public class IndexListSearchController : SearchControllerBase /// Get the details for indexers /// /// - [HttpGet("index")] + [HttpGet] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] - public Task> Indexes(int skip, int take) + public Task> All(int skip, int take) { IndexViewModel[] indexes = _examineManager.Indexes .Select(_indexViewModelFactory.Create) diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexDetailsExamineController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/DetailsIndexerController.cs similarity index 85% rename from src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexDetailsExamineController.cs rename to src/Umbraco.Cms.ManagementApi/Controllers/Indexer/DetailsIndexerController.cs index b8759e478b..c17c77390b 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexDetailsExamineController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/DetailsIndexerController.cs @@ -4,15 +4,15 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.ManagementApi.Factories; using Umbraco.Cms.ManagementApi.ViewModels.Search; -namespace Umbraco.Cms.ManagementApi.Controllers.Search; +namespace Umbraco.Cms.ManagementApi.Controllers.Indexer; [ApiVersion("1.0")] -public class IndexDetailsSearchController : SearchControllerBase +public class DetailsIndexerController : IndexerControllerBase { private readonly IIndexViewModelFactory _indexViewModelFactory; private readonly IExamineManager _examineManager; - public IndexDetailsSearchController( + public DetailsIndexerController( IIndexViewModelFactory indexViewModelFactory, IExamineManager examineManager) { @@ -29,11 +29,11 @@ public class IndexDetailsSearchController : SearchControllerBase /// This is kind of rudimentary since there's no way we can know that the index has rebuilt, we /// have a listener for the index op complete so we'll just check if that key is no longer there in the runtime cache /// - [HttpGet("index/{indexName}")] + [HttpGet("{indexName}")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(IndexViewModel), StatusCodes.Status200OK)] - public async Task> Index(string indexName) + public async Task> Details(string indexName) { if (_examineManager.TryGetIndex(indexName, out IIndex? index)) { diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/IndexerControllerBase.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/IndexerControllerBase.cs new file mode 100644 index 0000000000..183d99a718 --- /dev/null +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/IndexerControllerBase.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; +using Umbraco.New.Cms.Web.Common.Routing; + +namespace Umbraco.Cms.ManagementApi.Controllers.Indexer; + +[ApiController] +[VersionedApiBackOfficeRoute("indexer")] +[ApiExplorerSettings(GroupName = "Indexer")] +public class IndexerControllerBase : ManagementApiControllerBase +{ +} diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexRebuildSearchController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/RebuildIndexerController.cs similarity index 88% rename from src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexRebuildSearchController.cs rename to src/Umbraco.Cms.ManagementApi/Controllers/Indexer/RebuildIndexerController.cs index 825014540d..f4bbb0dac5 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/IndexRebuildSearchController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Indexer/RebuildIndexerController.cs @@ -5,17 +5,17 @@ using Microsoft.Extensions.Logging; using Umbraco.Cms.Infrastructure.Examine; using Umbraco.New.Cms.Infrastructure.Services; -namespace Umbraco.Cms.ManagementApi.Controllers.Search; +namespace Umbraco.Cms.ManagementApi.Controllers.Indexer; [ApiVersion("1.0")] -public class IndexRebuildSearchController : SearchControllerBase +public class RebuildIndexerController : IndexerControllerBase { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IIndexingRebuilderService _indexingRebuilderService; private readonly IExamineManager _examineManager; - public IndexRebuildSearchController( - ILogger logger, + public RebuildIndexerController( + ILogger logger, IIndexingRebuilderService indexingRebuilderService, IExamineManager examineManager) { @@ -29,7 +29,7 @@ public class IndexRebuildSearchController : SearchControllerBase /// /// /// - [HttpPost("index/{indexName}/rebuild")] + [HttpPost("{indexName}/rebuild")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OkResult), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearchControllerBase.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearchControllerBase.cs deleted file mode 100644 index 9d3befc022..0000000000 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearchControllerBase.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Umbraco.New.Cms.Web.Common.Routing; - -namespace Umbraco.Cms.ManagementApi.Controllers.Search; - -[ApiController] -[VersionedApiBackOfficeRoute("search")] -[ApiExplorerSettings(GroupName = "Search")] -public class SearchControllerBase : ManagementApiControllerBase -{ -} diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherListSearchController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/AllSearcherController.cs similarity index 79% rename from src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherListSearchController.cs rename to src/Umbraco.Cms.ManagementApi/Controllers/Searcher/AllSearcherController.cs index 344a905eb9..e003dcb37d 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherListSearchController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/AllSearcherController.cs @@ -5,23 +5,23 @@ using Umbraco.Cms.ManagementApi.ViewModels.Pagination; using Umbraco.Cms.ManagementApi.ViewModels.Search; using Umbraco.Extensions; -namespace Umbraco.Cms.ManagementApi.Controllers.Search; +namespace Umbraco.Cms.ManagementApi.Controllers.Searcher; [ApiVersion("1.0")] -public class SearcherListSearchController : SearchControllerBase +public class AllSearcherController : SearcherControllerBase { private readonly IExamineManager _examineManager; - public SearcherListSearchController(IExamineManager examineManager) => _examineManager = examineManager; + public AllSearcherController(IExamineManager examineManager) => _examineManager = examineManager; /// /// Get the details for searchers /// /// - [HttpGet("searcher")] + [HttpGet] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] - public async Task>> Searchers(int skip, int take) + public async Task>> All(int skip, int take) { var searchers = new List( _examineManager.RegisteredSearchers.Select(searcher => new SearcherViewModel { Name = searcher.Name }) diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherSearchSearchController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/QuerySearcherController.cs similarity index 83% rename from src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherSearchSearchController.cs rename to src/Umbraco.Cms.ManagementApi/Controllers/Searcher/QuerySearcherController.cs index 3b9f7f6f85..971bc979f2 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/Search/SearcherSearchSearchController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/QuerySearcherController.cs @@ -8,24 +8,24 @@ using Umbraco.Cms.ManagementApi.ViewModels.Pagination; using Umbraco.Cms.ManagementApi.ViewModels.Search; using Umbraco.Extensions; -namespace Umbraco.Cms.ManagementApi.Controllers.Search; +namespace Umbraco.Cms.ManagementApi.Controllers.Searcher; [ApiVersion("1.0")] -public class SearcherSearchSearchController : SearchControllerBase +public class QuerySearcherController : SearcherControllerBase { private readonly IExamineManagerService _examineManagerService; - public SearcherSearchSearchController(IExamineManagerService examineManagerService) => _examineManagerService = examineManagerService; + public QuerySearcherController(IExamineManagerService examineManagerService) => _examineManagerService = examineManagerService; - [HttpGet("searcher/{searcherName}/search")] + [HttpGet("{searcherName}/query")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] - public async Task>> GetSearchResults(string searcherName, string? query, int skip, int take) + public async Task>> Query(string searcherName, string? term, int skip, int take) { - query = query?.Trim(); + term = term?.Trim(); - if (query.IsNullOrWhiteSpace()) + if (term.IsNullOrWhiteSpace()) { return new PagedViewModel(); } @@ -50,7 +50,7 @@ public class SearcherSearchSearchController : SearchControllerBase { results = searcher .CreateQuery() - .NativeQuery(query) + .NativeQuery(term) .Execute(QueryOptions.SkipTake(skip, take)); } catch (ParseException) diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/SearcherControllerBase.cs b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/SearcherControllerBase.cs new file mode 100644 index 0000000000..309591e6af --- /dev/null +++ b/src/Umbraco.Cms.ManagementApi/Controllers/Searcher/SearcherControllerBase.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; +using Umbraco.New.Cms.Web.Common.Routing; + +namespace Umbraco.Cms.ManagementApi.Controllers.Searcher; + +[ApiController] +[VersionedApiBackOfficeRoute("searcher")] +[ApiExplorerSettings(GroupName = "Searcher")] +public class SearcherControllerBase : ManagementApiControllerBase +{ +} diff --git a/src/Umbraco.Cms.ManagementApi/ManagementApiComposer.cs b/src/Umbraco.Cms.ManagementApi/ManagementApiComposer.cs index 43949c62ae..f11290e76e 100644 --- a/src/Umbraco.Cms.ManagementApi/ManagementApiComposer.cs +++ b/src/Umbraco.Cms.ManagementApi/ManagementApiComposer.cs @@ -61,6 +61,18 @@ public class ManagementApiComposer : IComposer { swaggerGenOptions.CustomOperationIds(e => { + var httpMethod = e.HttpMethod?.ToLower().ToFirstUpper() ?? "Get"; + + // if the route info "Name" is supplied we'll use this explicitly as the operation ID + // - usage example: [HttpGet("my-api/route}", Name = "MyCustomRoute")] + if (string.IsNullOrWhiteSpace(e.ActionDescriptor.AttributeRouteInfo?.Name) == false) + { + var explicitOperationId = e.ActionDescriptor.AttributeRouteInfo!.Name; + return explicitOperationId.InvariantStartsWith(httpMethod) + ? explicitOperationId + : $"{httpMethod}{explicitOperationId}"; + } + var relativePath = e.RelativePath; if (string.IsNullOrWhiteSpace(relativePath)) @@ -68,8 +80,6 @@ public class ManagementApiComposer : IComposer throw new Exception($"There is no relative path for controller action {e.ActionDescriptor.RouteValues["controller"]}"); } - var httpMethod = e.HttpMethod?.ToLower().ToFirstUpper() ?? "Get"; - // Remove the prefixed base path with version, e.g. /umbraco/management/api/v1/tracked-reference/{id} => tracked-reference/{id} var unprefixedRelativePath = OperationIdRegexes.VersionPrefixRegex().Replace(relativePath, string.Empty); diff --git a/src/Umbraco.Cms.ManagementApi/OpenApi.json b/src/Umbraco.Cms.ManagementApi/OpenApi.json index d2c27c5746..b4b01c10e7 100644 --- a/src/Umbraco.Cms.ManagementApi/OpenApi.json +++ b/src/Umbraco.Cms.ManagementApi/OpenApi.json @@ -892,16 +892,6 @@ } ], "responses": { - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -911,6 +901,16 @@ } } } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -942,16 +942,6 @@ } ], "responses": { - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -961,6 +951,16 @@ } } } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -1181,6 +1181,16 @@ } ], "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PagedHelpPage" + } + } + } + }, "400": { "description": "Bad Request", "content": { @@ -1190,13 +1200,121 @@ } } } + } + } + } + }, + "/umbraco/management/api/v1/indexer": { + "get": { + "tags": [ + "Indexer" + ], + "operationId": "GetIndexer", + "parameters": [ + { + "name": "skip", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } }, + { + "name": "take", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { "200": { "description": "Success", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PagedHelpPage" + "$ref": "#/components/schemas/PagedIndex" + } + } + } + } + } + } + }, + "/umbraco/management/api/v1/indexer/{indexName}": { + "get": { + "tags": [ + "Indexer" + ], + "operationId": "GetIndexerByIndexName", + "parameters": [ + { + "name": "indexName", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Index" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/umbraco/management/api/v1/indexer/{indexName}/rebuild": { + "post": { + "tags": [ + "Indexer" + ], + "operationId": "PostIndexerByIndexNameRebuild", + "parameters": [ + { + "name": "indexName", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResult" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" } } } @@ -1211,6 +1329,16 @@ ], "operationId": "GetInstallSettings", "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InstallSettings" + } + } + } + }, "400": { "description": "Bad Request", "content": { @@ -1230,16 +1358,6 @@ } } } - }, - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InstallSettings" - } - } - } } } } @@ -1260,6 +1378,9 @@ } }, "responses": { + "200": { + "description": "Success" + }, "400": { "description": "Bad Request", "content": { @@ -1279,9 +1400,6 @@ } } } - }, - "200": { - "description": "Success" } } } @@ -1302,6 +1420,9 @@ } }, "responses": { + "200": { + "description": "Success" + }, "400": { "description": "Bad Request", "content": { @@ -1311,9 +1432,6 @@ } } } - }, - "200": { - "description": "Success" } } } @@ -1374,16 +1492,6 @@ } ], "responses": { - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundResult" - } - } - } - }, "200": { "description": "Success", "content": { @@ -1393,6 +1501,16 @@ } } } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundResult" + } + } + } } } }, @@ -1413,6 +1531,9 @@ } ], "responses": { + "200": { + "description": "Success" + }, "400": { "description": "Bad Request", "content": { @@ -1432,9 +1553,6 @@ } } } - }, - "200": { - "description": "Success" } } } @@ -1455,6 +1573,9 @@ } }, "responses": { + "201": { + "description": "Created" + }, "400": { "description": "Bad Request", "content": { @@ -1464,9 +1585,6 @@ } } } - }, - "201": { - "description": "Created" } } } @@ -1487,15 +1605,8 @@ } }, "responses": { - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundResult" - } - } - } + "200": { + "description": "Success" }, "400": { "description": "Bad Request", @@ -1507,8 +1618,15 @@ } } }, - "200": { - "description": "Success" + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundResult" + } + } + } } } } @@ -1688,16 +1806,6 @@ } ], "responses": { - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -1707,6 +1815,16 @@ } } } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -1738,16 +1856,6 @@ } ], "responses": { - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -1757,6 +1865,16 @@ } } } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -2626,130 +2744,12 @@ } } }, - "/umbraco/management/api/v1/search/index": { + "/umbraco/management/api/v1/searcher": { "get": { "tags": [ - "Search" + "Searcher" ], - "operationId": "GetSearchIndex", - "parameters": [ - { - "name": "skip", - "in": "query", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "take", - "in": "query", - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PagedIndex" - } - } - } - } - } - } - }, - "/umbraco/management/api/v1/search/index/{indexName}": { - "get": { - "tags": [ - "Search" - ], - "operationId": "GetSearchIndexByIndexName", - "parameters": [ - { - "name": "indexName", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Index" - } - } - } - } - } - } - }, - "/umbraco/management/api/v1/search/index/{indexName}/rebuild": { - "post": { - "tags": [ - "Search" - ], - "operationId": "PostSearchIndexByIndexNameRebuild", - "parameters": [ - { - "name": "indexName", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OkResult" - } - } - } - } - } - } - }, - "/umbraco/management/api/v1/search/searcher": { - "get": { - "tags": [ - "Search" - ], - "operationId": "GetSearchSearcher", + "operationId": "GetSearcher", "parameters": [ { "name": "skip", @@ -2782,12 +2782,12 @@ } } }, - "/umbraco/management/api/v1/search/searcher/{searcherName}/search": { + "/umbraco/management/api/v1/searcher/{searcherName}/query": { "get": { "tags": [ - "Search" + "Searcher" ], - "operationId": "GetSearchSearcherBySearcherNameSearch", + "operationId": "GetSearcherBySearcherNameQuery", "parameters": [ { "name": "searcherName", @@ -2798,7 +2798,7 @@ } }, { - "name": "query", + "name": "term", "in": "query", "schema": { "type": "string" @@ -2876,16 +2876,6 @@ ], "operationId": "GetServerStatus", "responses": { - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -2895,6 +2885,16 @@ } } } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -2906,16 +2906,6 @@ ], "operationId": "GetServerVersion", "responses": { - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, "200": { "description": "Success", "content": { @@ -2925,6 +2915,16 @@ } } } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } } } @@ -3245,6 +3245,9 @@ } }, "responses": { + "200": { + "description": "Success" + }, "400": { "description": "Bad Request", "content": { @@ -3254,9 +3257,6 @@ } } } - }, - "200": { - "description": "Success" } } } @@ -7115,4 +7115,4 @@ "OAuth": [] } ] -} \ No newline at end of file +} diff --git a/src/Umbraco.Cms.StaticAssets/wwwroot/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoImageBlock.html b/src/Umbraco.Cms.StaticAssets/wwwroot/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoImageBlock.html index cd3379994a..e5c6a4d04d 100644 --- a/src/Umbraco.Cms.StaticAssets/wwwroot/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoImageBlock.html +++ b/src/Umbraco.Cms.StaticAssets/wwwroot/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoImageBlock.html @@ -66,11 +66,22 @@ transition: opacity 120ms; } + .is-trashed { + background-color: #d42054 !important; + color:white !important; + } + .is-trashed .file-name { + opacity: 1; + } + - \ No newline at end of file diff --git a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj index b86d4f6e52..056eb09513 100644 --- a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj +++ b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj @@ -16,18 +16,38 @@ - - - + - $(MSBuildThisFileDirectory)appsettings-schema.json - $(MSBuildThisFileDirectory)appsettings-schema.Umbraco.Cms.json - $(MSBuildThisFileDirectory)..\JsonSchema\ + <_UmbracoCmsJsonSchemaReference>appsettings-schema.Umbraco.Cms.json + NU5100;NU5128 - - - + + + + + + + + + + <_UmbracoJsonSchemaExtensionsFiles Include="$(PkgUmbraco_JsonSchema_Extensions)\tasks\netstandard2.0\**" /> + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.props b/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.props index a967c4fd33..6168686bcb 100644 --- a/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.props +++ b/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.props @@ -9,4 +9,8 @@ + + + + diff --git a/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.targets b/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.targets index d33f644293..4d6e128b68 100644 --- a/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.targets +++ b/src/Umbraco.Cms.Targets/buildTransitive/Umbraco.Cms.Targets.targets @@ -1,13 +1,32 @@ - - - <_SchemaFiles Include="$(MSBuildThisFileDirectory)..\appsettings-schema.json" /> - <_SchemaFiles Include="$(MSBuildThisFileDirectory)..\appsettings-schema.Umbraco.Cms.json" /> - - - + + + + appsettings.json + + + appsettings-schema.json + + + + + + + + + + + + + + + + + + + <_AppPluginsFiles Include="App_Plugins\**" /> @@ -15,6 +34,7 @@ + <_UmbracoFolderFiles Include="umbraco\config\**" /> diff --git a/src/Umbraco.Core/Configuration/Models/ActiveDirectorySettings.cs b/src/Umbraco.Core/Configuration/Models/ActiveDirectorySettings.cs index 3373b7a778..3a3f90de89 100644 --- a/src/Umbraco.Core/Configuration/Models/ActiveDirectorySettings.cs +++ b/src/Umbraco.Core/Configuration/Models/ActiveDirectorySettings.cs @@ -7,7 +7,8 @@ namespace Umbraco.Cms.Core.Configuration.Models; /// Typed configuration options for active directory settings. /// [UmbracoOptions(Constants.Configuration.ConfigActiveDirectory)] -[Obsolete("This is not used anymore. Will be removed in Umbraco 12")]public class ActiveDirectorySettings +[Obsolete("This is not used anymore. Will be removed in Umbraco 12")] +public class ActiveDirectorySettings { /// /// Gets or sets a value for the Active Directory domain. diff --git a/src/Umbraco.Core/Configuration/Models/GlobalSettings.cs b/src/Umbraco.Core/Configuration/Models/GlobalSettings.cs index 92c443fd77..19b2fb44fb 100644 --- a/src/Umbraco.Core/Configuration/Models/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/GlobalSettings.cs @@ -82,8 +82,8 @@ public class GlobalSettings public string UmbracoPath { get => Constants.System.DefaultUmbracoPath; - [Obsolete($"{nameof(UmbracoPath)} is no longer configurable, property setter is scheduled for removal in V12")] - // NOTE: when removing this, also clean up the hardcoded removal of UmbracoPath in UmbracoJsonSchemaGenerator + [Obsolete($"{nameof(UmbracoPath)} is no longer configurable, this property setter is scheduled for removal in V12.")] + // NOTE: When removing this, also clean up the hardcoded removal of UmbracoPath in Umbraco.JsonSchema set { } } diff --git a/src/Umbraco.Core/Configuration/Models/LicensesSettings.cs b/src/Umbraco.Core/Configuration/Models/LicensesSettings.cs deleted file mode 100644 index f8de1d7265..0000000000 --- a/src/Umbraco.Core/Configuration/Models/LicensesSettings.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -namespace Umbraco.Cms.Core.Configuration.Models; - -/// -/// Typed configuration options for license settings. -/// -public class LicensesSettings : Dictionary -{ -} diff --git a/src/Umbraco.Core/Configuration/Models/MarketplaceSettings.cs b/src/Umbraco.Core/Configuration/Models/MarketplaceSettings.cs new file mode 100644 index 0000000000..092e420e3c --- /dev/null +++ b/src/Umbraco.Core/Configuration/Models/MarketplaceSettings.cs @@ -0,0 +1,16 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +namespace Umbraco.Cms.Core.Configuration.Models; + +/// +/// Configuration options for the Marketplace. +/// +[UmbracoOptions(Constants.Configuration.ConfigMarketplace)] +public class MarketplaceSettings +{ + /// + /// Gets or sets the additional parameters that are sent to the Marketplace. + /// + public IDictionary AdditionalParameters { get; set; } = new Dictionary(); +} diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs index bc4c29cfa6..656bcd1cdf 100644 --- a/src/Umbraco.Core/Constants-Configuration.cs +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -27,6 +27,7 @@ public static partial class Constants public const string ConfigHostingDebug = ConfigHostingPrefix + "Debug"; public const string ConfigCustomErrorsMode = ConfigCustomErrorsPrefix + "Mode"; public const string ConfigActiveDirectory = ConfigPrefix + "ActiveDirectory"; + public const string ConfigMarketplace = ConfigPrefix + "Marketplace"; public const string ConfigLegacyPasswordMigration = ConfigPrefix + "LegacyPasswordMigration"; public const string ConfigContent = ConfigPrefix + "Content"; public const string ConfigCoreDebug = ConfigCorePrefix + "Debug"; diff --git a/src/Umbraco.Core/Constants-Marketplace.cs b/src/Umbraco.Core/Constants-Marketplace.cs new file mode 100644 index 0000000000..6d5abb38e7 --- /dev/null +++ b/src/Umbraco.Core/Constants-Marketplace.cs @@ -0,0 +1,12 @@ +namespace Umbraco.Cms.Core; + +public static partial class Constants +{ + /// + /// Defines the constants used for the Umbraco Marketplace. + /// + public static class Marketplace + { + public const string Url = "https://dev.marketplace.umbraco.com"; + } +} diff --git a/src/Umbraco.Core/Constants-PackageRepository.cs b/src/Umbraco.Core/Constants-PackageRepository.cs index 96746adb49..ef2e6fdd48 100644 --- a/src/Umbraco.Core/Constants-PackageRepository.cs +++ b/src/Umbraco.Core/Constants-PackageRepository.cs @@ -5,6 +5,7 @@ public static partial class Constants /// /// Defines the constants used for the Umbraco package repository /// + [Obsolete("This is no longer used and will be removed in Umbraco 13")] public static class PackageRepository { public const string RestApiBaseUrl = "https://our.umbraco.com/webapi/packages/v1"; diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs index 28fc05907e..92e10c7b1c 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs @@ -50,6 +50,7 @@ public static partial class UmbracoBuilderExtensions builder .AddUmbracoOptions() .AddUmbracoOptions() + .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs index d783a67a52..f35229e4e0 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs @@ -325,6 +325,7 @@ namespace Umbraco.Cms.Core.DependencyInjection Services.AddUnique(provider => new CultureImpactFactory(provider.GetRequiredService>())); Services.AddUnique(); + Services.AddUnique(); } } } diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/da.xml b/src/Umbraco.Core/EmbeddedResources/Lang/da.xml index 5581752d7c..624c343d72 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/da.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/da.xml @@ -1263,6 +1263,7 @@ Mange hilsner fra Umbraco robotten Mediearkiv Medlemmer Pakker + Marketplace Nyhedsbreve Indstillinger Statistik @@ -2247,9 +2248,7 @@ Mange hilsner fra Umbraco robotten Træk for at skalere Tilføj indhold label Overskriv labellen for tilføj indholds knappen i dette område. - Tilføj skalerings muligheder - Tilføj områder - Tilføj katalog udseende + Tilføj skalerings muligheder Tilføj Blok Tilføj gruppe Tilføj gruppe eller Blok @@ -2267,6 +2266,9 @@ Mange hilsner fra Umbraco robotten Sortings tilstand Afslut sortings tilstand Dette område alias skal være unikt sammenlignet med andre områder af denne Blok. + Konfigurer område + Slet område + Tilføj mulighed for %0% koloner Hvad er Indholdsskabeloner? diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml index 4c625ed18c..82d38a3222 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml @@ -1479,6 +1479,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Members Newsletters Packages + Marketplace Settings Statistics Translation @@ -2808,7 +2809,6 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Create Button Label Overwrite the label on the create button of this Area. Show resize options - Show catalogue appearance Add Block Add group Pick group or Block @@ -2828,6 +2828,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont This Areas Alias must be unique compared to the other Areas of this Block. Configure area Delete area + Add spanning %0% columns option What are Content Templates? diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml index 056d9f0e71..c71c900185 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml @@ -1517,6 +1517,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Media Members Packages + Marketplace Settings Translation Users @@ -2911,7 +2912,6 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Create Button Label Overwrite the label on the create button of this Area. Show resize options - Show catalogue appearance Add Block Add group Pick group or Block @@ -2931,6 +2931,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont This Areas Alias must be unique compared to the other Areas of this Block. Configure area Delete area + Add spanning %0% columns option What are Content Templates? diff --git a/src/Umbraco.Core/Services/ITemporaryMediaService.cs b/src/Umbraco.Core/Services/ITemporaryMediaService.cs new file mode 100644 index 0000000000..9c3c07acaf --- /dev/null +++ b/src/Umbraco.Core/Services/ITemporaryMediaService.cs @@ -0,0 +1,8 @@ +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Core.Services; + +public interface ITemporaryMediaService +{ + public IMedia Save(string temporaryLocation, Guid? startNode, string? mediaTypeAlias); +} diff --git a/src/Umbraco.Core/Services/TemporaryMediaService.cs b/src/Umbraco.Core/Services/TemporaryMediaService.cs new file mode 100644 index 0000000000..44aa555804 --- /dev/null +++ b/src/Umbraco.Core/Services/TemporaryMediaService.cs @@ -0,0 +1,94 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Core.Extensions; +using Umbraco.Cms.Core.IO; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.Security; +using Umbraco.Cms.Core.Strings; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Core.Services; + +public class TemporaryMediaService : ITemporaryMediaService +{ + private readonly IShortStringHelper _shortStringHelper; + private readonly MediaFileManager _mediaFileManager; + private readonly IMediaService _mediaService; + private readonly MediaUrlGeneratorCollection _mediaUrlGenerators; + private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; + private readonly IHostEnvironment _hostingEnvironment; + private readonly ILogger _logger; + private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; + + public TemporaryMediaService( + IShortStringHelper shortStringHelper, + MediaFileManager mediaFileManager, + IMediaService mediaService, + MediaUrlGeneratorCollection mediaUrlGenerators, + IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, + IHostEnvironment hostingEnvironment, + ILogger logger, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor) + { + _shortStringHelper = shortStringHelper; + _mediaFileManager = mediaFileManager; + _mediaService = mediaService; + _mediaUrlGenerators = mediaUrlGenerators; + _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; + _hostingEnvironment = hostingEnvironment; + _logger = logger; + _backOfficeSecurityAccessor = backOfficeSecurityAccessor; + } + + public IMedia Save(string temporaryLocation, Guid? startNode, string? mediaTypeAlias) + { + var userId = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? Constants.Security.SuperUserId; + var absoluteTempImagePath = _hostingEnvironment.MapPathContentRoot(temporaryLocation); + var fileName = Path.GetFileName(absoluteTempImagePath); + var safeFileName = fileName.ToSafeFileName(_shortStringHelper); + + var mediaItemName = safeFileName.ToFriendlyName(); + + IMedia mediaFile; + if (startNode is null) + { + mediaFile = _mediaService.CreateMedia(mediaItemName, Constants.System.Root, mediaTypeAlias ?? Constants.Conventions.MediaTypes.File, userId); + } + else + { + mediaFile = _mediaService.CreateMedia(mediaItemName, startNode.Value, mediaTypeAlias ?? Constants.Conventions.MediaTypes.File, userId); + } + + var fileInfo = new FileInfo(absoluteTempImagePath); + + FileStream? fileStream = fileInfo.OpenReadWithRetry(); + if (fileStream is null) + { + throw new InvalidOperationException("Could not acquire file stream"); + } + + using (fileStream) + { + mediaFile.SetValue(_mediaFileManager, _mediaUrlGenerators, _shortStringHelper, _contentTypeBaseServiceProvider, Constants.Conventions.Media.File, safeFileName, fileStream); + } + + _mediaService.Save(mediaFile, userId); + + // Delete temp file now that we have persisted it + var folderName = Path.GetDirectoryName(absoluteTempImagePath); + try + { + if (folderName is not null) + { + Directory.Delete(folderName, true); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath); + } + + return mediaFile; + } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs index bada35623b..5c7488401f 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs @@ -152,20 +152,15 @@ public class DocumentRepository : ContentRepositoryBase(x => x.Published); } // invariant: left join will yield NULL and we must use pcv to determine published // variant: left join may yield NULL or something, and that determines published - Sql joins = Sql() .InnerJoin("ctype").On( (content, contentType) => content.ContentTypeId == contentType.NodeId, aliasRight: "ctype") @@ -185,9 +180,9 @@ public class DocumentRepository : ContentRepositoryBase(x => x.Published)}) ELSE (CASE WHEN ccvp.id IS NULL THEN 0 ELSE 1 END) END) AS ordering "); // trailing space is important! sql = Sql(sqlText, sql.Arguments); diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs index 3d8f9ac898..5be7cfdde2 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs @@ -81,6 +81,51 @@ public class UmbracoDatabase : Database, IUmbracoDatabase { Mappers.AddRange(_mapperCollection); } + + InitCommandTimeout(); + } + + // https://github.com/umbraco/Umbraco-CMS/issues/13354 + // This sets the Database Command to connectionString Connection Timeout / Connect Timeout + // This could be better, ideally the UmbracoDatabaseFactory.CreateDatabase() function would set this based on a setting (global or connectionstring setting) + private void InitCommandTimeout() + { + if (CommandTimeout != 0) + { + // CommandTimeout configured elsewhere, so we'll skip + return; + } + + if (Connection is not null && Connection.ConnectionTimeout > 0) + { + CommandTimeout = Connection.ConnectionTimeout; + return; + } + + // get from ConnectionString + var connectionParser = new DbConnectionStringBuilder + { + ConnectionString = ConnectionString + }; + + if (connectionParser.TryGetValue("connection timeout", out var connectionTimeoutString)) + { + if (int.TryParse(connectionTimeoutString.ToString(), out var connectionTimeout)) + { + _logger.LogTrace("Setting Command Timeout to value configured in connectionstring Connection Timeout : {TimeOut} seconds", connectionTimeout); + CommandTimeout = connectionTimeout; + return; + } + } + + if (connectionParser.TryGetValue("connect timeout", out var connectTimeoutString)) + { + if (int.TryParse(connectTimeoutString.ToString(), out var connectionTimeout)) + { + _logger.LogTrace("Setting Command Timeout to value configured in connectionstring Connect Timeout : {TimeOut} seconds", connectionTimeout); + CommandTimeout = connectionTimeout; + } + } } #endregion diff --git a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs index ed774f9215..09eb6a1f47 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -1,7 +1,9 @@ using System.Runtime.Serialization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Editors; @@ -37,7 +39,8 @@ public class MediaPicker3PropertyEditor : DataEditor IDataValueEditorFactory dataValueEditorFactory, IIOHelper ioHelper, EditorType type = EditorType.PropertyValue) - : this(dataValueEditorFactory, ioHelper, StaticServiceProvider.Instance.GetRequiredService(), type) + : this(dataValueEditorFactory, ioHelper, + StaticServiceProvider.Instance.GetRequiredService(), type) { } @@ -68,6 +71,8 @@ public class MediaPicker3PropertyEditor : DataEditor { private readonly IDataTypeService _dataTypeService; private readonly IJsonSerializer _jsonSerializer; + private readonly ITemporaryMediaService _temporaryMediaService; + public MediaPicker3PropertyValueEditor( ILocalizedTextService localizedTextService, @@ -75,11 +80,13 @@ public class MediaPicker3PropertyEditor : DataEditor IJsonSerializer jsonSerializer, IIOHelper ioHelper, DataEditorAttribute attribute, - IDataTypeService dataTypeService) + IDataTypeService dataTypeService, + ITemporaryMediaService temporaryMediaService) : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) { _jsonSerializer = jsonSerializer; _dataTypeService = dataTypeService; + _temporaryMediaService = temporaryMediaService; } /// @@ -118,6 +125,11 @@ public class MediaPicker3PropertyEditor : DataEditor { if (editorValue.Value is JArray dtos) { + if (editorValue.DataTypeConfiguration is MediaPicker3Configuration configuration) + { + dtos = PersistTempMedia(dtos, configuration); + } + // Clean up redundant/default data foreach (JObject? dto in dtos.Values()) { @@ -150,7 +162,7 @@ public class MediaPicker3PropertyEditor : DataEditor Key = Guid.NewGuid(), MediaKey = guidUdi.Guid, Crops = Enumerable.Empty(), - FocalPoint = new ImageCropperValue.ImageCropperFocalPoint { Left = 0.5m, Top = 0.5m }, + FocalPoint = new ImageCropperValue.ImageCropperFocalPoint {Left = 0.5m, Top = 0.5m}, }; } } @@ -170,6 +182,49 @@ public class MediaPicker3PropertyEditor : DataEditor } } + private JArray PersistTempMedia(JArray jArray, MediaPicker3Configuration mediaPicker3Configuration) + { + var result = new JArray(); + foreach (JObject? dto in jArray.Values()) + { + if (dto is null) + { + continue; + } + + if (!dto.TryGetValue("tmpLocation", out JToken? temporaryLocation)) + { + // If it does not have a temporary path, it can be an already saved image or not-yet uploaded temp-image, check for media-key + if (dto.TryGetValue("mediaKey", out _)) + { + result.Add(dto); + } + + continue; + } + + var temporaryLocationString = temporaryLocation.Value(); + if (temporaryLocationString is null) + { + continue; + } + + GuidUdi? startNodeGuid = mediaPicker3Configuration.StartNodeId as GuidUdi ?? null; + JToken? mediaTypeAlias = dto.GetValue("mediaTypeAlias"); + IMedia mediaFile = _temporaryMediaService.Save(temporaryLocationString, startNodeGuid?.Guid, mediaTypeAlias?.Value()); + MediaWithCropsDto? mediaDto = _jsonSerializer.Deserialize(dto.ToString()); + if (mediaDto is null) + { + continue; + } + + mediaDto.MediaKey = mediaFile.GetUdi().Guid; + result.Add(JObject.Parse(_jsonSerializer.Serialize(mediaDto))); + } + + return result; + } + /// /// Model/DTO that represents the JSON that the MediaPicker3 stores. /// diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs index 768fe382f9..6d44fcd15f 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs @@ -1,4 +1,5 @@ using System.Runtime.Serialization; +using System.Web; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Routing; @@ -54,6 +55,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private MemberPasswordConfigurationSettings _memberPasswordConfigurationSettings; private DataTypesSettings _dataTypesSettings; private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory; + private MarketplaceSettings _marketplaceSettings; [Obsolete("Use constructor that takes IOptionsMontior, scheduled for removal in V12")] public BackOfficeServerVariables( @@ -139,6 +141,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { } + [Obsolete("Use constructor that takes IOptionsMonitor, scheduled for removal in V13")] public BackOfficeServerVariables( LinkGenerator linkGenerator, IRuntimeState runtimeState, @@ -159,6 +162,52 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers IOptionsMonitor memberPasswordConfigurationSettings, IOptionsMonitor dataTypesSettings, ITempDataDictionaryFactory tempDataDictionaryFactory) + : this( + linkGenerator, + runtimeState, + features, + globalSettings, + umbracoVersion, + contentSettings, + httpContextAccessor, + treeCollection, + hostingEnvironment, + runtimeSettings, + securitySettings, + runtimeMinifier, + externalLogins, + imageUrlGenerator, + previewRoutes, + emailSender, + memberPasswordConfigurationSettings, + dataTypesSettings, + tempDataDictionaryFactory, + StaticServiceProvider.Instance.GetRequiredService>() + ) + { + } + + public BackOfficeServerVariables( + LinkGenerator linkGenerator, + IRuntimeState runtimeState, + UmbracoFeatures features, + IOptionsMonitor globalSettings, + IUmbracoVersion umbracoVersion, + IOptionsMonitor contentSettings, + IHttpContextAccessor httpContextAccessor, + TreeCollection treeCollection, + IHostingEnvironment hostingEnvironment, + IOptionsMonitor runtimeSettings, + IOptionsMonitor securitySettings, + IRuntimeMinifier runtimeMinifier, + IBackOfficeExternalLoginProviders externalLogins, + IImageUrlGenerator imageUrlGenerator, + PreviewRoutes previewRoutes, + IEmailSender emailSender, + IOptionsMonitor memberPasswordConfigurationSettings, + IOptionsMonitor dataTypesSettings, + ITempDataDictionaryFactory tempDataDictionaryFactory, + IOptionsMonitor marketplaceSettings) { _linkGenerator = linkGenerator; _runtimeState = runtimeState; @@ -179,6 +228,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _tempDataDictionaryFactory = tempDataDictionaryFactory; _memberPasswordConfigurationSettings = memberPasswordConfigurationSettings.CurrentValue; _dataTypesSettings = dataTypesSettings.CurrentValue; + _marketplaceSettings = marketplaceSettings.CurrentValue; globalSettings.OnChange(x => _globalSettings = x); contentSettings.OnChange(x => _contentSettings = x); @@ -186,6 +236,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers securitySettings.OnChange(x => _securitySettings = x); dataTypesSettings.OnChange(x => _dataTypesSettings = x); memberPasswordConfigurationSettings.OnChange(x => _memberPasswordConfigurationSettings = x); + marketplaceSettings.OnChange(x => _marketplaceSettings = x); } /// @@ -298,6 +349,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers {"gridConfig", _linkGenerator.GetPathByAction(nameof(BackOfficeController.GetGridConfig), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })}, // TODO: This is ultra confusing! this same key is used for different things, when returning the full app when authenticated it is this URL but when not auth'd it's actually the ServerVariables address {"serverVarsJs", _linkGenerator.GetPathByAction(nameof(BackOfficeController.Application), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })}, + {"marketplaceUrl", GetMarketplaceUrl()}, //API URLs { "packagesRestApiBaseUrl", Constants.PackageRepository.RestApiBaseUrl @@ -529,6 +581,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers "propertyTypeApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl( controller => controller.HasValues(string.Empty)) }, + { + "mediaPickerThreeBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl( + controller => controller.UploadMedia(null!)) + }, } }, { @@ -621,6 +677,25 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return defaultVals; } + private string GetMarketplaceUrl() + { + var uriBuilder = new UriBuilder(Constants.Marketplace.Url); + + var query = HttpUtility.ParseQueryString(uriBuilder.Query); + + query["umbversion"] = _runtimeState.SemanticVersion.ToSemanticStringWithoutBuild(); + query["style"] = "backoffice"; + + foreach (var kvp in _marketplaceSettings.AdditionalParameters) + { + query[kvp.Key] = kvp.Value; + } + + uriBuilder.Query = query.ToString(); + + return uriBuilder.ToString(); + } + [DataContract] private class PluginTree { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaPickerThreeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaPickerThreeController.cs new file mode 100644 index 0000000000..57b27e1df2 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaPickerThreeController.cs @@ -0,0 +1,113 @@ +using System.Net; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Dictionary; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Hosting; +using Umbraco.Cms.Core.IO; +using Umbraco.Cms.Core.Media; +using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Strings; +using Umbraco.Cms.Web.Common.ActionsResults; +using Umbraco.Cms.Web.Common.Attributes; +using Umbraco.Cms.Web.Common.Authorization; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.BackOffice.Controllers; + +[PluginController(Constants.Web.Mvc.BackOfficeApiArea)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessMedia)] +public class MediaPickerThreeController : ContentControllerBase +{ + private readonly IHostingEnvironment _hostingEnvironment; + private readonly ContentSettings _contentSettings; + private readonly IImageUrlGenerator _imageUrlGenerator; + private readonly IIOHelper _ioHelper; + + public MediaPickerThreeController( + ICultureDictionary cultureDictionary, + ILoggerFactory loggerFactory, + IShortStringHelper shortStringHelper, + IEventMessagesFactory eventMessages, + ILocalizedTextService localizedTextService, + IJsonSerializer serializer, + IHostingEnvironment hostingEnvironment, + IOptionsSnapshot contentSettings, + IImageUrlGenerator imageUrlGenerator, + IIOHelper ioHelper) + : base(cultureDictionary, loggerFactory, shortStringHelper, eventMessages, localizedTextService, serializer) + { + _hostingEnvironment = hostingEnvironment; + _contentSettings = contentSettings.Value; + _imageUrlGenerator = imageUrlGenerator; + _ioHelper = ioHelper; + } + + [HttpPost] + public async Task UploadMedia(List file) + { + // Create an unique folder path to help with concurrent users to avoid filename clash + var imageTempPath = + _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempFileUploads + "/" + Guid.NewGuid()); + + // Ensure image temp path exists + if (Directory.Exists(imageTempPath) == false) + { + Directory.CreateDirectory(imageTempPath); + } + + // Must have a file + if (file.Count == 0) + { + return NotFound(); + } + + // Should only have one file + if (file.Count > 1) + { + return new UmbracoProblemResult("Only one file can be uploaded at a time", HttpStatusCode.BadRequest); + } + + // Really we should only have one file per request to this endpoint + IFormFile formFile = file.First(); + + var fileName = formFile.FileName.Trim(new[] { '\"' }).TrimEnd(); + var safeFileName = fileName.ToSafeFileName(ShortStringHelper); + var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLowerInvariant(); + + if (_contentSettings.IsFileAllowedForUpload(ext) == false) + { + // Throw some error - to say can't upload this IMG type + return new UmbracoProblemResult("This is not an image filetype extension that is approved", HttpStatusCode.BadRequest); + } + + var newFilePath = imageTempPath + Path.DirectorySeparatorChar + safeFileName; + var relativeNewFilePath = GetRelativePath(newFilePath); + + await using (FileStream stream = System.IO.File.Create(newFilePath)) + { + await formFile.CopyToAsync(stream); + } + + return Ok(new { tmpLocation = relativeNewFilePath }); + } + + // Use private method istead of _ioHelper.GetRelativePath as that is relative for the webroot and not the content root. + private string GetRelativePath(string path) + { + if (path.IsFullPath()) + { + var rootDirectory = _hostingEnvironment.MapPathContentRoot("~"); + var relativePath = _ioHelper.PathStartsWith(path, rootDirectory) ? path[rootDirectory.Length..] : path; + path = relativePath; + } + + return PathUtility.EnsurePathIsApplicationRootPrefixed(path); + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs index 9582a6f032..09b24b11e4 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs @@ -132,6 +132,35 @@ public class MediaTypeController : ContentTypeControllerBase return dto; } + /// + /// Returns a media type by alias + /// + /// /// Alias of the media type + /// + public IEnumerable GetAllFiltered([FromQuery] string[] aliases) + { + if (aliases.Length < 1) + { + return _mediaTypeService.GetAll().Select(_umbracoMapper.Map).WhereNotNull(); + } + + var mediaTypeDisplays = new List(); + + foreach (var alias in aliases) + { + IMediaType? mediaType = _mediaTypeService.Get(alias); + + MediaTypeDisplay? mediaTypeDisplay = _umbracoMapper.Map(mediaType); + + if (mediaTypeDisplay is not null) + { + mediaTypeDisplays.Add(mediaTypeDisplay); + } + } + + return mediaTypeDisplays; + } + /// /// Deletes a media type with a given ID /// diff --git a/src/Umbraco.Web.UI.Client/.eslintrc b/src/Umbraco.Web.UI.Client/.eslintrc index f727714466..42492d802c 100644 --- a/src/Umbraco.Web.UI.Client/.eslintrc +++ b/src/Umbraco.Web.UI.Client/.eslintrc @@ -1,28 +1,60 @@ { - "env": { - "browser": true - }, - "rules": { "comma-dangle": ["error", "never"] }, "parserOptions": { - "ecmaVersion": 2020 + "ecmaVersion": "latest" }, - "globals": { - "angular": false, - "_": false, - "$": false, - "tinymce": false, - "tinyMCE": false, - "FileReader": false, - "Umbraco": false, - "Utilities": false, - "window": false, - "LazyLoad": false, - "ActiveXObject": false, - "Bloodhound": false - } + "overrides": [ + { + "env": { + "browser": true, + "es6": true, + "jquery": true + }, + + "files": ["src/**/*.js"], + + "extends": ["eslint:recommended"], + + "rules": { + "no-extra-semi": "off", + "no-mixed-spaces-and-tabs": "off", + "no-unused-vars": "off", + "no-control-regex": "off", + "no-self-assign": "warn", + "no-useless-escape": "warn", + "no-extra-boolean-cast": "warn", + "no-prototype-builtins": "warn" + }, + + "globals": { + "angular": "readonly", + "_": "readonly", + "$": "readonly", + "jQuery": "readonly", + "tinymce": "readonly", + "tinyMCE": "readonly", + "FileReader": "readonly", + "Umbraco": "readonly", + "Utilities": "readonly", + "window": "readonly", + "LazyLoad": "readonly", + "ActiveXObject": "readonly", + "Bloodhound": "readonly", + "Diff": "readonly", + "moment": "readonly", + "signalR": "readonly", + "Markdown": "readonly", + "Sortable": "readonly", + "noUiSlider": "readonly", + "ClipboardJS": "readonly", + "anime": "readonly", + "flatpickr": "readonly", + "FlatpickrInstance": "readonly" + } + } + ] } diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js index c1eab78b21..2f711245e3 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js @@ -291,11 +291,6 @@ function dependencies() { "./node_modules/@umbraco-ui/uui-css/dist/uui-text.css" ], "base": "./node_modules/@umbraco-ui" - }, - { - "name": "sortablejs", - "src": ["./node_modules/sortablejs/Sortable.min.js"], - "base": "./node_modules/sortablejs" } ]; diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js index 98b1c23343..f892a50292 100644 --- a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js +++ b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js @@ -2,7 +2,7 @@ var config = require('../config'); var gulp = require('gulp'); -var eslint = require('gulp-eslint'); +var eslint = require('gulp-eslint-new'); var babel = require("gulp-babel"); var sort = require('gulp-sort'); var concat = require('gulp-concat'); @@ -21,14 +21,19 @@ module.exports = function (files, out) { var task = gulp.src(files); // check for js errors - task = task.pipe(eslint()); + task = task.pipe(eslint({ + warnIgnored: true, + quiet: true + })); // outputs the lint results to the console task = task.pipe(eslint.format()); + // fail after all errors have been discovered + task = task.pipe(eslint.failAfterError()); // sort files in stream by path or any custom sort comparator task = task.pipe(babel()) .pipe(sort()); - + //in production, embed the templates if(config.compile.current.embedtemplates === true) { task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } })); diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 6f56601eca..2f244d827e 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -38,7 +38,6 @@ "moment": "2.29.4", "ng-file-upload": "12.2.13", "nouislider": "15.6.1", - "sortablejs": "1.15.0", "spectrum-colorpicker2": "2.0.9", "tinymce": "6.2.0", "typeahead.js": "0.11.1", @@ -50,13 +49,14 @@ "@babel/preset-env": "7.19.1", "autoprefixer": "10.4.4", "cssnano": "5.1.13", + "eslint": "8.28.0", "gulp": "4.0.2", "gulp-angular-embed-templates": "2.3.0", "gulp-babel": "8.0.0", "gulp-clean-css": "4.3.0", "gulp-cli": "2.3.0", "gulp-concat": "2.6.1", - "gulp-eslint": "6.0.0", + "gulp-eslint-new": "1.7.0", "gulp-imagemin": "7.1.0", "gulp-less": "5.0.0", "gulp-minify": "3.1.0", @@ -1715,6 +1715,62 @@ "node": ">=0.1.90" } }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -1810,6 +1866,39 @@ "node": ">=0.10.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -1961,6 +2050,22 @@ "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, + "node_modules/@types/eslint": { + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", @@ -1971,6 +2076,12 @@ "@types/node": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2944,21 +3055,6 @@ "node": ">=0.10.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -3293,15 +3389,6 @@ "node": ">=0.10.0" } }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -4351,12 +4438,6 @@ "node": ">=4" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/chart.js": { "version": "2.9.4", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", @@ -4530,27 +4611,6 @@ "timers-ext": "^0.1.5" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/clipboard": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", @@ -5015,6 +5075,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, + "optional": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -6348,112 +6409,229 @@ } }, "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" } }, "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=6" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" } }, "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" @@ -6462,61 +6640,171 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/resolve-from": { + "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, "node_modules/esprima": { @@ -6566,9 +6854,9 @@ } }, "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -6987,20 +7275,6 @@ "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -7198,31 +7472,16 @@ "node": ">=8" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/file-type": { @@ -7414,17 +7673,31 @@ } }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/flatpickr": { @@ -7433,9 +7706,9 @@ "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" }, "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "node_modules/flush-write-stream": { @@ -7497,6 +7770,12 @@ "node": ">=0.10.0" } }, + "node_modules/fork-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", + "integrity": "sha512-Pqq5NnT78ehvUnAk/We/Jr22vSvanRlFTpAmQ88xBY/M1TlHe+P0ILuEyXS595ysdGfaj22634LBkGMA2GTcpA==", + "dev": true + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -7621,12 +7900,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8049,15 +8322,6 @@ "node": ">=8" } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/globby/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8129,6 +8393,12 @@ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", @@ -8251,17 +8521,82 @@ "node": ">= 0.10" } }, - "node_modules/gulp-eslint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-6.0.0.tgz", - "integrity": "sha512-dCVPSh1sA+UVhn7JSQt7KEb4An2sQNbOdB3PA8UCfxsoPlAKjJHxYHGXdXC7eb+V1FAnilSFFqslPrq037l1ig==", + "node_modules/gulp-eslint-new": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/gulp-eslint-new/-/gulp-eslint-new-1.7.0.tgz", + "integrity": "sha512-qrG9ItWNI5Vs8+P5P8YSJfEjx7w1V9ynRybOLunfjB0hfTZO/eMNmhPl8MCWKN/KHe1Q3QwsHyOl9rUv/2Q8yw==", "dev": true, "dependencies": { - "eslint": "^6.0.0", - "fancy-log": "^1.3.2", - "plugin-error": "^1.0.1" + "@types/eslint": "^8.4.9", + "@types/node": ">=12", + "eslint": "8", + "fancy-log": "^2.0.0", + "plugin-error": "^2.0.0", + "semver": "^7.3.8", + "ternary-stream": "^3.0.0", + "vinyl-fs": "^3.0.3" + }, + "engines": { + "node": "12 >=12.20 || 14 >=14.13 || >=16" } }, + "node_modules/gulp-eslint-new/node_modules/fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "dev": true, + "dependencies": { + "color-support": "^1.1.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-eslint-new/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulp-eslint-new/node_modules/plugin-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.0.tgz", + "integrity": "sha512-o4bwIOmuFwUg2MU6xt7plGEQY3YyENx6kvwaFZBrUpamA91FdS9w3U+pU0y4OuDoBQe+jf3RLGSfQebSRBEVsQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-eslint-new/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulp-eslint-new/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/gulp-imagemin": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-7.1.0.tgz", @@ -9321,9 +9656,9 @@ "optional": true }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -9425,6 +9760,22 @@ "url": "https://github.com/sindresorhus/imagemin-svgo?sponsor=1" } }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", @@ -9479,115 +9830,6 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -10026,6 +10268,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -10333,6 +10584,16 @@ "resolved": "https://registry.npmjs.org/jquery-ui-touch-punch/-/jquery-ui-touch-punch-0.2.3.tgz", "integrity": "sha1-7tgiQnM7okP0az6HwYQbMIGR2mg=" }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10659,15 +10920,6 @@ "karma": ">=0.9" } }, - "node_modules/karma/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/karma/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -10871,18 +11123,6 @@ "node": ">=0.10.0" } }, - "node_modules/karma/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/karma/node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -11228,6 +11468,21 @@ "node": ">=0.10.0" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -11332,6 +11587,12 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -11396,12 +11657,6 @@ } } }, - "node_modules/log4js/node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, "node_modules/logalot": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", @@ -11804,6 +12059,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "optional": true, "engines": { "node": ">=6" } @@ -11957,12 +12213,6 @@ "node": ">= 0.10" } }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "node_modules/nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", @@ -12121,7 +12371,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/node-fetch": { "version": "2.6.7", @@ -12657,6 +12908,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "optional": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -12737,15 +12989,6 @@ "node": ">=0.10.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -12789,6 +13032,36 @@ "node": ">=4" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-map-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", @@ -13000,6 +13273,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, + "optional": true, "engines": { "node": ">=4" } @@ -13839,15 +14113,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -14238,12 +14503,15 @@ } }, "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { - "node": ">=6.5.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/regexpu-core": { @@ -14424,6 +14692,15 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-options": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", @@ -14453,19 +14730,6 @@ "lowercase-keys": "^1.0.0" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -14496,6 +14760,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, + "optional": true, "dependencies": { "glob": "^7.1.3" }, @@ -14503,15 +14768,6 @@ "rimraf": "bin.js" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -14663,18 +14919,6 @@ "node": ">=0.8.0" } }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -14822,6 +15066,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, + "optional": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -14834,6 +15079,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, + "optional": true, "engines": { "node": ">=0.10.0" } @@ -14863,7 +15109,8 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/simple-swizzle": { "version": "0.2.2", @@ -14889,29 +15136,6 @@ "node": ">=0.10.0" } }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -15132,11 +15356,6 @@ "node": ">=0.10.0" } }, - "node_modules/sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -15531,27 +15750,6 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.trimend": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", @@ -15581,24 +15779,24 @@ } }, "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -15786,50 +15984,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -15873,6 +16027,54 @@ "node": ">=4" } }, + "node_modules/ternary-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz", + "integrity": "sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==", + "dev": true, + "dependencies": { + "duplexify": "^4.1.1", + "fork-stream": "^0.0.4", + "merge-stream": "^2.0.0", + "through2": "^3.0.1" + } + }, + "node_modules/ternary-stream/node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ternary-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ternary-stream/node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, "node_modules/terser": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", @@ -15915,7 +16117,8 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "dev": true, + "optional": true }, "node_modules/through2": { "version": "2.0.5", @@ -15985,18 +16188,6 @@ "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.2.0.tgz", "integrity": "sha512-zLjbFrg0hbtJ6PxmZUjQY6zyIOM/mLrWGTvhBec7XwYwoW1E0xXMQzy2tgMTh3OvJpsclgqf2ZMjmwcv4Cludw==" }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -16198,12 +16389,6 @@ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", "dev": true }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -16236,9 +16421,9 @@ } }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" @@ -16633,12 +16818,6 @@ "uuid": "bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -17027,18 +17206,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ws": { "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", @@ -17211,6 +17378,18 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -18349,6 +18528,49 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -18423,6 +18645,29 @@ } } }, + "@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -18547,6 +18792,22 @@ "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, + "@types/eslint": { + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "@types/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", @@ -18557,6 +18818,12 @@ "@types/node": "*" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -19491,15 +19758,6 @@ "ansi-wrap": "0.1.0" } }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -19747,12 +20005,6 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, "async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -20589,12 +20841,6 @@ "supports-color": "^5.3.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "chart.js": { "version": "2.9.4", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", @@ -20746,21 +20992,6 @@ "timers-ext": "^0.1.5" } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, "clipboard": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", @@ -21163,6 +21394,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, + "optional": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -22250,132 +22482,290 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" } }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "resolve-from": { + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true + } } }, "esprima": { @@ -22411,9 +22801,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -22764,17 +23154,6 @@ "is-extendable": "^0.1.0" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -22936,22 +23315,13 @@ "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-type": { @@ -23108,14 +23478,24 @@ "dev": true }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatpickr": { @@ -23124,9 +23504,9 @@ "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "flush-write-stream": { @@ -23165,6 +23545,12 @@ "for-in": "^1.0.1" } }, + "fork-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", + "integrity": "sha512-Pqq5NnT78ehvUnAk/We/Jr22vSvanRlFTpAmQ88xBY/M1TlHe+P0ILuEyXS595ysdGfaj22634LBkGMA2GTcpA==", + "dev": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -23262,12 +23648,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -23587,12 +23967,6 @@ "slash": "^3.0.0" }, "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -23656,6 +24030,12 @@ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", @@ -23759,15 +24139,64 @@ "vinyl": "^2.0.0" } }, - "gulp-eslint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-6.0.0.tgz", - "integrity": "sha512-dCVPSh1sA+UVhn7JSQt7KEb4An2sQNbOdB3PA8UCfxsoPlAKjJHxYHGXdXC7eb+V1FAnilSFFqslPrq037l1ig==", + "gulp-eslint-new": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/gulp-eslint-new/-/gulp-eslint-new-1.7.0.tgz", + "integrity": "sha512-qrG9ItWNI5Vs8+P5P8YSJfEjx7w1V9ynRybOLunfjB0hfTZO/eMNmhPl8MCWKN/KHe1Q3QwsHyOl9rUv/2Q8yw==", "dev": true, "requires": { - "eslint": "^6.0.0", - "fancy-log": "^1.3.2", - "plugin-error": "^1.0.1" + "@types/eslint": "^8.4.9", + "@types/node": ">=12", + "eslint": "8", + "fancy-log": "^2.0.0", + "plugin-error": "^2.0.0", + "semver": "^7.3.8", + "ternary-stream": "^3.0.0", + "vinyl-fs": "^3.0.3" + }, + "dependencies": { + "fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "dev": true, + "requires": { + "color-support": "^1.1.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "plugin-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.0.tgz", + "integrity": "sha512-o4bwIOmuFwUg2MU6xt7plGEQY3YyENx6kvwaFZBrUpamA91FdS9w3U+pU0y4OuDoBQe+jf3RLGSfQebSRBEVsQ==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "gulp-imagemin": { @@ -24602,9 +25031,9 @@ "optional": true }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "image-size": { @@ -24676,6 +25105,16 @@ "svgo": "^1.3.2" } }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", @@ -24721,87 +25160,6 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -25118,6 +25476,12 @@ "dev": true, "optional": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -25347,6 +25711,12 @@ "resolved": "https://registry.npmjs.org/jquery-ui-touch-punch/-/jquery-ui-touch-punch-0.2.3.tgz", "integrity": "sha1-7tgiQnM7okP0az6HwYQbMIGR2mg=" }, + "js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -25538,12 +25908,6 @@ "yargs": "^16.1.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -25684,15 +26048,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -26004,6 +26359,15 @@ } } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -26108,6 +26472,12 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -26160,12 +26530,6 @@ "requires": { "ms": "2.1.2" } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true } } }, @@ -26490,7 +26854,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "dev": true, + "optional": true }, "mimic-response": { "version": "1.0.1", @@ -26606,12 +26971,6 @@ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", "dev": true }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", @@ -26741,7 +27100,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "dev": true, + "optional": true }, "node-fetch": { "version": "2.6.7", @@ -27155,6 +27515,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "optional": true, "requires": { "mimic-fn": "^2.1.0" } @@ -27213,12 +27574,6 @@ "lcid": "^1.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -27250,6 +27605,24 @@ "dev": true, "optional": true }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "p-map-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", @@ -27406,7 +27779,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "dev": true, + "optional": true }, "path-parse": { "version": "1.0.7", @@ -27959,12 +28333,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -28276,9 +28644,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { @@ -28422,6 +28790,12 @@ "global-modules": "^1.0.0" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "resolve-options": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", @@ -28447,16 +28821,6 @@ "lowercase-keys": "^1.0.0" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -28480,16 +28844,11 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, + "optional": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -28596,15 +28955,6 @@ } } }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -28729,6 +29079,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, + "optional": true, "requires": { "shebang-regex": "^1.0.0" } @@ -28737,7 +29088,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "dev": true, + "optional": true }, "shellwords": { "version": "0.1.1", @@ -28761,7 +29113,8 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "dev": true, + "optional": true }, "simple-swizzle": { "version": "0.2.2", @@ -28786,25 +29139,6 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -28990,11 +29324,6 @@ "sort-keys": "^1.0.0" } }, - "sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -29322,23 +29651,6 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, "string.prototype.trimend": { @@ -29364,18 +29676,18 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true } } @@ -29519,43 +29831,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, "tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -29590,6 +29865,53 @@ "uuid": "^3.0.1" } }, + "ternary-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz", + "integrity": "sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==", + "dev": true, + "requires": { + "duplexify": "^4.1.1", + "fork-stream": "^0.0.4", + "merge-stream": "^2.0.0", + "through2": "^3.0.1" + }, + "dependencies": { + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dev": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, "terser": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", @@ -29625,7 +29947,8 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "dev": true, + "optional": true }, "through2": { "version": "2.0.5", @@ -29689,15 +30012,6 @@ "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.2.0.tgz", "integrity": "sha512-zLjbFrg0hbtJ6PxmZUjQY6zyIOM/mLrWGTvhBec7XwYwoW1E0xXMQzy2tgMTh3OvJpsclgqf2ZMjmwcv4Cludw==" }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -29857,12 +30171,6 @@ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", "dev": true }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -29889,9 +30197,9 @@ } }, "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "type-is": { @@ -30185,12 +30493,6 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -30509,15 +30811,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", @@ -30653,6 +30946,12 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 3f13149e8f..1c79ddbc8c 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -10,7 +10,8 @@ "build:dev": "gulp buildDev", "dev": "gulp dev", "fastdev": "gulp fastdev", - "watch": "gulp watch" + "watch": "gulp watch", + "lint": "eslint src" }, "engines": { "node": ">=16.17", @@ -49,7 +50,6 @@ "moment": "2.29.4", "ng-file-upload": "12.2.13", "nouislider": "15.6.1", - "sortablejs": "1.15.0", "spectrum-colorpicker2": "2.0.9", "tinymce": "6.2.0", "typeahead.js": "0.11.1", @@ -61,13 +61,14 @@ "@babel/preset-env": "7.19.1", "autoprefixer": "10.4.4", "cssnano": "5.1.13", + "eslint": "8.28.0", "gulp": "4.0.2", "gulp-angular-embed-templates": "2.3.0", "gulp-babel": "8.0.0", "gulp-clean-css": "4.3.0", "gulp-cli": "2.3.0", "gulp-concat": "2.6.1", - "gulp-eslint": "6.0.0", + "gulp-eslint-new": "1.7.0", "gulp-imagemin": "7.1.0", "gulp-less": "5.0.0", "gulp-minify": "3.1.0", diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js index 301e542ec3..989c051e03 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js @@ -129,7 +129,8 @@ Use this directive to render a button with a dropdown of alternative actions. size: "@?", icon: "@?", label: "@?", - labelKey: "@?" + labelKey: "@?", + disabled: " x.entityKey === $scope.content.key).length > 0; + })); + evts.push(eventsService.on("rte.file.uploading", function () { $scope.page.saveButtonState = "busy"; $scope.page.buttonGroupState = "busy"; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagethumbnail.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagethumbnail.directive.js index b1bb603ace..1ac5c5fdf3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagethumbnail.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagethumbnail.directive.js @@ -89,8 +89,6 @@ angular.module("umbraco.directives") var xy = cropperHelper.alignToCoordinates(p, scope.center, {width: scope.width, height: scope.height}); p.top = xy.top; p.left = xy.left; - }else{ - } p.position = "absolute"; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js index f7ba043ef1..f02178064a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js @@ -342,8 +342,7 @@ Opens an overlay to show a custom YSOD.
if (clickableElements.indexOf(activeElementType) >= 0) { // don't do anything, let the browser Enter key handle this } else if (activeElementType === "TEXTAREA" && !submitOnEnter) { - - + // don't do anything } else if (submitOnEnter && submitOnEnterValue === "false") { // don't do anything } else { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblightbox.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblightbox.directive.js index 8a0d6875b2..5272abc46f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblightbox.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblightbox.directive.js @@ -132,13 +132,6 @@ if(scope.onClose) { scope.onClose(); focusLockService.removeInertAttribute(); - - if(previousElement){ - setTimeout(function(){ - previousElement.focus(); - previousElement = null; - }, 200); - } } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js index cc480efea5..c073c89141 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js @@ -203,12 +203,9 @@ Use this directive to generate a thumbnail grid of media items. } else { return scope.onlyFolders !== "true"; } - - return false; - } - function setOriginalSize(item, maxHeight) { + function setOriginalSize(item) { //set to a square by default item.width = itemDefaultWidth; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 9381940c74..03bccfdf74 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -12,14 +12,7 @@ angular.module("umbraco.directives") //Select the node that will be observed for mutations (native DOM element not jQLite version) var targetNode = element[0]; - //Watch for DOM changes - so when the property editor subview loads in - //We can be notified its updated the child elements inside the DIV we are watching - var observer = new MutationObserver(domChange); - - // Options for the observer (which mutations to observe) - var config = { attributes: true, childList: true, subtree: true }; - - function domChange(mutationsList, observer) { + const domChange = function(mutationsList) { for (var mutation of mutationsList) { //DOM items have been added or removed @@ -36,6 +29,13 @@ angular.module("umbraco.directives") } } + //Watch for DOM changes - so when the property editor subview loads in + //We can be notified its updated the child elements inside the DIV we are watching + var observer = new MutationObserver(domChange); + + // Options for the observer (which mutations to observe) + var config = { attributes: true, childList: true, subtree: true }; + // Start observing the target node for configured mutations //GO GO GO observer.observe(targetNode, config); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js index d15ad6af51..d8ad5f8243 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js @@ -77,7 +77,7 @@ function valFormManager(serverValidationManager, $rootScope, $timeout, $location // not found, then fallback to searching the scope chain, this may be needed when DOM inheritance isn't maintained but scope // inheritance is (i.e.infinite editing) - var found = angularHelper.traverseScopeChain(scope, s => s && s.valFormManager && s.valFormManager.constructor.name === "ValFormManagerController"); + found = angularHelper.traverseScopeChain(scope, s => s && s.valFormManager && s.valFormManager.constructor.name === "ValFormManagerController"); return found ? found.valFormManager : null; } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js index f9e2af584f..86afda1233 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js @@ -160,7 +160,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel collectAllNgModelControllersRecursively(ctrl.$getControls(), ngModels); } } - else if (ctrl.hasOwnProperty('$modelValue') && Utilities.isObject(ctrl.$validators)) { + else if (Object.prototype.hasOwnProperty.call(ctrl, '$modelValue') && Utilities.isObject(ctrl.$validators)) { ngModels.push(ctrl); } }); @@ -267,12 +267,12 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel // subscribing to this single watch. // TODO: Really? Since valFormManager is watching a countof all errors which is more overhead than watching formCtrl.$invalid // and there's a TODO there that it should just watch formCtrl.$invalid - valFormManager.onValidationStatusChanged(function (evt, args) { + valFormManager.onValidationStatusChanged(function () { checkValidationStatus(); }); //listen for the forms saving event - unsubscribe.push(scope.$on("formSubmitting", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitting", function () { showValidation = true; if (hasError && scope.errorMsg === "") { scope.errorMsg = getErrorMsg(); @@ -284,7 +284,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel })); //listen for the forms saved event - unsubscribe.push(scope.$on("formSubmitted", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitted", function () { showValidation = false; resetError(); })); @@ -299,7 +299,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel // indicate that a content property is invalid at the property level since developers may not actually implement // the correct field validation in their property editors. - function serverValidationManagerCallback(isValid, propertyErrors, allErrors) { + const serverValidationManagerCallback = function(isValid, propertyErrors) { var hadError = hasError; hasError = !isValid; if (hasError) { diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js index 8293443dd4..a9b65f826a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js @@ -42,7 +42,7 @@ angular.module('umbraco.mocks'). /** Creats a mock content object */ getMockContent: function (id, key, udi) { key = key || String.CreateGuid(); - var udi = udi || udiService.build("content", key); + udi = udi || udiService.build("content", key); var node = { name: "My content with id: " + id, updateDate: new Date().toIsoDateTimeString(), @@ -288,7 +288,7 @@ angular.module('umbraco.mocks'). /** Creats a mock variant content object */ getMockVariantContent: function(id, key, udi) { key = key || String.CreateGuid(); - var udi = udi || udiService.build("content", key); + udi = udi || udiService.build("content", key); var node = { name: "My content with id: " + id, updateDate: new Date().toIsoDateTimeString(), diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js index 7abefedfab..51029234f5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js @@ -1,5 +1,6 @@ //create the namespace (NOTE: This loads before any dependencies so we don't have a namespace mgr so we just create it manually) -var Umbraco = {}; +// eslint-disable-next-line no-redeclare +var Umbraco = Umbraco || {}; Umbraco.Sys = {}; //define a global static object Umbraco.Sys.ServerVariables = { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js index 91d74e1efd..bc3ffb666a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js @@ -428,8 +428,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) { renameContainer: function (id, name) { return umbRequestHelper.resourcePromise( - $http.post - (umbRequestHelper.getApiUrl( + $http.post(umbRequestHelper.getApiUrl( "dataTypeApiBaseUrl", "PostRenameContainer", { id: id, name: encodeURIComponent(name) })), diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/dictionary.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/dictionary.resource.js index fd81668d04..0d7db8159b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/dictionary.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/dictionary.resource.js @@ -3,7 +3,7 @@ * @name umbraco.resources.dictionaryResource * @description Loads in data for dictionary items **/ -function dictionaryResource($q, $http, $location, umbRequestHelper, umbDataFormatter) { +function dictionaryResource($http, umbRequestHelper, umbDataFormatter, localizationService, notificationsService) { /** * @ngdoc method diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js index 3b2618a82b..a3c96cf805 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js @@ -176,9 +176,9 @@ function entityResource($q, $http, umbRequestHelper) { "GetUrlsByIds", query), { - ids: ids + ids: udis }), - 'Failed to retrieve url map for ids ' + ids); + 'Failed to retrieve url map for ids ' + udis); }, getUrlByUdi: function (udi, culture) { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index 79f35d0d74..f7bba87ad5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -121,6 +121,22 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter, locali 'Failed to retrieve all content types'); }, + getAllFiltered: function (aliases) { + var aliasesQuery = ""; + + if (aliases && aliases.length > 0) { + aliases.forEach(alias => aliasesQuery += `aliases=${alias}&`); + } + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "getAllFiltered", + aliasesQuery)), + 'Failed to retrieve media types'); + }, + getScaffold: function (parentId) { return umbRequestHelper.resourcePromise( diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/ourpackagerrepository.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/ourpackagerrepository.resource.js index 430f05c2c4..60ceebb207 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/ourpackagerrepository.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/ourpackagerrepository.resource.js @@ -2,8 +2,9 @@ * @ngdoc service * @name umbraco.resources.ourPackageRepositoryResource * @description handles data for package installations + * @deprecated This resource is deprecated and will be removed in future versions. Umbraco no longer supports the Our Umbraco repository. **/ -function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHelper) { +function ourPackageRepositoryResource($http, umbRequestHelper) { var baseurl = Umbraco.Sys.ServerVariables.umbracoUrls.packagesRestApiBaseUrl; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js b/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js index b474b66174..8149e45ee8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js @@ -75,7 +75,7 @@ angular.module('umbraco.services') function getLocales(locales, supportedLocales, path) { var localeUrls = []; - var locales = locales.split(','); + locales = locales.split(','); for (var i = 0; i < locales.length; i++) { var locale = locales[i].toString().toLowerCase(); if (locale !== 'en-us') { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/help.service.js b/src/Umbraco.Web.UI.Client/src/common/services/help.service.js index cd727ac32b..1d541b8028 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/help.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/help.service.js @@ -7,7 +7,7 @@ angular.module('umbraco.services') function getCachedHelp(url){ if(helpTopics[url]){ - return helpTopics[cacheKey]; + return helpTopics[url]; }else{ return null; } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js index 139418f1c9..e0cb92beb3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/macro.service.js @@ -32,7 +32,7 @@ function macroService() { macroAlias: alias, macroParamsDictionary: {} }; - while (paramMatch = paramExpression.exec(paramsChunk)) { + while ((paramMatch = paramExpression.exec(paramsChunk))) { returnVal.macroParamsDictionary[paramMatch[1]] = paramMatch[2]; } return returnVal; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js b/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js index 7856714ccd..86956da6da 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js @@ -32,7 +32,6 @@ function umbracoMenuActions(treeService, $location, navigationService, appState, "DisableUser": function(args) { localizationService.localize("defaultdialogs_confirmdisable").then(function (txtConfirmDisable) { - var currentMenuNode = UmbClientMgr.mainTree().getActionNode(); if (confirm(txtConfirmDisable + ' "' + args.entity.name + '"?\n\n')) { usersResource.disableUser(args.entity.id).then(function () { navigationService.syncTree({ tree: args.treeAlias, path: [args.entity.parentId, args.entity.id], forceReload: true }); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index 81d1818448..77b97545b6 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -220,7 +220,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService * utility to clear the querystring/search params while maintaining a known list of parameters that should be maintained throughout the app */ clearSearch: function (toRetain) { - var toRetain = _.union(retainedQueryStrings, toRetain); + toRetain = _.union(retainedQueryStrings, toRetain); var currentSearch = $location.search(); $location.search(''); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 8614173af8..fb8cf12ea2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -139,6 +139,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s } promises.push(stylesheetResource.getRulesByName(val).then(function (rules) { + var split; rules.forEach(function (rule) { var r = {}; r.title = rule.name; @@ -151,12 +152,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s r.attributes = { id: rule.selector.substring(1) }; } else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) { - var split = rule.selector.split("."); + split = rule.selector.split("."); r.block = split[0]; r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(/\./g, " "); } else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) { - var split = rule.selector.split("#"); + split = rule.selector.split("#"); r.block = split[0]; r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1); } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js index b419600653..1141a0f1a1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js @@ -391,6 +391,7 @@ function umbRequestHelper($http, $q, notificationsService, eventsService, formHe var octetStreamMime = 'application/octet-stream'; var success = false; + var blob, url; // Get the headers var headers = response.headers(); @@ -405,7 +406,7 @@ function umbRequestHelper($http, $q, notificationsService, eventsService, formHe try { // Try using msSaveBlob if supported - var blob = new Blob([response.data], { type: contentType }); + blob = new Blob([response.data], { type: contentType }); if (navigator.msSaveBlob) navigator.msSaveBlob(blob, filename); else { @@ -430,8 +431,8 @@ function umbRequestHelper($http, $q, notificationsService, eventsService, formHe // Try to simulate a click try { // Prepare a blob URL - var blob = new Blob([response.data], { type: contentType }); - var url = urlCreator.createObjectURL(blob); + blob = new Blob([response.data], { type: contentType }); + url = urlCreator.createObjectURL(blob); link.setAttribute('href', url); // Set the download attribute (Supported in Chrome 14+ / Firefox 20+) @@ -454,8 +455,8 @@ function umbRequestHelper($http, $q, notificationsService, eventsService, formHe try { // Prepare a blob URL // Use application/octet-stream when using window.location to force download - var blob = new Blob([response.data], { type: octetStreamMime }); - var url = urlCreator.createObjectURL(blob); + blob = new Blob([response.data], { type: octetStreamMime }); + url = urlCreator.createObjectURL(blob); window.location = url; success = true; } catch (ex) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/uploadtracker.service.js b/src/Umbraco.Web.UI.Client/src/common/services/uploadtracker.service.js new file mode 100644 index 0000000000..46d5543afa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/uploadtracker.service.js @@ -0,0 +1,54 @@ +/** +* @ngdoc service +* @name umbraco.services.uploadTracker +* @description a helper to keep track of uploads in progress +**/ +function uploadTracker(eventsService) { + + const uploadsInProgress = []; + const events = {}; + + /** + * @ngdoc function + * @name umbraco.services.uploadTracker#uploadStarted + * @methodOf umbraco.services.uploadTracker + * @function + * + * @description + * Called when an upload is started to inform listeners that an upload is in progress. This will raise the uploadTracker.uploadsInProgressChanged event. + * + * @param {string} entityKey The key of the entity where the upload is taking place + */ + function uploadStarted (entityKey) { + const uploadDetails = { + entityKey + }; + + uploadsInProgress.push(uploadDetails); + eventsService.emit('uploadTracker.uploadsInProgressChanged', { uploadsInProgress }); + } + + /** + * @ngdoc function + * @name umbraco.services.uploadTracker#uploadEnded + * @methodOf umbraco.services.uploadTracker + * @function + * + * @description + * Called when an upload is ended to inform listeners that an upload has stopped. This will raise the uploadTracker.uploadsInProgressChanged event. + * + * @param {string} entityKey The key of the entity where the upload has stopped. + */ + function uploadEnded (entityKey) { + const index = uploadsInProgress.findIndex(upload => upload.entityKey === entityKey); + uploadsInProgress.splice(index, 1); + eventsService.emit('uploadTracker.uploadsInProgressChanged', { uploadsInProgress }); + } + + return { + uploadStarted, + uploadEnded + }; +} + +angular.module('umbraco.services').factory('uploadTracker', uploadTracker); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/services/urlhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/urlhelper.service.js index a6a22bab03..7bac830bd1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/urlhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/urlhelper.service.js @@ -95,7 +95,7 @@ var query = location ? location.substring(1) : $window.location.search.substring(1); var urlParams = {}; - while (match = search.exec(query)) { + while ((match = search.exec(query))) { urlParams[decode(match[1])] = decode(match[2]); } diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 918f3377ae..765be4f4b9 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -1,5 +1,5 @@ /** Executed when the application starts, binds to events and set global state */ -app.run(['$rootScope', '$route', '$location', '$cookies', 'urlHelper', 'appState', 'assetsService', 'eventsService', 'tourService', 'localStorageService', 'navigationService', 'localizationService', +window.app.run(['$rootScope', '$route', '$location', '$cookies', 'urlHelper', 'appState', 'assetsService', 'eventsService', 'tourService', 'localStorageService', 'navigationService', 'localizationService', function ($rootScope, $route, $location, $cookies, urlHelper, appState, assetsService, eventsService, tourService, localStorageService, navigationService, localizationService) { //This sets the default jquery ajax headers to include our csrf token, we @@ -63,7 +63,6 @@ app.run(['$rootScope', '$route', '$location', '$cookies', 'urlHelper', 'appState appState.setGlobalState("isReady", true); //send the ready event with the included returnToPath,returnToSearch data eventsService.emit("app.ready", data); - returnToPath = null, returnToSearch = null; } var currentRouteParams = null; diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js index 30d42299b5..af25608ef7 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js @@ -6,7 +6,7 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseControll $scope.dbs = $scope.installer.current.model.databases; window.dbs = $scope.dbs; - $scope.providerNames = _.chain(dbs) + $scope.providerNames = _.chain(window.dbs) .map('providerName') .filter(x => x) .uniq() @@ -16,7 +16,7 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseControll $scope.selectedDbMeta = $scope.dbs[0]; } - $scope.$watch('selectedDbMeta', function(newValue, oldValue) { + $scope.$watch('selectedDbMeta', function(newValue) { $scope.installer.current.model.integratedAuth = false; $scope.installer.current.model.databaseProviderMetadataId = newValue.id; $scope.installer.current.model.providerName = newValue.providerName; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less index 589a3bfe91..14cfa5f007 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less @@ -1,3 +1,41 @@ +[data-element="editor-packages"] { + .umb-pane { + height: 100%; + margin: 0; + + .umb-pane-content, + .umb-editor-sub-views { + height: 100%; + + .umb-editor-sub-view { + padding: 20px; + } + + .sub-view-Marketplace { + height: 100%; + margin: 0; + padding: 0; + + .umb-editor-sub-view__content { + height: 100%; + } + } + } + } +} + +.umb-marketplace-view-wrapper { + height: 100%; + display: flex; + align-items: stretch; +} + +.umb-marketplace-view { + width: 100%; + height: 100%; + overflow: hidden; +} + .umb-packages-view-title { font-size: 20px; font-weight: bold; diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index 93122792d3..7e65346d1b 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -1,11 +1,11 @@ -app.config(function ($routeProvider) { +window.app.config(function ($routeProvider) { /** * This determines if the route can continue depending on authentication and initialization requirements * @param {boolean} authRequired If true, it checks if the user is authenticated and will resolve successfully otherwise the route will fail and the $routeChangeError event will execute, in that handler we will redirect to the rejected path that is resolved from this method and prevent default (prevent the route from executing) - * @returns {promise} + * @returns {promise} */ var canRoute = function(authRequired) { diff --git a/src/Umbraco.Web.UI.Client/src/utilities.js b/src/Umbraco.Web.UI.Client/src/utilities.js index 14e37ecb87..9ed93998b2 100644 --- a/src/Umbraco.Web.UI.Client/src/utilities.js +++ b/src/Umbraco.Web.UI.Client/src/utilities.js @@ -116,6 +116,254 @@ return obj; }; + const MediaUploader = function (Upload, mediaHelper, mediaTypeHelper, localizationService, overlayService, mediaTypeResource) { + const umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; + const allowedUploadFiles = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles); + const allowedImageFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); + const allowedFileTypes = `${allowedUploadFiles},${allowedImageFileTypes}`; + const disallowedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles); + const maxFileSize = umbracoSettings.maxFileSize !== '' ? `${umbracoSettings.maxFileSize} KB` : ''; + + const events = {}; + const translations = {}; + + let initialized = false; + let uploadURL = ''; + let allowedMediaTypes = []; + let queue = []; + let invalidEntries = []; + + function init (options) { + uploadURL = options.uploadURL; + + return new Promise((resolve, reject) => { + const promises = [ + mediaTypeResource.getAllFiltered(options.allowedMediaTypeAliases), + localizationService.localizeMany(["media_disallowedFileType", "media_maxFileSize", "defaultdialogs_selectMediaType"]) + ]; + + Promise.all(promises).then(values => { + const mediaTypes = values[0]; + const translationValues = values[1]; + + allowedMediaTypes = mediaTypes; + translations.disallowedFileType = translationValues[0]; + translations.maxFileSize = translationValues[1] + " " + maxFileSize; + translations.selectMediaTypeDialogTitle = translationValues[2]; + initialized = true; + resolve(); + }, (reason) => { + reject(reason); + }); + }); + } + + function requestUpload (files) { + if (!initialized) { + throw 'MediaUploader is not initialized'; + } + + const validBatch = []; + const uploadItems = createUploadItemsFromFiles(files); + + // Validate based on server allowed file types + uploadItems.forEach(item => { + const isAllowedFileType = Upload.validatePattern(item.file, allowedFileTypes); + const isDisallowedFileType = Upload.validatePattern(item.file, disallowedFileTypes); + const underMaxFileSize = maxFileSize ? validateMaxFileSize(item.file, maxFileSize) : true; + + if (isAllowedFileType && !isDisallowedFileType && underMaxFileSize) { + _acceptMediaEntry(item.mediaEntry); + validBatch.push(item); + return; + } + + if (!isAllowedFileType || isDisallowedFileType) { + _rejectMediaEntry(item.mediaEntry, { type: 'pattern', message: translations.disallowedFileType }); + return; + } + + if (!underMaxFileSize) { + _rejectMediaEntry(item.mediaEntry, { type: 'maxSize', message: translations.maxFileSize }); + return; + } + }); + + _addItemsToQueue(validBatch); + _emit('queueStarted'); + _processQueue(); + } + + function _acceptMediaEntry (mediaEntry) { + _emit('mediaEntryAccepted', { mediaEntry }); + } + + function _rejectMediaEntry (mediaEntry, reason) { + mediaEntry.error = true; + mediaEntry.errorType = {}; + mediaEntry.errorType[reason.type] = true; + mediaEntry.errorText = reason.message; + + invalidEntries.push(mediaEntry); + _emit('mediaEntryRejected', { mediaEntry }); + } + + function createUploadItemsFromFiles (files) { + // angular complains about "Illegal invocation" if the file is part of the model.value + // so we have to keep them separate + return files.map(file => { + const mediaEntry = { + key: String.CreateGuid(), + name: file.name, + $uploadProgress: 0, + $dataURL: '' + }; + + if (file.type.includes('image')) { + Upload.base64DataUrl(file).then(function(url) { + mediaEntry.$dataURL = url; + }); + } else { + mediaEntry.$extension = mediaHelper.getFileExtension(file.name); + } + + return { + mediaEntry, + file + }; + }); + }; + + function validateMaxFileSize (file, val) { + return file.size - 0.1 <= Upload.translateScalars(val); + } + + function _upload(queueItem) { + const mediaEntry = queueItem.mediaEntry; + + _emit('uploadStarted', { mediaEntry }); + Upload.upload({ + url: uploadURL, + file: queueItem.file + }) + .progress(function(evt) { + var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10); + mediaEntry.$uploadProgress = progressPercentage; + }) + .success(function (data) { + _emit('uploadSuccess', { mediaEntry, ...data }); + _processQueue(); + }) + .error(function(error) { + _emit('uploadError', { mediaEntry }); + _rejectMediaEntry(mediaEntry, { type: 'server', message: error.Message }); + _processQueue(); + }); + } + + function _addItemsToQueue (queueItems) { + queue = [...queue, ...queueItems]; + } + + function _processQueue () { + const nextItem = queue.shift(); + + // queue is empty + if (!nextItem) { + _emit('queueCompleted'); + return; + } + + _getMatchedMediaType(nextItem.file).then(mediaType => { + nextItem.mediaEntry.mediaTypeAlias = mediaType.alias; + nextItem.mediaEntry.$icon = mediaType.icon; + _upload(nextItem); + }, () => { + _rejectMediaEntry(nextItem.mediaEntry, { type: 'pattern', message: translations.disallowedFileType }); + _processQueue(); + }); + } + + function _getMatchedMediaType(file) { + return new Promise((resolve, reject) => { + const uploadFileExtension = mediaHelper.getFileExtension(file.name); + const matchedMediaTypes = mediaTypeHelper.getTypeAcceptingFileExtensions(allowedMediaTypes, [uploadFileExtension]); + + if (matchedMediaTypes.length === 0) { + reject(); + return; + }; + + if (matchedMediaTypes.length === 1) { + resolve(matchedMediaTypes[0]); + return; + }; + + // when we get all media types, the "File" media type will always show up because it accepts all file extensions. + // If we don't remove it from the list we will always show the picker. + const matchedMediaTypesNoFile = matchedMediaTypes.filter(mediaType => mediaType.alias !== "File"); + if (matchedMediaTypesNoFile.length === 1) { + resolve(matchedMediaTypesNoFile[0]); + return; + }; + + if (matchedMediaTypes.length > 1) { + _chooseMediaTypeDialog(matchedMediaTypes, file) + .then((selectedMediaType) => { + resolve(selectedMediaType); + }, () => { + reject(); + }); + }; + }); + } + + function _chooseMediaTypeDialog(mediaTypes, file) { + return new Promise((resolve, reject) => { + const dialog = { + view: "itempicker", + filter: mediaTypes.length > 8, + availableItems: mediaTypes, + submit: function (model) { + resolve(model.selectedItem); + overlayService.close(); + }, + close: function () { + reject(); + overlayService.close(); + } + }; + + dialog.title = translations.selectMediaTypeDialogTitle; + dialog.subtitle = file.name; + overlayService.open(dialog); + }); + } + + function _emit(name, data) { + if (!events[name]) return; + events[name].forEach(callback => callback({name}, data)); + } + + function on(name, callback) { + if (typeof callback !== 'function') return; + + const unsubscribe = function () { + events[name] = events[name].filter(cb => cb !== callback); + } + + events[name] = events[name] || []; + events[name].push(callback); + return unsubscribe; + } + + return { + init, + requestUpload, + on + } + } + let _utilities = { noop: noop, copy: copy, @@ -130,7 +378,8 @@ isObject: isObject, fromJson: fromJson, toJson: toJson, - forEach: forEach + forEach: forEach, + MediaUploader: MediaUploader }; if (typeof (window.Utilities) === 'undefined') { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index 732127ffa0..e777e91e29 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -44,6 +44,20 @@ angular.module("umbraco") function updateMedia() { + if (!vm.mediaEntry.mediaKey) { + vm.imageSrc = vm.mediaEntry.$dataURL; + vm.fileSrc = vm.mediaEntry.$dataURL; + vm.loading = false; + vm.hasDimensions = false; + vm.isCroppable = false; + vm.fileExtension = 'JPG'; + + localizationService.localize("mediaPicker_editMediaEntryLabel", [vm.mediaEntry.name, vm.model.documentName]).then(data => { + vm.title = data; + }); + return; + } + vm.loading = true; entityResource.getById(vm.mediaEntry.mediaKey, "Media").then(function (mediaEntity) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index a56e3aeed6..45a463f8bf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -93,13 +93,13 @@
- - diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js index 72eb504c60..ac929fcb3a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js @@ -545,7 +545,7 @@ angular.module("umbraco").controller("Umbraco.Editors.TreePickerController", //we need to ensure that any currently displayed nodes that get selected // from the search get updated to have a check box! - function checkChildren(children) { + const checkChildren = function(children) { children.forEach(child => { //check if the id is in the selection, if so ensure it's flagged as selected var exists = vm.searchInfo.selectedSearchResults.find(selected => child.id === selected.id); diff --git a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-button-group.html b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-button-group.html index bb310441bf..2a4a43769d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-button-group.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-button-group.html @@ -1,5 +1,4 @@
- + add-ellipsis={{defaultButton.addEllipsis}} + disabled="disabled"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html index ab7274df6f..0c5ad35b04 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html @@ -39,7 +39,8 @@ button-style="link" label-key="general_close" shortcut="esc" - type="button"> + type="button" + disabled="page.uploadsInProgress"> + label-key="buttons_saveAndPreview" + disabled="page.uploadsInProgress"> + add-ellipsis="{{page.saveButtonEllipsis}}" + disabled="page.uploadsInProgress"> + label="More publishing options" + disabled="page.uploadsInProgress"> + type="button" + disabled="page.uploadsInProgress"> + type="button" + disabled="page.uploadsInProgress"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-container.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-container.html index aa1765f365..2def207c70 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-container.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-container.html @@ -6,6 +6,6 @@
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-sub-views.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-sub-views.html index a0f56ee883..56c7a9cf48 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-sub-views.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-sub-views.html @@ -1,17 +1,12 @@
- -
- -
-
- -
- +
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index 3d06c8b16f..c0b6cd9e79 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -3,9 +3,7 @@ umb-media-card { position: relative; display: inline-block; width: 100%; - //background-color: white; border-radius: @baseBorderRadius; - //box-shadow: 0 1px 2px rgba(0,0,0,.2); overflow: hidden; transition: box-shadow 120ms; cursor: pointer; @@ -194,3 +192,32 @@ umb-media-card { } } } + + +.umb-media-card { + .__upload-progress-container { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + backdrop-filter: blur(2px); + background-color: rgba(255,255,255,.7); + display: flex; + align-items: center; + justify-content: center; + + .__upload-progress { + width: 66%; + margin-top: 13px; + } + + .__upload-progress-label { + font-size: 13px; + margin-top: 3px; + } + } +} + diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js index f5fd3bfd9c..d0de742205 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js @@ -1,99 +1,99 @@ (function () { - "use strict"; + "use strict"; - function PackagesOverviewController($scope, $location, $routeParams, localizationService, localStorageService) { + function PackagesOverviewController($location, $routeParams, localizationService, localStorageService) { - //Hack! - // if there is a local storage value for packageInstallData then we need to redirect there, - // the issue is that we still have webforms and we cannot go to a hash location and then window.reload - // because it will double load it. - // we will refresh and then navigate there. + //Hack! + // if there is a local storage value for packageInstallData then we need to redirect there, + // the issue is that we still have webforms and we cannot go to a hash location and then window.reload + // because it will double load it. + // we will refresh and then navigate there. - let packageInstallData = localStorageService.get("packageInstallData"); - let packageUri = $routeParams.method; + let packageInstallData = localStorageService.get("packageInstallData"); + let packageUri = $routeParams.method; - if (packageInstallData) { - localStorageService.remove("packageInstallData"); + if (packageInstallData) { + localStorageService.remove("packageInstallData"); - if (packageInstallData.postInstallationPath) { - //navigate to the custom installer screen if set - $location.path(packageInstallData.postInstallationPath).search("packageId", packageInstallData.id); - return; - } + if (packageInstallData.postInstallationPath) { + //navigate to the custom installer screen if set + $location.path(packageInstallData.postInstallationPath).search("packageId", packageInstallData.id); + return; + } - //if it is "installed" then set the uri/path to that - if (packageInstallData === "installed") { - packageUri = "installed"; - } - } - - var vm = this; - vm.page = {}; - vm.page.labels = {}; - vm.page.name = ""; - vm.page.navigation = []; - - onInit(); - - function onInit() { - - loadNavigation(); - - setPageName(); - } - - function loadNavigation() { - - var labels = ["sections_packages", "packager_installed", "packager_installLocal", "packager_created"]; - - localizationService.localizeMany(labels).then(function (data) { - vm.page.labels.packages = data[0]; - vm.page.labels.installed = data[1]; - vm.page.labels.install = data[2]; - vm.page.labels.created = data[3]; - - vm.page.navigation = [ - { - "name": vm.page.labels.packages, - "icon": "icon-cloud", - "view": "views/packages/views/repo.html", - "active": !packageUri || packageUri === "repo", - "alias": "umbPackages", - "action": function () { - $location.path("/packages/packages/repo"); - } - }, - { - "name": vm.page.labels.installed, - "icon": "icon-box", - "view": "views/packages/views/installed.html", - "active": packageUri === "installed", - "alias": "umbInstalled", - "action": function () { - $location.path("/packages/packages/installed"); - } - }, - { - "name": vm.page.labels.created, - "icon": "icon-files", - "view": "views/packages/views/created.html", - "active": packageUri === "created", - "alias": "umbCreatedPackages", - "action": function () { - $location.path("/packages/packages/created"); - } - } - ]; - }); - } - - function setPageName() { - localizationService.localize("sections_packages").then(function (data) { - vm.page.name = data; - }) - } + //if it is "installed" then set the uri/path to that + if (packageInstallData === "installed") { + packageUri = "installed"; + } } - angular.module("umbraco").controller("Umbraco.Editors.Packages.OverviewController", PackagesOverviewController); + var vm = this; + vm.page = {}; + vm.page.labels = {}; + vm.page.name = ""; + vm.page.navigation = []; + + onInit(); + + function onInit() { + + loadNavigation(); + + setPageName(); + } + + function loadNavigation() { + + var labels = ["sections_marketplace", "packager_installed", "packager_installLocal", "packager_created"]; + + localizationService.localizeMany(labels).then(function (data) { + vm.page.labels.marketplace = data[0]; + vm.page.labels.installed = data[1]; + vm.page.labels.install = data[2]; + vm.page.labels.created = data[3]; + + vm.page.navigation = [ + { + "name": vm.page.labels.marketplace, + "icon": "icon-cloud", + "view": "views/packages/views/marketplace.html", + "active": !packageUri || packageUri === "repo", + "alias": "umbMarketplace", + "action": function () { + $location.path("/packages/packages/repo"); + } + }, + { + "name": vm.page.labels.installed, + "icon": "icon-box", + "view": "views/packages/views/installed.html", + "active": packageUri === "installed", + "alias": "umbInstalled", + "action": function () { + $location.path("/packages/packages/installed"); + } + }, + { + "name": vm.page.labels.created, + "icon": "icon-files", + "view": "views/packages/views/created.html", + "active": packageUri === "created", + "alias": "umbCreatedPackages", + "action": function () { + $location.path("/packages/packages/created"); + } + } + ]; + }); + } + + function setPageName() { + localizationService.localize("sections_marketplace").then(function (data) { + vm.page.name = data; + }) + } + } + + angular.module("umbraco").controller("Umbraco.Editors.Packages.OverviewController", PackagesOverviewController); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.controller.js new file mode 100644 index 0000000000..f2a4deb2c1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.controller.js @@ -0,0 +1,18 @@ +(function () { + "use strict"; + + function MarketplaceController($sce) { + + var vm = this; + var marketplaceUrl = new URL(Umbraco.Sys.ServerVariables.umbracoUrls.marketplaceUrl); + + function init() { + vm.marketplaceUrl = $sce.trustAsResourceUrl(marketplaceUrl.toString()); + } + + init(); + } + + angular.module("umbraco").controller("Umbraco.Editors.Packages.MarketplaceController", MarketplaceController); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.html b/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.html new file mode 100644 index 0000000000..95a28061b4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/marketplace.html @@ -0,0 +1,13 @@ +
+ +
diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js deleted file mode 100644 index 0c7a2bd91c..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js +++ /dev/null @@ -1,265 +0,0 @@ -(function () { - "use strict"; - - function PackagesRepoController($scope, $timeout, ourPackageRepositoryResource, $q, localizationService, notificationsService) { - - var vm = this; - - vm.packageViewState = "packageList"; - vm.categories = []; - vm.loading = true; - vm.pagination = { - pageNumber: 1, - totalPages: 10, - pageSize: 24 - }; - vm.searchQuery = ""; - vm.selectCategory = selectCategory; - vm.showPackageDetails = showPackageDetails; - vm.setPackageViewState = setPackageViewState; - vm.nextPage = nextPage; - vm.prevPage = prevPage; - vm.goToPage = goToPage; - vm.openLightbox = openLightbox; - vm.closeLightbox = closeLightbox; - vm.search = search; - vm.installCompleted = false; - vm.highlightedPackageCollections = []; - vm.labels = {}; - - var defaultSort = "Latest"; - var currSort = defaultSort; - - //used to cancel any request in progress if another one needs to take it's place - var canceler = null; - - function getActiveCategory() { - if (vm.searchQuery !== "") { - return ""; - } - for (var i = 0; i < vm.categories.length; i++) { - if (vm.categories[i].active === true) { - return vm.categories[i].name; - } - } - return ""; - } - - function init() { - - vm.loading = true; - localizationService.localizeMany(["packager_packagesPopular", "packager_packagesPromoted"]) - .then(function (labels) { - vm.labels.popularPackages = labels[0]; - vm.labels.promotedPackages = labels[1]; - - var popularPackages, promotedPackages; - $q.all([ - ourPackageRepositoryResource.getCategories() - .then(function (cats) { - vm.categories = cats.filter(function (cat) { - return cat.name !== "Umbraco Pro"; - }); - }), - ourPackageRepositoryResource.getPopular(10) - .then(function (pack) { - popularPackages = { title: vm.labels.popularPackages, packages: pack.packages }; - }), - ourPackageRepositoryResource.getPromoted(20) - .then(function (pack) { - promotedPackages = { title: vm.labels.promotedPackages, packages: pack.packages }; - }), - ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1, vm.pagination.pageSize, currSort) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - }) - ]) - .then(function () { - vm.highlightedPackageCollections = [popularPackages, promotedPackages]; - vm.loading = false; - }); - }); - } - - function selectCategory(selectedCategory, categories) { - - for (var i = 0; i < categories.length; i++) { - var category = categories[i]; - if (category.name === selectedCategory.name) { - //it's already selected, let's unselect to show all again - if (category.active === true) { - category.active = false; - } - else { - category.active = true; - } - } - else { - category.active = false; - } - } - - vm.loading = true; - vm.searchQuery = ""; - - var reset = selectedCategory.active === false; - var searchCategory = reset ? "" : selectedCategory.name; - - currSort = defaultSort; - - var popularPackages, promotedPackages; - $q.all([ - ourPackageRepositoryResource.getPopular(10, searchCategory) - .then(function (pack) { - popularPackages = { title: vm.labels.popularPackages, packages: pack.packages }; - }), - ourPackageRepositoryResource.getPromoted(20, searchCategory) - .then(function (pack) { - promotedPackages = { title: vm.labels.promotedPackages, packages: pack.packages }; - }), - ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1, vm.pagination.pageSize, currSort, searchCategory, vm.searchQuery) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - vm.pagination.pageNumber = 1; - }) - ]) - .then(function () { - vm.highlightedPackageCollections = [popularPackages, promotedPackages]; - vm.loading = false; - }); - } - - function showPackageDetails(selectedPackage) { - ourPackageRepositoryResource.getDetails(selectedPackage.id) - .then(function (pack) { - vm.package = pack; - vm.packageViewState = "packageDetails"; - }); - } - - function setPackageViewState(state) { - if (state) { - vm.packageViewState = state; - } - } - - function nextPage(pageNumber) { - ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, currSort, getActiveCategory(), vm.searchQuery) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - }); - } - - function prevPage(pageNumber) { - ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, currSort, getActiveCategory(), vm.searchQuery) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - }); - } - - function goToPage(pageNumber) { - ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, currSort, getActiveCategory(), vm.searchQuery) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - }); - } - var previousElement = null; - - function openLightbox(itemIndex, items) { - - previousElement = ( document.activeElement || document.body ); - - vm.lightbox = { - show: true, - items: items, - activeIndex: itemIndex, - focus: true - }; - } - - function closeLightbox() { - vm.lightbox.show = false; - vm.lightbox = null; - - if(previousElement){ - setTimeout(function(){ - previousElement.focus(); - previousElement = null; - }, 100) - } - document.activeElement.blur(); - } - - - var searchDebounced = _.debounce(function (e) { - //a canceler exists, so perform the cancelation operation and reset - if (canceler) { - canceler.resolve(); - } - - canceler = $q.defer(); - - $scope.$apply(function () { - currSort = vm.searchQuery ? "Default" : "Latest"; - - ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1, - vm.pagination.pageSize, - currSort, - "", - vm.searchQuery, - canceler.promise) - .then(function (pack) { - vm.packages = pack.packages; - vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize); - vm.pagination.pageNumber = 1; - vm.loading = false; - //set back to null so it can be re-created - canceler = null; - }) - .catch(function (err) { - canceler = null; - - if (err) { - // If an abort happened, ignore it since it happened because of a new search - if (err.xhrStatus === 'abort') { - return; - } - - // Otherwise, show the error - if (err.errorMsg) { - notificationsService.error(err.errorMsg); - return; - } - } - - console.error(err); - }); - - }); - - }, 200); - - function search(searchQuery) { - vm.loading = true; - searchDebounced(); - } - - vm.reloadPage = function () { - //reload on next digest (after cookie) - $timeout(function () { - window.location.reload(true); - }); - } - - init(); - - } - - angular.module("umbraco").controller("Umbraco.Editors.Packages.RepoController", PackagesRepoController); - -})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.html b/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.html deleted file mode 100644 index 3ed1216d52..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.html +++ /dev/null @@ -1,318 +0,0 @@ -
- - - - -
- -
- -
- -
-
- -
-
- -
- -
-
-

{{highlightedPackageCollection.title}}

-
- -
- -
- -
-
-
- -
- -

New Releases

-

Results for '{{ vm.searchQuery }}'

- -
- -
- -
- -
-
- -
- - - - -
- - - -

We couldn't find anything for '{{ vm.searchQuery }}'

-

Please try searching for another package or browse through the categories.

-
- - -

Sorry, we can not find what you are looking for.

-

Please try searching for another package or browse through the categories.

-
- -
- -
- - - -
- - - - - - - -
- -
- -
- - - -

{{ vm.package.name }}

-
- -
-
- - - - -
- -
- - - -
Install Instructions
-
- dotnet add package {{vm.package.nuGetPackageId}} -
-
-
- - - -
- -
- - -
- -
-
{{ vm.package.ownerInfo.owner }}
-
- {{ vm.package.ownerInfo.owner }} has {{ vm.package.ownerInfo.karma }} karma points -
-
-
-
-
- - - -
Information
-
- -
-
Owner:
-
{{vm.package.ownerInfo.owner}}
-
- -
-
Contributors:
-
- {{ contributor }} -
-
- -
-
Created:
-
{{vm.package.created | date:'yyyy-MM-dd HH:mm:ss'}}
-
- -
-
Current version:
-
{{vm.package.latestVersion}}
-
- -
-
.NET Version:
-
{{vm.package.information.netVersion}}
-
- -
-
License:
-
{{vm.package.licenseName}}
-
- -
-
Downloads:
-
{{vm.package.downloads}}
-
- -
-
Likes:
-
{{vm.package.likes}}
-
- -
-
Verified to work on Umbraco CLoud
-
- -
-
-
- - - -
Compatibility
-
This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100%
-
-
- {{compatibility.version}} - ({{compatibility.percentage}}%) -
- - -
-
-
- - - -
External sources
- -
-
- -
- -
-
-
- -
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js index c3f0314389..b7a38e562e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js @@ -27,15 +27,17 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.ColorPickerControl if (!isValidHex(oldValue.value || oldValue)) continue; + var hexCode; + if (oldValue.hasOwnProperty("value")) { - var hexCode = toFullHex(oldValue.value); + hexCode = toFullHex(oldValue.value); items.push({ value: hexCode.substr(1, hexCode.length), label: oldValue.label, id: i }); } else { - var hexCode = toFullHex(oldValue); + hexCode = toFullHex(oldValue); items.push({ value: hexCode.substr(1, hexCode.length), label: oldValue, diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridentryeditors/gridinlineblock/gridinlineblock.editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridentryeditors/gridinlineblock/gridinlineblock.editor.html index 3a67a1be88..71c4da4178 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridentryeditors/gridinlineblock/gridinlineblock.editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridentryeditors/gridinlineblock/gridinlineblock.editor.html @@ -71,7 +71,11 @@ min-height: 48px; height: auto; } - + + .blockelement-gridinlineblock-editor > slot { + --umb-block-grid--inline-editor--pointer-events--condition: var(--umb-block-grid--dragging-mode) none; + pointer-events: var(--umb-block-grid--inline-editor--pointer-events--condition, auto); + } @@ -100,6 +104,6 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridui.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridui.less index b6205d73ac..693108f05d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridui.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/blockgridui.less @@ -188,7 +188,8 @@ ng-form.ng-invalid-val-server-match-content > .umb-block-grid__block:not(.--acti &.--active { /** Avoid displaying hover when dragging-mode */ - --umb-block-grid--block-ui-opacity: calc(1 - var(--umb-block-grid--dragging-mode, 0)); + --umb-block-grid--block-ui-opacity--condition: var(--umb-block-grid--dragging-mode) 0; + --umb-block-grid--block-ui-opacity: var(--umb-block-grid--block-ui-opacity--code, 1); > .umb-block-grid__block--context { opacity: var(--umb-block-grid--block-ui-opacity); @@ -222,8 +223,8 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl .umb-block-grid__block--context { position: absolute; - top: -20px; - right: 0; + top: -21px; + right: -1px; font-size: 12px; z-index: 4; display: var(--umb-block-grid--block-ui-display, flex); @@ -244,6 +245,9 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl padding-top: 1px; background-color: #3544B1; color: white; + border-top: rgba(255, 255, 255, .7) 1px solid; + border-left: rgba(255, 255, 255, .7) 1px solid; + border-right: rgba(255, 255, 255, .7) 1px solid; border-top-left-radius: 3px; border-top-right-radius: 3px; display: inline-block; @@ -366,6 +370,7 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl padding: 0; background-color: white; border: @blueDark solid 1px; + box-shadow: 0 0 0 1px rgba(255, 255, 255, .7); opacity: 0; transition: opacity 120ms; } @@ -412,15 +417,17 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl z-index: 1; /** overwritten for the first one of an area. */ /** Avoid showing inline-create in dragging-mode */ - opacity: calc(1 - var(--umb-block-grid--dragging-mode, 0)); + + --umb-block-grid__block--inline-create-button-display--condition: var(--umb-block-grid--dragging-mode) none; + display: var(--umb-block-grid__block--inline-create-button-display--condition); } .umb-block-grid__block--inline-create-button.--above { left: 0; - width: 100%; + width: var(--umb-block-grid-editor--inline-create-width, 100%); top: calc(var(--umb-block-grid--row-gap, 0px) * -0.5); } -.umb-block-grid__layout-item:first-of-type .umb-block-grid__block--inline-create-button.--above { +.umb-block-grid__layout-item:first-of-type > .umb-block-grid__block--inline-create-button.--above { /* Do not use row-gap if the first one. */ top: 0; } @@ -428,7 +435,7 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl /* If at root, and full-width then become 40px wider: */ --calc: clamp(0, calc(var(--umb-block-grid--item-column-span) - (var(--umb-block-grid--grid-columns)-1)), 1); left: calc(-20px * var(--calc)); - width: calc(100% + 40px * var(--calc)); + width: calc(var(--umb-block-grid-editor--inline-create-width, 100%) + 40px * var(--calc)); } .umb-block-grid__block--inline-create-button.--after { @@ -454,6 +461,10 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl /* Move inline create button slightly up, to avoid collision with others*/ margin-bottom: -7px; margin-top: -13px; + + /** Avoid showing last-inline-create in dragging-mode */ + --umb-block-grid__block--last-inline-create-button-display--condition: var(--umb-block-grid--dragging-mode) none; + display: var(--umb-block-grid__block--last-inline-create-button-display--condition); } @@ -553,6 +564,7 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl .umb-block-grid__area-actions { grid-column: span var(--umb-block-grid--area-column-span); + flex-grow: 1; opacity: calc(var(--umb-block-grid--hint-area-ui, 0) * .5 + var(--umb-block-grid--show-area-ui, 0)); transition: opacity 120ms; @@ -590,10 +602,12 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl } } + .umb-block-grid__layout-item-placeholder { background: transparent; border-radius: 3px; + box-sizing: border-box; border: solid 1px; border-color: rgba(@blueDark, .5); border-radius: 3px; @@ -601,9 +615,11 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl height: 100%; } + .umb-block-grid__layout-item-placeholder > * { display: none; } + .umb-block-grid__layout-item-placeholder::before { content: ''; position:absolute; @@ -611,6 +627,7 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl inset: 0; border-radius: 3px; background-color: white; + pointer-events:none; } .umb-block-grid__layout-item-placeholder::after { content: ''; @@ -618,6 +635,7 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl z-index:1; inset: 0; border-radius: 3px; + pointer-events:none; transition: background-color 240ms ease-in; animation: umb-block-grid__placeholder__pulse 400ms ease-in-out alternate infinite; @@ -630,7 +648,12 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl .umb-block-grid__area { position: relative; - --umb-block-grid--show-area-ui: 0; + height: 100%; + display: flex; + flex-direction: column; + + --umb-block-grid__area--show-area-ui--condition: var(--umb-block-grid--dragging-mode) 1; + --umb-block-grid--show-area-ui: var(--umb-block-grid__area--show-area-ui--condition, 0); } .umb-block-grid__area:focus, .umb-block-grid__area:focus-within, @@ -654,10 +677,9 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl /* Moved slightly in to align with the inline-create button, which is moved slightly in to avoid collision with other create buttons. */ top:2px; bottom: 2px; - /** Avoid displaying highlight when in dragging-mode */ - opacity: calc(1 - var(--umb-block-grid--dragging-mode, 0)); border-color: @blueDark; box-shadow: 0 0 0 1px rgba(255, 255, 255, .7), inset 0 0 0 1px rgba(255, 255, 255, .7); + } .umb-block-grid__area:has( .umb-block-grid__layout-item-placeholder )::after { opacity: 1; @@ -674,6 +696,9 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl 100% { border-color: rgba(@blueDark, 0.66); } } } +.umb-block-grid__area > ng-form { + display: contents; +} .umb-block-grid__scalebox-backdrop { position: absolute; @@ -740,4 +765,4 @@ ng-form.ng-invalid > .umb-block-grid__block:not(.--active) > .umb-block-grid__bl color: @errorText; border-radius: 0; border-top: 1px solid rgba(255, 255, 255, .2); -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.controller.js index f20f14f227..1c2f7e1c2b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.controller.js @@ -25,7 +25,7 @@ value: {min:vm.area.minAllowed, max:vm.area.maxAllowed} } - unsubscribe.push($scope.$watch('vm.area.alias', (newVal, oldVal) => { + unsubscribe.push($scope.$watch('vm.area.alias', (newVal) => { $scope.model.updateTitle(); if($scope.blockGridBlockConfigurationAreaForm.alias) { $scope.blockGridBlockConfigurationAreaForm.alias.$setValidity("alias", $scope.model.otherAreaAliases.indexOf(newVal) === -1); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.html index 90918d71e1..a4ba0db72e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.area.overlay.html @@ -13,7 +13,7 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.controller.js index ceb0a99a11..f24520dda6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.controller.js @@ -43,7 +43,6 @@ var unsubscribe = []; const vm = this; - vm.openBlock = null; vm.showSampleDataCTA = false; @@ -57,7 +56,6 @@ if (blockGroupModel.value == null) { blockGroupModel.value = []; } - vm.blockGroups = blockGroupModel.value; if (!$scope.model.value) { @@ -89,14 +87,13 @@ } } } - unsubscribe.push(eventsService.on("editors.documentType.saved", updateUsedElementTypes)); function removeReferencesToElementTypeKey(contentElementTypeKey) { // Clean up references to this one: $scope.model.value.forEach(blockType => { blockType.areas.forEach(area => { - area.specifiedAllowance = area.specifiedAllowance?.filter(allowance => + area.specifiedAllowance = area.specifiedAllowance?.filter(allowance => allowance.elementTypeKey !== contentElementTypeKey ) || []; }); @@ -107,7 +104,7 @@ // Clean up references to this one: $scope.model.value.forEach(blockType => { blockType.areas.forEach(area => { - area.specifiedAllowance = area.specifiedAllowance?.filter(allowance => + area.specifiedAllowance = area.specifiedAllowance?.filter(allowance => allowance.groupKey !== groupKey ) || []; }); @@ -156,7 +153,7 @@ }; vm.blockSortableOptions = { - ...defaultOptions, + ...defaultOptions, "ui-floating": true, connectWith: ".umb-block-card-grid", items: "umb-block-card", @@ -242,7 +239,6 @@ infiniteMode: true, noTemplate: true, isElement: true, - noTemplate: true, submit: function(model) { loadElementTypes().then(function() { callback(model.documentTypeKey); @@ -284,11 +280,11 @@ title: data, openAreas: openAreas, view: "views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.html", - size: "large", + size: "medium", submit: function(overlayModel) { loadElementTypes()// lets load elementType again, to ensure we are up to date. TransferProperties(overlayModel.block, block);// transfer properties back to block object. (Doing this cause we dont know if block object is added to model jet, therefor we cant use index or replace the object.) - + overlayModel.close(); }, close: function() { @@ -338,7 +334,7 @@ return false; } else { - return true; + return true; } } ); @@ -360,7 +356,6 @@ }); } } - dataTypeResource.getAll().then(function(dataTypes) { if (dataTypes.filter(x => x.alias === "Umbraco.BlockGrid").length === 0) { vm.showSampleDataCTA = true; @@ -383,7 +378,7 @@ }; vm.blockGroups.push(sampleGroup); } - + function initSampleBlock(udi, groupKey, options) { const key = udiService.getKey(udi); if ($scope.model.value.find(X => X.contentElementTypeKey === key) === undefined) { @@ -391,7 +386,7 @@ $scope.model.value.push(blockType); } } - + initSampleBlock(data.umbBlockGridDemoHeadlineBlock, sampleGroup.key, {"label": "Headline ({{headline | truncate:true:36}})", "view": "~/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoHeadlineBlock.html"}); initSampleBlock(data.umbBlockGridDemoImageBlock, sampleGroup.key, {"label": "Image", "view": "~/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoImageBlock.html"}); initSampleBlock(data.umbBlockGridDemoRichTextBlock, sampleGroup.key, { "label": "Rich Text ({{richText | ncRichText | truncate:true:36}})", "view": "~/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoRichTextBlock.html"}); @@ -416,10 +411,10 @@ } ]; initSampleBlock(data.umbBlockGridDemoTwoColumnLayoutBlock, sampleGroup.key, {"label": "Two Column Layout", "view": "~/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoTwoColumnLayoutBlock.html", "allowInAreas": false, "areas": twoColumnLayoutAreas}); - + vm.showSampleDataCTA = false; }); - + }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.controller.js index 0bb9f6e703..11a0972309 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.controller.js @@ -93,7 +93,7 @@ var elementTypeId = elementType.id; const editor = { id: elementTypeId, - submit: function (model) { + submit: function () { editorService.close(); }, close: function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.html index 4d398844ed..85668c0786 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.html @@ -15,9 +15,9 @@ -
+
-
+
General @@ -80,124 +80,9 @@
- - -
- -
-
- Size options - - Define one or more size options, this enables resizing of the Block - -
-
- -
- - - - -
-
- - - Define the different number of layout columns this block is allowed to span across. - -
- -
-
-
- - -
-
- - - Define the range of layout rows this block is allowed to span across. - -
- -
-
-
- -
- -
- -
- -
- Catalogue appearance -
- -
- - - - -
-
- -
- - -
-
-
- - -
-
- -
- - -
-
-
- - -
-
- -
-
- - -
- -
-
- -
-
-
- -
- -
- - -
+
Permissions @@ -244,11 +129,61 @@
+ + + +
+ +
+
+ Size options + + Define one or more size options, this enables resizing of the Block + +
+
+ +
+ + + + +
+
+ + + Define the different number of layout columns this block is allowed to span across. + +
+ +
+
+
+ + +
+
+ + + Define the range of layout rows this block is allowed to span across. + +
+ +
+
+
+ +
+ +
+
-
+
@@ -288,7 +223,7 @@
-
+
Advanced @@ -384,6 +319,66 @@
+
+ +
+ Catalogue appearance +
+ +
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ +
+
+ + +
+ +
+
+ +
+
+
+ +
+ +
@@ -413,4 +408,4 @@ -
\ No newline at end of file +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.less index 57507f8044..5861cfdda5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/blockgrid.blockconfiguration.overlay.less @@ -1,28 +1,5 @@ .umb-block-grid-block-configuration-overlay { - .umb-block-grid-block-configuration-layout { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - - grid-gap: 0 20px; - grid-auto-flow: row; - grid-auto-rows: minmax(50px, auto); - - - } - - - .umb-block-grid-block-configuration__umb-group-panel { - @media (max-width: 1024px) { - grid-column: span 2; - } - &.--span-two-cols { - grid-column: span 2; - } - &.--span-two-rows { - grid-row: span 2; - } - } .umb-node-preview { flex-grow: 1; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html index 64a7909b7a..7ee2ee6344 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html @@ -2,33 +2,40 @@ -
+
- -
+ +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.less index bf66c34661..4f5d45c67c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.less @@ -217,6 +217,9 @@ Grid part: display: flex; align-items: center; justify-content: center; + + height:50px; + width:100%; color: @ui-action-discreet-type; font-weight: bold; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-column-editor-option.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-column-editor-option.html index ab63757bb5..05f55d3a07 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-column-editor-option.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-column-editor-option.html @@ -18,7 +18,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-configuration-area-entry.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-configuration-area-entry.html index b479890d75..9909b640a1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-configuration-area-entry.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-configuration-area-entry.html @@ -4,18 +4,18 @@
- -
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaAllowanceEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaAllowanceEditor.component.js index 693cdcc223..9729ddd85b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaAllowanceEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaAllowanceEditor.component.js @@ -27,7 +27,7 @@ } }); - function BlockGridAreaAllowanceController($scope, $element, assetsService, localizationService, editorService) { + function BlockGridAreaAllowanceController($scope) { var unsubscribe = []; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaEditor.component.js index 9126a6cc54..914e701fa6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridAreaEditor.component.js @@ -1,6 +1,44 @@ (function () { "use strict"; + + // Utils: + + function getInterpolatedIndexOfPositionInWeightMap(target, weights) { + const map = [0]; + weights.reduce((a, b, i) => { return map[i+1] = a+b; }, 0); + const foundValue = map.reduce((a, b) => { + let aDiff = Math.abs(a - target); + let bDiff = Math.abs(b - target); + + if (aDiff === bDiff) { + return a < b ? a : b; + } else { + return bDiff < aDiff ? b : a; + } + }) + const foundIndex = map.indexOf(foundValue); + const targetDiff = (target-foundValue); + let interpolatedIndex = foundIndex; + if (targetDiff < 0 && foundIndex === 0) { + // Don't adjust. + } else if (targetDiff > 0 && foundIndex === map.length-1) { + // Don't adjust. + } else { + const foundInterpolationWeight = weights[targetDiff >= 0 ? foundIndex : foundIndex-1]; + interpolatedIndex += foundInterpolationWeight === 0 ? interpolatedIndex : (targetDiff/foundInterpolationWeight) + } + return interpolatedIndex; + } + + function getAccumulatedValueOfIndex(index, weights) { + let i = 0, len = Math.min(index, weights.length), calc = 0; + while(i modelEntry.key === el.dataset.areaKey, + querySelectModelToElement: (container, modelEntry) => container.querySelector(`[data-area-key='${modelEntry.key}']`), + itemHasNestedContainersResolver: () => false,// We never have nested in this case. + containerSelector: ".umb-block-grid-area-editor__grid-wrapper", + itemSelector: ".umb-block-grid-area-editor__area", + placeholderClass: "umb-block-grid-area-editor__area-placeholder", + onSync: onSortSync } - const gridContainerEl = $element[0].querySelector('.umb-block-grid-area-editor__grid-wrapper'); + function onSortSync() { + $scope.$evalAsync(); + setDirty(); + } - const sortable = Sortable.create(gridContainerEl, { - sort: true, // sorting inside list - animation: 150, // ms, animation speed moving items when sorting, `0` — without animation - easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples. - cancel: '', - draggable: ".umb-block-grid-area-editor__area", // Specifies which items inside the element should be draggable - ghostClass: "umb-block-grid-area-editor__area-placeholder", - onAdd: function (evt) { - _sync(evt); - $scope.$evalAsync(); - }, - onUpdate: function (evt) { - _sync(evt); - $scope.$evalAsync(); + function resolveVerticalDirection(data) { + + /** We need some data about the grid to figure out if there is room to be placed next to the found element */ + const approvedContainerComputedStyles = getComputedStyle(data.containerElement); + const gridColumnGap = Number(approvedContainerComputedStyles.columnGap.split("px")[0]) || 0; + const gridColumnNumber = vm.rootLayoutColumns; + + const foundElColumns = parseInt(data.relatedElement.dataset.colSpan, 10); + const currentElementColumns = data.item.columnSpan; + + if(currentElementColumns >= gridColumnNumber) { + return true; } - }); - - // TODO: setDirty if sort has happend. + + // Get grid template: + const approvedContainerGridColumns = approvedContainerComputedStyles.gridTemplateColumns.trim().split("px").map(x => Number(x)).filter(n => n > 0).map((n, i, list) => list.length === i ? n : n + gridColumnGap); + + // ensure all columns are there. + // This will also ensure handling non-css-grid mode, + // use container width divided by amount of columns( or the item width divided by its amount of columnSpan) + let amountOfColumnsInWeightMap = approvedContainerGridColumns.length; + const amountOfUnknownColumns = gridColumnNumber-amountOfColumnsInWeightMap; + if(amountOfUnknownColumns > 0) { + let accumulatedValue = getAccumulatedValueOfIndex(amountOfColumnsInWeightMap, approvedContainerGridColumns) || 0; + const layoutWidth = data.containerRect.width; + const missingColumnWidth = (layoutWidth-accumulatedValue)/amountOfUnknownColumns; + if(missingColumnWidth > 0) { + while(amountOfColumnsInWeightMap++ < gridColumnNumber) { + approvedContainerGridColumns.push(missingColumnWidth); + } + } + } + + let offsetPlacement = 0; + /* If placeholder is in this same line, we want to assume that it will offset the placement of the found element, + which provides more potential space for the item to drop at. + This is relevant in this calculation where we look at the space to determine if its a vertical or horizontal drop in relation to the found element. + */ + if(data.placeholderIsInThisRow && data.elementRect.left < data.relatedRect.left) { + offsetPlacement = -(data.elementRect.width + gridColumnGap); + } + + const relatedStartX = Math.max(data.relatedRect.left - data.containerRect.left + offsetPlacement, 0); + const relatedStartCol = Math.round(getInterpolatedIndexOfPositionInWeightMap(relatedStartX, approvedContainerGridColumns)); + + // If the found related element does not have enough room after which for the current element, then we go vertical mode: + return (relatedStartCol + (data.horizontalPlaceAfter ? foundElColumns : 0) + currentElementColumns > gridColumnNumber); + + } + } @@ -93,7 +164,6 @@ } vm.requestDeleteArea = function (area) { - // TODO: Translations localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockAreaMessage", "blockEditor_confirmDeleteBlockAreaNotice"]).then(function (data) { overlayService.confirmDelete({ title: data[0], @@ -145,8 +215,6 @@ vm.openArea = null; vm.openAreaOverlay = function (area) { - - // TODO: use the right localization key: localizationService.localize("blockEditor_blockConfigurationOverlayTitle").then(function (localized) { var clonedAreaData = Utilities.copy(area); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridColumnEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridColumnEditor.component.js index 864f479009..1dcbc5b2da 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridColumnEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridColumnEditor.component.js @@ -25,9 +25,7 @@ } }); - function BlockGridColumnController($scope) { - - //var unsubscribe = []; + function BlockGridColumnController() { var vm = this; @@ -58,12 +56,6 @@ } } - /*$scope.$on("$destroy", function () { - for (const subscription of unsubscribe) { - subscription(); - } - });*/ - } })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridConfigurationAreaEntry.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridConfigurationAreaEntry.component.js index f7c1351c47..64d5e421e2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridConfigurationAreaEntry.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umbBlockGridConfigurationAreaEntry.component.js @@ -2,9 +2,7 @@ "use strict"; /** - * * Note for new backoffice: there is a lot of similarities between the Area configuration and the Block entry, as they both share Grid scaling features. - * TODO: Can we already as part of this PR make it shared as a dictionary or something? */ @@ -100,6 +98,13 @@ function updateGridLayoutData() { + if(!layoutContainer) { + layoutContainer = $element[0].closest('.umb-block-grid-area-editor__grid-wrapper'); + if(!layoutContainer) { + console.error($element[0], 'could not find area-container'); + } + } + const computedStyles = window.getComputedStyle(layoutContainer); gridColumns = computedStyles.gridTemplateColumns.trim().split("px").map(x => Number(x)); @@ -126,12 +131,6 @@ window.addEventListener('mouseup', vm.onMouseUp); window.addEventListener('mouseleave', vm.onMouseUp); - - layoutContainer = $element[0].closest('.umb-block-grid-area-editor__grid-wrapper'); - if(!layoutContainer) { - console.error($element[0], 'could not find area-container'); - } - updateGridLayoutData(); scaleBoxBackdropEl = document.createElement('div'); @@ -217,6 +216,8 @@ vm.scaleHandlerKeyUp = function($event) { + updateGridLayoutData(); + let addCol = 0; let addRow = 0; @@ -236,7 +237,7 @@ } // Todo: Ensure value fit with configuration. - vm.area.columnSpan = Math.max(vm.area.columnSpan + addCol, 1); + vm.area.columnSpan = Math.min(Math.max(vm.area.columnSpan + addCol, 1), gridColumns.length); vm.area.rowSpan = Math.max(vm.area.rowSpan + addRow, 1); $event.originalEvent.stopPropagation(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umb-block-grid-entries.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umb-block-grid-entries.html index 4aed670ffd..ef02d28318 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umb-block-grid-entries.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umb-block-grid-entries.html @@ -2,9 +2,10 @@