diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs index ff43d39..1a9d6f9 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs @@ -43,7 +43,7 @@ namespace FileTime.ConsoleUI.App.UI if (paneState == null) throw new Exception($"{nameof(paneState)} can not be null"); Tab = pane; - Tab.CurrentLocationChanged.Add((_, _) => { _currentDisplayStartY = 0; return Task.CompletedTask; }); + Tab.CurrentLocationChanged.Add((_, _, _) => { _currentDisplayStartY = 0; return Task.CompletedTask; }); TabState = paneState; } @@ -70,7 +70,7 @@ namespace FileTime.ConsoleUI.App.UI if (currentLocation.GetParent() is var parentContainer && parentContainer is not null) { - await parentContainer.Refresh(); + await parentContainer.RefreshAsync(); await PrintColumn( currentVirtualContainer != null @@ -96,7 +96,7 @@ namespace FileTime.ConsoleUI.App.UI if (token.IsCancellationRequested) return; - await currentLocation.Refresh(); + await currentLocation.RefreshAsync(); await CheckAndSetCurrentDisplayStartY(); await PrintColumn( @@ -112,7 +112,7 @@ namespace FileTime.ConsoleUI.App.UI if (currentSelectedItem is IContainer selectedContainer) { - await selectedContainer.Refresh(); + await selectedContainer.RefreshAsync(); selectedContainer = currentVirtualContainer != null ? currentVirtualContainer.CloneVirtualChainFor(selectedContainer, v => v.IsTransitive) diff --git a/src/Core/AsyncEvent/AsyncEventHandler.cs b/src/Core/AsyncEvent/AsyncEventHandler.cs index 2064a37..8b9a6e2 100644 --- a/src/Core/AsyncEvent/AsyncEventHandler.cs +++ b/src/Core/AsyncEvent/AsyncEventHandler.cs @@ -2,55 +2,68 @@ { public class AsyncEventHandler { - private readonly List> _handlers; - private readonly Action> _add; - private readonly Action> _remove; + private readonly object _guard = new(); + private readonly List> _handlers; + private readonly Action> _add; + private readonly Action> _remove; - public IReadOnlyList> Handlers { get; } + public IReadOnlyList> Handlers { get; } - public AsyncEventHandler(Action>? add = null, Action>? remove = null) + public AsyncEventHandler(Action>? add = null, Action>? remove = null) { - _handlers = new List>(); + _handlers = new List>(); Handlers = _handlers.AsReadOnly(); _add = add ?? AddInternal; _remove = remove ?? RemoveInternal; } - public void Add(Func handler) + public void Add(Func handler) { - _add.Invoke(handler); + lock (_guard) + { + _add.Invoke(handler); + } } - public void Remove(Func handler) + public void Remove(Func handler) { - _remove.Invoke(handler); + lock (_guard) + { + _remove.Invoke(handler); + } } - private void AddInternal(Func handler) + private void AddInternal(Func handler) { _handlers.Add(handler); } - private void RemoveInternal(Func handler) + private void RemoveInternal(Func handler) { _handlers.Remove(handler); } - public async Task InvokeAsync(TSender sender, TArg args) + public async Task InvokeAsync(TSender sender, TArg args, CancellationToken token = default) { - foreach(var handler in _handlers) + List>? handlers; + lock (_guard) { - await handler(sender, args); + handlers = _handlers; + } + + foreach (var handler in handlers) + { + await handler(sender, args, token); } } - public static AsyncEventHandler operator +(AsyncEventHandler obj, Func handler) + public static AsyncEventHandler operator +(AsyncEventHandler obj, Func handler) { obj.Add(handler); return obj; } - public static AsyncEventHandler operator -(AsyncEventHandler obj, Func handler) + public static AsyncEventHandler operator -(AsyncEventHandler obj, Func handler) { obj.Remove(handler); return obj; @@ -58,11 +71,11 @@ } public class AsyncEventHandler : AsyncEventHandler { - public AsyncEventHandler(Action>? add = null, Action>? remove = null) : base(add, remove) { } + public AsyncEventHandler(Action>? add = null, Action>? remove = null) : base(add, remove) { } } public class AsyncEventHandler : AsyncEventHandler { - public AsyncEventHandler(Action>? add = null, Action>? remove = null) : base(add, remove) { } + public AsyncEventHandler(Action>? add = null, Action>? remove = null) : base(add, remove) { } } } diff --git a/src/Core/FileTime.Core/Components/Tab.cs b/src/Core/FileTime.Core/Components/Tab.cs index 6174baa..6f651e4 100644 --- a/src/Core/FileTime.Core/Components/Tab.cs +++ b/src/Core/FileTime.Core/Components/Tab.cs @@ -11,6 +11,9 @@ namespace FileTime.Core.Components #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. private string? _lastPath; + private readonly object _guardSetCurrentSelectedItemCTS = new object(); + private CancellationTokenSource? _setCurrentSelectedItemCTS; + public int CurrentSelectedIndex { get; private set; } public AsyncEventHandler CurrentLocationChanged = new(); @@ -21,7 +24,7 @@ namespace FileTime.Core.Components await SetCurrentLocation(currentPath); } - public Task GetCurrentLocation() + public Task GetCurrentLocation(CancellationToken token = default) { return Task.FromResult(_currentLocation); } @@ -49,24 +52,36 @@ namespace FileTime.Core.Components return Task.FromResult(_currentSelectedItem); } - public async Task SetCurrentSelectedItem(IItem? value) + public async Task SetCurrentSelectedItem(IItem? value, bool secondary = false) { if (_currentSelectedItem != value) { IItem? itemToSelect = null; if (value != null) { - itemToSelect = (await _currentLocation.GetItems())?.FirstOrDefault(i => - i.FullName == null && value?.FullName == null + itemToSelect = (await _currentLocation.GetItems())?.FirstOrDefault(i => + i.FullName == null && value?.FullName == null ? i.Name == value?.Name : i.FullName == value?.FullName); if (itemToSelect == null) throw new IndexOutOfRangeException("Provided item does not exists in the current container."); } + CancellationToken newToken; + lock (_guardSetCurrentSelectedItemCTS) + { + _setCurrentSelectedItemCTS?.Cancel(); + _setCurrentSelectedItemCTS = new CancellationTokenSource(); + newToken = _setCurrentSelectedItemCTS.Token; + } + _currentSelectedItem = itemToSelect; _lastPath = GetCommonPath(_lastPath, itemToSelect?.FullName); - CurrentSelectedIndex = await GetItemIndex(itemToSelect); - await CurrentSelectedItemChanged.InvokeAsync(this, AsyncEventArgs.Empty); + + var newCurrentSelectedIndex = await GetItemIndex(itemToSelect, newToken); + if (newToken.IsCancellationRequested) return; + CurrentSelectedIndex = newCurrentSelectedIndex; + + await CurrentSelectedItemChanged.InvokeAsync(this, AsyncEventArgs.Empty, newToken); } } public async Task GetItemByLastPath(IContainer? container = null) @@ -85,21 +100,16 @@ namespace FileTime.Core.Components var itemNameToSelect = _lastPath .Split(Constants.SeparatorChar) - .Skip( - containerFullName == null - ? 0 - : containerFullName - .Split(Constants.SeparatorChar) - .Count()) + .Skip((containerFullName?.Split(Constants.SeparatorChar).Length) ?? 0) .FirstOrDefault(); return (await container.GetItems())?.FirstOrDefault(i => i.Name == itemNameToSelect); } - private string GetCommonPath(string? oldPath, string? newPath) + private static string GetCommonPath(string? oldPath, string? newPath) { - var oldPathParts = oldPath?.Split(Constants.SeparatorChar) ?? new string[0]; - var newPathParts = newPath?.Split(Constants.SeparatorChar) ?? new string[0]; + var oldPathParts = oldPath?.Split(Constants.SeparatorChar) ?? Array.Empty(); + var newPathParts = newPath?.Split(Constants.SeparatorChar) ?? Array.Empty(); var commonPathParts = new List(); @@ -126,13 +136,13 @@ namespace FileTime.Core.Components return string.Join(Constants.SeparatorChar, commonPathParts); } - private async Task HandleCurrentLocationRefresh(object? sender, AsyncEventArgs e) + private async Task HandleCurrentLocationRefresh(object? sender, AsyncEventArgs e, CancellationToken token = default) { var currentSelectedName = (await GetCurrentSelectedItem())?.FullName ?? (await GetItemByLastPath())?.FullName; - var currentLocationItems = (await (await GetCurrentLocation()).GetItems())!; + var currentLocationItems = (await (await GetCurrentLocation(token)).GetItems(token))!; if (currentSelectedName != null) { - await SetCurrentSelectedItem(currentLocationItems.FirstOrDefault(i => i.FullName == currentSelectedName) ?? currentLocationItems.FirstOrDefault()); + await SetCurrentSelectedItem(currentLocationItems.FirstOrDefault(i => i.FullName == currentSelectedName) ?? currentLocationItems[0]); } else if (currentLocationItems.Count > 0) { @@ -184,7 +194,7 @@ namespace FileTime.Core.Components if (await GetCurrentSelectedItem() != null) { - (await GetCurrentLocation())?.Refresh(); + (await GetCurrentLocation())?.RefreshAsync(); IItem? newSelectedItem = null; foreach (var item in currentPossibleItems) @@ -197,7 +207,7 @@ namespace FileTime.Core.Components } } - if(newSelectedItem != null) + if (newSelectedItem != null) { newSelectedItem = (await (await GetCurrentLocation()).GetItems())?.FirstOrDefault(i => i.Name == newSelectedItem.Name); } @@ -272,11 +282,12 @@ namespace FileTime.Core.Components public async Task OpenContainer(IContainer container) => await SetCurrentLocation(container); - private async Task GetItemIndex(IItem? item) + private async Task GetItemIndex(IItem? item, CancellationToken token) { if (item == null) return -1; - var currentLocationItems = (await (await GetCurrentLocation()).GetItems())!; + var currentLocationItems = (await (await GetCurrentLocation(token)).GetItems(token))!; + if (token.IsCancellationRequested) return -1; for (var i = 0; i < currentLocationItems.Count; i++) { if (currentLocationItems[i] == item) return i; diff --git a/src/Core/FileTime.Core/Models/IContainer.cs b/src/Core/FileTime.Core/Models/IContainer.cs index 2e377e8..36321a9 100644 --- a/src/Core/FileTime.Core/Models/IContainer.cs +++ b/src/Core/FileTime.Core/Models/IContainer.cs @@ -9,7 +9,7 @@ namespace FileTime.Core.Models Task?> GetContainers(CancellationToken token = default); Task?> GetElements(CancellationToken token = default); - Task Refresh(); + Task RefreshAsync(CancellationToken token = default); Task GetByPath(string path, bool acceptDeepestMatch = false); Task CreateContainer(string name); Task CreateElement(string name); diff --git a/src/Core/FileTime.Core/Models/VirtualContainer.cs b/src/Core/FileTime.Core/Models/VirtualContainer.cs index d5d86dc..0546e54 100644 --- a/src/Core/FileTime.Core/Models/VirtualContainer.cs +++ b/src/Core/FileTime.Core/Models/VirtualContainer.cs @@ -35,11 +35,11 @@ namespace FileTime.Core.Models public AsyncEventHandler Refreshed { get; } - private void RefreshAddBase(Func handler) + private void RefreshAddBase(Func handler) { BaseContainer.Refreshed.Add(handler); } - private void RefreshRemoveBase(Func handler) + private void RefreshRemoveBase(Func handler) { BaseContainer.Refreshed.Add(handler); } @@ -52,7 +52,7 @@ namespace FileTime.Core.Models bool isTransitive = false, string? virtualContainerName = null) { - Refreshed = new (RefreshAddBase, RefreshRemoveBase); + Refreshed = new(RefreshAddBase, RefreshRemoveBase); BaseContainer = baseContainer; _containerTransformators = containerTransformators; _elementTransformators = elementTransformators; @@ -67,10 +67,10 @@ namespace FileTime.Core.Models await InitItems(); } - private async Task InitItems() + private async Task InitItems(CancellationToken token = default) { - Containers = _containerTransformators.Aggregate((await BaseContainer.GetContainers())?.AsEnumerable(), (a, t) => t(a!))?.ToList()?.AsReadOnly(); - Elements = _elementTransformators.Aggregate((await BaseContainer.GetElements())?.AsEnumerable(), (a, t) => t(a!))?.ToList()?.AsReadOnly(); + Containers = _containerTransformators.Aggregate((await BaseContainer.GetContainers(token))?.AsEnumerable(), (a, t) => t(a!))?.ToList()?.AsReadOnly(); + Elements = _elementTransformators.Aggregate((await BaseContainer.GetElements(token))?.AsEnumerable(), (a, t) => t(a!))?.ToList()?.AsReadOnly(); Items = (Elements != null ? Containers?.Cast().Concat(Elements) @@ -82,10 +82,10 @@ namespace FileTime.Core.Models public IContainer? GetParent() => BaseContainer.GetParent(); - public async Task Refresh() + public async Task RefreshAsync(CancellationToken token = default) { - await BaseContainer.Refresh(); - await InitItems(); + await BaseContainer.RefreshAsync(token); + await InitItems(token); } public IContainer GetRealContainer() => diff --git a/src/Core/FileTime.Core/Providers/TopContainer.cs b/src/Core/FileTime.Core/Providers/TopContainer.cs index 3acbbe9..ce9e2b7 100644 --- a/src/Core/FileTime.Core/Providers/TopContainer.cs +++ b/src/Core/FileTime.Core/Providers/TopContainer.cs @@ -57,7 +57,7 @@ namespace FileTime.Core.Providers public Task IsExists(string name) => throw new NotImplementedException(); - public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + public async Task RefreshAsync(CancellationToken token = default) => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); public Task?> GetItems(CancellationToken token = default) => Task.FromResult(_items); public Task?> GetContainers(CancellationToken token = default) => Task.FromResult(_containers); diff --git a/src/Core/FileTime.Core/Timeline/TimeContainer.cs b/src/Core/FileTime.Core/Timeline/TimeContainer.cs index 59f7c9e..1221e07 100644 --- a/src/Core/FileTime.Core/Timeline/TimeContainer.cs +++ b/src/Core/FileTime.Core/Timeline/TimeContainer.cs @@ -103,7 +103,7 @@ namespace FileTime.Core.Timeline public async Task IsExists(string name) => (await GetItems())?.Any(i => i.Name == name) ?? false; - public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + public async Task RefreshAsync(CancellationToken token = default) => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); public Task Rename(string newName) => Task.CompletedTask; diff --git a/src/Core/FileTime.Core/Timeline/TimeProvider.cs b/src/Core/FileTime.Core/Timeline/TimeProvider.cs index 53db1f8..f7aadc3 100644 --- a/src/Core/FileTime.Core/Timeline/TimeProvider.cs +++ b/src/Core/FileTime.Core/Timeline/TimeProvider.cs @@ -84,7 +84,7 @@ namespace FileTime.Core.Timeline throw new NotImplementedException(); } - public Task Refresh() => Task.CompletedTask; + public Task RefreshAsync(CancellationToken token = default) => Task.CompletedTask; public Task Rename(string newName) => throw new NotSupportedException(); diff --git a/src/GuiApp/FileTime.Avalonia/Application/AppState.cs b/src/GuiApp/FileTime.Avalonia/Application/AppState.cs index b670312..5ed418d 100644 --- a/src/GuiApp/FileTime.Avalonia/Application/AppState.cs +++ b/src/GuiApp/FileTime.Avalonia/Application/AppState.cs @@ -6,6 +6,7 @@ using System.Linq; using FileTime.App.Core.Tab; using System.Threading.Tasks; using FileTime.Core.Models; +using System.Threading; namespace FileTime.Avalonia.Application { @@ -71,12 +72,13 @@ namespace FileTime.Avalonia.Application } } - private async Task TabItemMarked(TabState tabState, AbsolutePath item) + private async Task TabItemMarked(TabState tabState, AbsolutePath item, CancellationToken token = default) { var tabContainer = Tabs.FirstOrDefault(t => t.TabState == tabState); if (tabContainer != null) { - var item2 = (await tabContainer.CurrentLocation.GetItems()).FirstOrDefault(i => i.Item.FullName == item.Path); + var item2 = (await tabContainer.CurrentLocation.GetItems(token)).FirstOrDefault(i => i.Item.FullName == item.Path); + if (token.IsCancellationRequested) return; if (item2 != null) { item2.IsMarked = true; @@ -84,12 +86,13 @@ namespace FileTime.Avalonia.Application } } - private async Task TabItemUnmarked(TabState tabState, AbsolutePath item) + private async Task TabItemUnmarked(TabState tabState, AbsolutePath item, CancellationToken token = default) { var tabContainer = Tabs.FirstOrDefault(t => t.TabState == tabState); if (tabContainer != null) { - var item2 = (await tabContainer.CurrentLocation.GetItems()).FirstOrDefault(i => i.Item.FullName == item.Path); + var item2 = (await tabContainer.CurrentLocation.GetItems(token)).FirstOrDefault(i => i.Item.FullName == item.Path); + if (token.IsCancellationRequested) return; if (item2 != null) { item2.IsMarked = false; diff --git a/src/GuiApp/FileTime.Avalonia/Application/INewItemProcessor.cs b/src/GuiApp/FileTime.Avalonia/Application/INewItemProcessor.cs index e972a9d..b974aa8 100644 --- a/src/GuiApp/FileTime.Avalonia/Application/INewItemProcessor.cs +++ b/src/GuiApp/FileTime.Avalonia/Application/INewItemProcessor.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using FileTime.Avalonia.ViewModels; @@ -5,6 +6,6 @@ namespace FileTime.Avalonia.Application { public interface INewItemProcessor { - Task UpdateMarkedItems(ContainerViewModel containerViewModel); + Task UpdateMarkedItems(ContainerViewModel containerViewModel, CancellationToken token = default); } } \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs b/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs index ab76098..aee2e6e 100644 --- a/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs +++ b/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs @@ -10,7 +10,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using FileTime.App.Core.Tab; -using System.Collections.Generic; +using System.Threading; namespace FileTime.Avalonia.Application { @@ -40,21 +40,30 @@ namespace FileTime.Avalonia.Application private IItemViewModel? _selectedItem; + [Obsolete($"Use {nameof(SetSelectedItemAsync)} instead.")] public IItemViewModel? SelectedItem { get => _selectedItem; set { - if (_selectedItem != value)// && value != null + if (value != null) { - _selectedItem = value; - - OnPropertyChanged("SelectedItem"); - SelectedItemChanged().Wait(); + SetSelectedItemAsync(value, true).Wait(); } } } + public async Task SetSelectedItemAsync(IItemViewModel? value, bool fromDataBinding = false) + { + if (_selectedItem != value) + { + _selectedItem = value; + + OnPropertyChanged(nameof(SelectedItem)); + await Tab.SetCurrentSelectedItem(SelectedItem?.Item, fromDataBinding); + } + } + partial void OnInitialize() { _tabState = new TabState(Tab); @@ -96,18 +105,20 @@ namespace FileTime.Avalonia.Application return parent; } - private async Task Tab_CurrentLocationChanged(object? sender, AsyncEventArgs e) + private async Task Tab_CurrentLocationChanged(object? sender, AsyncEventArgs e, CancellationToken token = default) { - var currentLocation = await Tab.GetCurrentLocation(); + var currentLocation = await Tab.GetCurrentLocation(token); var parent = GenerateParent(currentLocation); CurrentLocation = new ContainerViewModel(this, parent, currentLocation, ItemNameConverterService); - await CurrentLocation.Init(); + await CurrentLocation.Init(token: token); + + if (token.IsCancellationRequested) return; if (parent != null) { parent.ChildrenToAdopt.Add(CurrentLocation); Parent = parent; - await Parent.Init(); + await Parent.Init(token: token); } else { @@ -115,42 +126,47 @@ namespace FileTime.Avalonia.Application } } - private async Task Tab_CurrentSelectedItemChanged(object? sender, AsyncEventArgs e) + private async Task Tab_CurrentSelectedItemChanged(object? sender, AsyncEventArgs e, CancellationToken token = default) { - await UpdateCurrentSelectedItem(); + await UpdateCurrentSelectedItem(token); } - public async Task UpdateCurrentSelectedItem() + public async Task UpdateCurrentSelectedItem(CancellationToken token = default) { try { var tabCurrentSelectenItem = await Tab.GetCurrentSelectedItem(); + + if (token.IsCancellationRequested) return; + IItemViewModel? currentSelectenItem = null; if (tabCurrentSelectenItem == null) { - SelectedItem = null; + await SetSelectedItemAsync(null); ChildContainer = null; } else { - currentSelectenItem = (await _currentLocation.GetItems()).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name); + currentSelectenItem = (await _currentLocation.GetItems(token)).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name); if (currentSelectenItem is ContainerViewModel currentSelectedContainer) { - SelectedItem = currentSelectedContainer; + await SetSelectedItemAsync(currentSelectedContainer); ChildContainer = currentSelectedContainer; } else if (currentSelectenItem is ElementViewModel element) { - SelectedItem = element; + await SetSelectedItemAsync(element); ChildContainer = null; } else { - SelectedItem = null; + await SetSelectedItemAsync(null); ChildContainer = null; } } + if (token.IsCancellationRequested) return; + var items = await _currentLocation.GetItems(); if (items?.Count > 0) { @@ -173,6 +189,7 @@ namespace FileTime.Avalonia.Application var child = item; while (child is ContainerViewModel containerViewModel && containerViewModel.Container.IsLoaded) { + if (token.IsCancellationRequested) return; var activeChildItem = await Tab.GetItemByLastPath(containerViewModel.Container); child = (await containerViewModel.GetItems()).FirstOrDefault(i => i.Item == activeChildItem); if (child != null) @@ -199,22 +216,13 @@ namespace FileTime.Avalonia.Application } } } - catch + catch { //INFO collection modified exception on: currentSelectenItem = (await _currentLocation.GetItems()).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name); //TODO: handle or error message } } - private async Task SelectedItemChanged() - { - try - { - await Tab.SetCurrentSelectedItem(SelectedItem?.Item); - } - catch { } - } - public async Task SetCurrentSelectedItem(IItem newItem) { try @@ -309,13 +317,14 @@ namespace FileTime.Avalonia.Application await _tabState.MakrCurrentItem(); } - public async Task UpdateMarkedItems(ContainerViewModel containerViewModel) + public async Task UpdateMarkedItems(ContainerViewModel containerViewModel, CancellationToken token = default) { if (containerViewModel == CurrentLocation && containerViewModel.Container.IsLoaded) { + if (token.IsCancellationRequested) return; var selectedItems = TabState.GetCurrentMarkedItems(containerViewModel.Container); - foreach (var item in await containerViewModel.GetItems()) + foreach (var item in await containerViewModel.GetItems(token)) { item.IsMarked = selectedItems.Any(c => c.Path == item.Item.FullName); } diff --git a/src/GuiApp/FileTime.Avalonia/IconProviders/MaterialIconProvider.cs b/src/GuiApp/FileTime.Avalonia/IconProviders/MaterialIconProvider.cs index ef88a6a..8ab83cb 100644 --- a/src/GuiApp/FileTime.Avalonia/IconProviders/MaterialIconProvider.cs +++ b/src/GuiApp/FileTime.Avalonia/IconProviders/MaterialIconProvider.cs @@ -9,9 +9,18 @@ namespace FileTime.Avalonia.IconProviders { public class MaterialIconProvider : IIconProvider { + + private static readonly Dictionary _iconsByExtension = new(); + private static readonly Dictionary _iconsByFileName = new(); + private readonly List _specialPaths = new(); public bool EnableAdvancedIcons { get; set; } = true; + static MaterialIconProvider() + { + InitMatches(); + } + public MaterialIconProvider() { _specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Desktop.Path, GetAssetPath("desktop.svg"))); @@ -46,13 +55,18 @@ namespace FileTime.Avalonia.IconProviders { return new ImagePath(ImagePathType.Absolute, localPath); } - icon = !element.Name.Contains('.') - ? icon - : element.Name.Split('.').Last() switch - { - "cs" => "csharp.svg", - _ => icon - }; + + string? possibleIcon = null; + var fileName = element.Name; + var extension = element.Name.Contains('.') ? element.Name.Split('.').Last() : null; + + if (_iconsByFileName.TryGetValue(fileName, out var value)) possibleIcon = value; + else if (_iconsByExtension.FirstOrDefault(k => fileName.EndsWith("." + k.Key)) is KeyValuePair matchingExtension && matchingExtension.Key != null) possibleIcon = matchingExtension.Value; + + if(possibleIcon != null) + { + icon = possibleIcon + ".svg"; + } } } return GetAssetPath(icon); @@ -62,5 +76,1304 @@ namespace FileTime.Avalonia.IconProviders { return new ImagePath(ImagePathType.Asset, "/Assets/material/" + iconName); } + + private static void InitMatches() + { + //Manually added + _iconsByExtension.Add("ts", "typescript"); + + //Generated + _iconsByExtension.Add("htm", "html"); + _iconsByExtension.Add("xhtml", "html"); + _iconsByExtension.Add("html_vm", "html"); + _iconsByExtension.Add("asp", "html"); + _iconsByExtension.Add("jade", "pug"); + _iconsByExtension.Add("pug", "pug"); + _iconsByExtension.Add("md", "markdown"); + _iconsByExtension.Add("markdown", "markdown"); + _iconsByExtension.Add("rst", "markdown"); + _iconsByExtension.Add("blink", "blink"); + _iconsByExtension.Add("css", "css"); + _iconsByExtension.Add("scss", "sass"); + _iconsByExtension.Add("sass", "sass"); + _iconsByExtension.Add("less", "less"); + _iconsByExtension.Add("json", "json"); + _iconsByExtension.Add("tsbuildinfo", "json"); + _iconsByExtension.Add("json5", "json"); + _iconsByExtension.Add("jsonl", "json"); + _iconsByExtension.Add("ndjson", "json"); + _iconsByExtension.Add("jinja", "jinja"); + _iconsByExtension.Add("jinja2", "jinja"); + _iconsByExtension.Add("j2", "jinja"); + _iconsByExtension.Add("jinja-html", "jinja"); + _iconsByExtension.Add("proto", "proto"); + _iconsByExtension.Add("sublime-project", "sublime"); + _iconsByExtension.Add("sublime-workspace", "sublime"); + _iconsByExtension.Add("tw", "twine"); + _iconsByExtension.Add("twee", "twine"); + _iconsByExtension.Add("yml", "yaml"); + _iconsByExtension.Add("yaml", "yaml"); + _iconsByExtension.Add("yml.dist", "yaml"); + _iconsByExtension.Add("yaml.dist", "yaml"); + _iconsByExtension.Add("YAML-tmLanguage", "yaml"); + _iconsByExtension.Add("xml", "xml"); + _iconsByExtension.Add("plist", "xml"); + _iconsByExtension.Add("xsd", "xml"); + _iconsByExtension.Add("dtd", "xml"); + _iconsByExtension.Add("xsl", "xml"); + _iconsByExtension.Add("xslt", "xml"); + _iconsByExtension.Add("resx", "xml"); + _iconsByExtension.Add("iml", "xml"); + _iconsByExtension.Add("xquery", "xml"); + _iconsByExtension.Add("tmLanguage", "xml"); + _iconsByExtension.Add("manifest", "xml"); + _iconsByExtension.Add("project", "xml"); + _iconsByExtension.Add("xml.dist", "xml"); + _iconsByExtension.Add("xml.dist.sample", "xml"); + _iconsByExtension.Add("dmn", "xml"); + _iconsByExtension.Add("png", "image"); + _iconsByExtension.Add("jpeg", "image"); + _iconsByExtension.Add("jpg", "image"); + _iconsByExtension.Add("gif", "image"); + _iconsByExtension.Add("ico", "image"); + _iconsByExtension.Add("tif", "image"); + _iconsByExtension.Add("tiff", "image"); + _iconsByExtension.Add("psd", "image"); + _iconsByExtension.Add("psb", "image"); + _iconsByExtension.Add("ami", "image"); + _iconsByExtension.Add("apx", "image"); + _iconsByExtension.Add("bmp", "image"); + _iconsByExtension.Add("bpg", "image"); + _iconsByExtension.Add("brk", "image"); + _iconsByExtension.Add("cur", "image"); + _iconsByExtension.Add("dds", "image"); + _iconsByExtension.Add("dng", "image"); + _iconsByExtension.Add("exr", "image"); + _iconsByExtension.Add("fpx", "image"); + _iconsByExtension.Add("gbr", "image"); + _iconsByExtension.Add("img", "image"); + _iconsByExtension.Add("jbig2", "image"); + _iconsByExtension.Add("jb2", "image"); + _iconsByExtension.Add("jng", "image"); + _iconsByExtension.Add("jxr", "image"); + _iconsByExtension.Add("pgf", "image"); + _iconsByExtension.Add("pic", "image"); + _iconsByExtension.Add("raw", "image"); + _iconsByExtension.Add("webp", "image"); + _iconsByExtension.Add("eps", "image"); + _iconsByExtension.Add("afphoto", "image"); + _iconsByExtension.Add("ase", "image"); + _iconsByExtension.Add("aseprite", "image"); + _iconsByExtension.Add("clip", "image"); + _iconsByExtension.Add("cpt", "image"); + _iconsByExtension.Add("heif", "image"); + _iconsByExtension.Add("heic", "image"); + _iconsByExtension.Add("kra", "image"); + _iconsByExtension.Add("mdp", "image"); + _iconsByExtension.Add("ora", "image"); + _iconsByExtension.Add("pdn", "image"); + _iconsByExtension.Add("reb", "image"); + _iconsByExtension.Add("sai", "image"); + _iconsByExtension.Add("tga", "image"); + _iconsByExtension.Add("xcf", "image"); + _iconsByExtension.Add("jfif", "image"); + _iconsByExtension.Add("ppm", "image"); + _iconsByExtension.Add("pbm", "image"); + _iconsByExtension.Add("pgm", "image"); + _iconsByExtension.Add("pnm", "image"); + _iconsByExtension.Add("esx", "javascript"); + _iconsByExtension.Add("mjs", "javascript"); + _iconsByExtension.Add("jsx", "react"); + _iconsByExtension.Add("tsx", "react_ts"); + _iconsByExtension.Add("ini", "settings"); + _iconsByExtension.Add("dlc", "settings"); + _iconsByExtension.Add("dll", "settings"); + _iconsByExtension.Add("config", "settings"); + _iconsByExtension.Add("conf", "settings"); + _iconsByExtension.Add("properties", "settings"); + _iconsByExtension.Add("prop", "settings"); + _iconsByExtension.Add("settings", "settings"); + _iconsByExtension.Add("option", "settings"); + _iconsByExtension.Add("props", "settings"); + _iconsByExtension.Add("toml", "settings"); + _iconsByExtension.Add("prefs", "settings"); + _iconsByExtension.Add("sln.dotsettings", "settings"); + _iconsByExtension.Add("sln.dotsettings.user", "settings"); + _iconsByExtension.Add("cfg", "settings"); + _iconsByExtension.Add("d.ts", "typescript-def"); + _iconsByExtension.Add("marko", "markojs"); + _iconsByExtension.Add("astro", "astro"); + _iconsByExtension.Add("pdf", "pdf"); + _iconsByExtension.Add("xlsx", "table"); + _iconsByExtension.Add("xls", "table"); + _iconsByExtension.Add("csv", "table"); + _iconsByExtension.Add("tsv", "table"); + _iconsByExtension.Add("vscodeignore", "vscode"); + _iconsByExtension.Add("vsixmanifest", "vscode"); + _iconsByExtension.Add("vsix", "vscode"); + _iconsByExtension.Add("code-workplace", "vscode"); + _iconsByExtension.Add("csproj", "visualstudio"); + _iconsByExtension.Add("ruleset", "visualstudio"); + _iconsByExtension.Add("sln", "visualstudio"); + _iconsByExtension.Add("suo", "visualstudio"); + _iconsByExtension.Add("vb", "visualstudio"); + _iconsByExtension.Add("vbs", "visualstudio"); + _iconsByExtension.Add("vcxitems", "visualstudio"); + _iconsByExtension.Add("vcxitems.filters", "visualstudio"); + _iconsByExtension.Add("vcxproj", "visualstudio"); + _iconsByExtension.Add("vcxproj.filters", "visualstudio"); + _iconsByExtension.Add("pdb", "database"); + _iconsByExtension.Add("sql", "database"); + _iconsByExtension.Add("pks", "database"); + _iconsByExtension.Add("pkb", "database"); + _iconsByExtension.Add("accdb", "database"); + _iconsByExtension.Add("mdb", "database"); + _iconsByExtension.Add("sqlite", "database"); + _iconsByExtension.Add("sqlite3", "database"); + _iconsByExtension.Add("pgsql", "database"); + _iconsByExtension.Add("postgres", "database"); + _iconsByExtension.Add("psql", "database"); + _iconsByExtension.Add("db", "database"); + _iconsByExtension.Add("db3", "database"); + _iconsByExtension.Add("kql", "kusto"); + _iconsByExtension.Add("cs", "csharp"); + _iconsByExtension.Add("csx", "csharp"); + _iconsByExtension.Add("qs", "qsharp"); + _iconsByExtension.Add("zip", "zip"); + _iconsByExtension.Add("tar", "zip"); + _iconsByExtension.Add("gz", "zip"); + _iconsByExtension.Add("xz", "zip"); + _iconsByExtension.Add("br", "zip"); + _iconsByExtension.Add("bzip2", "zip"); + _iconsByExtension.Add("gzip", "zip"); + _iconsByExtension.Add("brotli", "zip"); + _iconsByExtension.Add("7z", "zip"); + _iconsByExtension.Add("rar", "zip"); + _iconsByExtension.Add("tgz", "zip"); + _iconsByExtension.Add("vala", "vala"); + _iconsByExtension.Add("zig", "zig"); + _iconsByExtension.Add("exe", "exe"); + _iconsByExtension.Add("msi", "exe"); + _iconsByExtension.Add("dat", "hex"); + _iconsByExtension.Add("bin", "hex"); + _iconsByExtension.Add("hex", "hex"); + _iconsByExtension.Add("java", "java"); + _iconsByExtension.Add("jsp", "java"); + _iconsByExtension.Add("jar", "jar"); + _iconsByExtension.Add("class", "javaclass"); + _iconsByExtension.Add("c", "c"); + _iconsByExtension.Add("i", "c"); + _iconsByExtension.Add("mi", "c"); + _iconsByExtension.Add("h", "h"); + _iconsByExtension.Add("cc", "cpp"); + _iconsByExtension.Add("cpp", "cpp"); + _iconsByExtension.Add("cxx", "cpp"); + _iconsByExtension.Add("c++", "cpp"); + _iconsByExtension.Add("cp", "cpp"); + _iconsByExtension.Add("mm", "cpp"); + _iconsByExtension.Add("mii", "cpp"); + _iconsByExtension.Add("ii", "cpp"); + _iconsByExtension.Add("hh", "hpp"); + _iconsByExtension.Add("hpp", "hpp"); + _iconsByExtension.Add("hxx", "hpp"); + _iconsByExtension.Add("h++", "hpp"); + _iconsByExtension.Add("hp", "hpp"); + _iconsByExtension.Add("tcc", "hpp"); + _iconsByExtension.Add("inl", "hpp"); + _iconsByExtension.Add("go", "go"); + _iconsByExtension.Add("py", "python"); + _iconsByExtension.Add("pyc", "python-misc"); + _iconsByExtension.Add("whl", "python-misc"); + _iconsByExtension.Add("url", "url"); + _iconsByExtension.Add("sh", "console"); + _iconsByExtension.Add("ksh", "console"); + _iconsByExtension.Add("csh", "console"); + _iconsByExtension.Add("tcsh", "console"); + _iconsByExtension.Add("zsh", "console"); + _iconsByExtension.Add("bash", "console"); + _iconsByExtension.Add("bat", "console"); + _iconsByExtension.Add("cmd", "console"); + _iconsByExtension.Add("awk", "console"); + _iconsByExtension.Add("fish", "console"); + _iconsByExtension.Add("exp", "console"); + _iconsByExtension.Add("ps1", "powershell"); + _iconsByExtension.Add("psm1", "powershell"); + _iconsByExtension.Add("psd1", "powershell"); + _iconsByExtension.Add("ps1xml", "powershell"); + _iconsByExtension.Add("psc1", "powershell"); + _iconsByExtension.Add("pssc", "powershell"); + _iconsByExtension.Add("gradle", "gradle"); + _iconsByExtension.Add("doc", "word"); + _iconsByExtension.Add("docx", "word"); + _iconsByExtension.Add("rtf", "word"); + _iconsByExtension.Add("cer", "certificate"); + _iconsByExtension.Add("cert", "certificate"); + _iconsByExtension.Add("crt", "certificate"); + _iconsByExtension.Add("pub", "key"); + _iconsByExtension.Add("key", "key"); + _iconsByExtension.Add("pem", "key"); + _iconsByExtension.Add("asc", "key"); + _iconsByExtension.Add("gpg", "key"); + _iconsByExtension.Add("passwd", "key"); + _iconsByExtension.Add("woff", "font"); + _iconsByExtension.Add("woff2", "font"); + _iconsByExtension.Add("ttf", "font"); + _iconsByExtension.Add("eot", "font"); + _iconsByExtension.Add("suit", "font"); + _iconsByExtension.Add("otf", "font"); + _iconsByExtension.Add("bmap", "font"); + _iconsByExtension.Add("fnt", "font"); + _iconsByExtension.Add("odttf", "font"); + _iconsByExtension.Add("ttc", "font"); + _iconsByExtension.Add("font", "font"); + _iconsByExtension.Add("fonts", "font"); + _iconsByExtension.Add("sui", "font"); + _iconsByExtension.Add("ntf", "font"); + _iconsByExtension.Add("mrf", "font"); + _iconsByExtension.Add("lib", "lib"); + _iconsByExtension.Add("bib", "lib"); + _iconsByExtension.Add("rb", "ruby"); + _iconsByExtension.Add("erb", "ruby"); + _iconsByExtension.Add("fs", "fsharp"); + _iconsByExtension.Add("fsx", "fsharp"); + _iconsByExtension.Add("fsi", "fsharp"); + _iconsByExtension.Add("fsproj", "fsharp"); + _iconsByExtension.Add("swift", "swift"); + _iconsByExtension.Add("ino", "arduino"); + _iconsByExtension.Add("dockerignore", "docker"); + _iconsByExtension.Add("dockerfile", "docker"); + _iconsByExtension.Add("tex", "tex"); + _iconsByExtension.Add("sty", "tex"); + _iconsByExtension.Add("dtx", "tex"); + _iconsByExtension.Add("ltx", "tex"); + _iconsByExtension.Add("pptx", "powerpoint"); + _iconsByExtension.Add("ppt", "powerpoint"); + _iconsByExtension.Add("pptm", "powerpoint"); + _iconsByExtension.Add("potx", "powerpoint"); + _iconsByExtension.Add("potm", "powerpoint"); + _iconsByExtension.Add("ppsx", "powerpoint"); + _iconsByExtension.Add("ppsm", "powerpoint"); + _iconsByExtension.Add("pps", "powerpoint"); + _iconsByExtension.Add("ppam", "powerpoint"); + _iconsByExtension.Add("ppa", "powerpoint"); + _iconsByExtension.Add("webm", "video"); + _iconsByExtension.Add("mkv", "video"); + _iconsByExtension.Add("flv", "video"); + _iconsByExtension.Add("vob", "video"); + _iconsByExtension.Add("ogv", "video"); + _iconsByExtension.Add("ogg", "video"); + _iconsByExtension.Add("gifv", "video"); + _iconsByExtension.Add("avi", "video"); + _iconsByExtension.Add("mov", "video"); + _iconsByExtension.Add("qt", "video"); + _iconsByExtension.Add("wmv", "video"); + _iconsByExtension.Add("yuv", "video"); + _iconsByExtension.Add("rm", "video"); + _iconsByExtension.Add("rmvb", "video"); + _iconsByExtension.Add("mp4", "video"); + _iconsByExtension.Add("m4v", "video"); + _iconsByExtension.Add("mpg", "video"); + _iconsByExtension.Add("mp2", "video"); + _iconsByExtension.Add("mpeg", "video"); + _iconsByExtension.Add("mpe", "video"); + _iconsByExtension.Add("mpv", "video"); + _iconsByExtension.Add("m2v", "video"); + _iconsByExtension.Add("vdi", "virtual"); + _iconsByExtension.Add("vbox", "virtual"); + _iconsByExtension.Add("vbox-prev", "virtual"); + _iconsByExtension.Add("ics", "email"); + _iconsByExtension.Add("mp3", "audio"); + _iconsByExtension.Add("flac", "audio"); + _iconsByExtension.Add("m4a", "audio"); + _iconsByExtension.Add("wma", "audio"); + _iconsByExtension.Add("aiff", "audio"); + _iconsByExtension.Add("wav", "audio"); + _iconsByExtension.Add("coffee", "coffee"); + _iconsByExtension.Add("cson", "coffee"); + _iconsByExtension.Add("iced", "coffee"); + _iconsByExtension.Add("txt", "document"); + _iconsByExtension.Add("graphql", "graphql"); + _iconsByExtension.Add("gql", "graphql"); + _iconsByExtension.Add("rs", "rust"); + _iconsByExtension.Add("raml", "raml"); + _iconsByExtension.Add("xaml", "xaml"); + _iconsByExtension.Add("hs", "haskell"); + _iconsByExtension.Add("kt", "kotlin"); + _iconsByExtension.Add("kts", "kotlin"); + _iconsByExtension.Add("patch", "git"); + _iconsByExtension.Add("lua", "lua"); + _iconsByExtension.Add("clj", "clojure"); + _iconsByExtension.Add("cljs", "clojure"); + _iconsByExtension.Add("cljc", "clojure"); + _iconsByExtension.Add("groovy", "groovy"); + _iconsByExtension.Add("r", "r"); + _iconsByExtension.Add("rmd", "r"); + _iconsByExtension.Add("dart", "dart"); + _iconsByExtension.Add("as", "actionscript"); + _iconsByExtension.Add("mxml", "mxml"); + _iconsByExtension.Add("ahk", "autohotkey"); + _iconsByExtension.Add("swf", "flash"); + _iconsByExtension.Add("swc", "swc"); + _iconsByExtension.Add("cmake", "cmake"); + _iconsByExtension.Add("asm", "assembly"); + _iconsByExtension.Add("a51", "assembly"); + _iconsByExtension.Add("inc", "assembly"); + _iconsByExtension.Add("nasm", "assembly"); + _iconsByExtension.Add("s", "assembly"); + _iconsByExtension.Add("ms", "assembly"); + _iconsByExtension.Add("agc", "assembly"); + _iconsByExtension.Add("ags", "assembly"); + _iconsByExtension.Add("aea", "assembly"); + _iconsByExtension.Add("argus", "assembly"); + _iconsByExtension.Add("mitigus", "assembly"); + _iconsByExtension.Add("binsource", "assembly"); + _iconsByExtension.Add("vue", "vue"); + _iconsByExtension.Add("ml", "ocaml"); + _iconsByExtension.Add("mli", "ocaml"); + _iconsByExtension.Add("cmx", "ocaml"); + _iconsByExtension.Add("odin", "odin"); + _iconsByExtension.Add("js.map", "javascript-map"); + _iconsByExtension.Add("mjs.map", "javascript-map"); + _iconsByExtension.Add("cjs.map", "javascript-map"); + _iconsByExtension.Add("css.map", "css-map"); + _iconsByExtension.Add("lock", "lock"); + _iconsByExtension.Add("hbs", "handlebars"); + _iconsByExtension.Add("mustache", "handlebars"); + _iconsByExtension.Add("pm", "perl"); + _iconsByExtension.Add("raku", "perl"); + _iconsByExtension.Add("hx", "haxe"); + _iconsByExtension.Add("spec.ts", "test-ts"); + _iconsByExtension.Add("e2e-spec.ts", "test-ts"); + _iconsByExtension.Add("test.ts", "test-ts"); + _iconsByExtension.Add("ts.snap", "test-ts"); + _iconsByExtension.Add("spec.tsx", "test-jsx"); + _iconsByExtension.Add("test.tsx", "test-jsx"); + _iconsByExtension.Add("tsx.snap", "test-jsx"); + _iconsByExtension.Add("spec.jsx", "test-jsx"); + _iconsByExtension.Add("test.jsx", "test-jsx"); + _iconsByExtension.Add("jsx.snap", "test-jsx"); + _iconsByExtension.Add("spec.js", "test-js"); + _iconsByExtension.Add("spec.cjs", "test-js"); + _iconsByExtension.Add("spec.mjs", "test-js"); + _iconsByExtension.Add("e2e-spec.js", "test-js"); + _iconsByExtension.Add("e2e-spec.cjs", "test-js"); + _iconsByExtension.Add("e2e-spec.mjs", "test-js"); + _iconsByExtension.Add("test.js", "test-js"); + _iconsByExtension.Add("test.cjs", "test-js"); + _iconsByExtension.Add("test.mjs", "test-js"); + _iconsByExtension.Add("js.snap", "test-js"); + _iconsByExtension.Add("pp", "puppet"); + _iconsByExtension.Add("ex", "elixir"); + _iconsByExtension.Add("exs", "elixir"); + _iconsByExtension.Add("eex", "elixir"); + _iconsByExtension.Add("leex", "elixir"); + _iconsByExtension.Add("heex", "elixir"); + _iconsByExtension.Add("ls", "livescript"); + _iconsByExtension.Add("erl", "erlang"); + _iconsByExtension.Add("twig", "twig"); + _iconsByExtension.Add("jl", "julia"); + _iconsByExtension.Add("elm", "elm"); + _iconsByExtension.Add("pure", "purescript"); + _iconsByExtension.Add("purs", "purescript"); + _iconsByExtension.Add("tpl", "smarty"); + _iconsByExtension.Add("styl", "stylus"); + _iconsByExtension.Add("re", "reason"); + _iconsByExtension.Add("rei", "reason"); + _iconsByExtension.Add("cmj", "bucklescript"); + _iconsByExtension.Add("merlin", "merlin"); + _iconsByExtension.Add("vhd", "verilog"); + _iconsByExtension.Add("sv", "verilog"); + _iconsByExtension.Add("svh", "verilog"); + _iconsByExtension.Add("nb", "mathematica"); + _iconsByExtension.Add("wl", "wolframlanguage"); + _iconsByExtension.Add("wls", "wolframlanguage"); + _iconsByExtension.Add("njk", "nunjucks"); + _iconsByExtension.Add("nunjucks", "nunjucks"); + _iconsByExtension.Add("robot", "robot"); + _iconsByExtension.Add("sol", "solidity"); + _iconsByExtension.Add("au3", "autoit"); + _iconsByExtension.Add("haml", "haml"); + _iconsByExtension.Add("yang", "yang"); + _iconsByExtension.Add("mjml", "mjml"); + _iconsByExtension.Add("tf", "terraform"); + _iconsByExtension.Add("tf.json", "terraform"); + _iconsByExtension.Add("tfvars", "terraform"); + _iconsByExtension.Add("tfstate", "terraform"); + _iconsByExtension.Add("blade.php", "laravel"); + _iconsByExtension.Add("inky.php", "laravel"); + _iconsByExtension.Add("applescript", "applescript"); + _iconsByExtension.Add("ipa", "applescript"); + _iconsByExtension.Add("cake", "cake"); + _iconsByExtension.Add("feature", "cucumber"); + _iconsByExtension.Add("nim", "nim"); + _iconsByExtension.Add("nimble", "nim"); + _iconsByExtension.Add("apib", "apiblueprint"); + _iconsByExtension.Add("apiblueprint", "apiblueprint"); + _iconsByExtension.Add("riot", "riot"); + _iconsByExtension.Add("tag", "riot"); + _iconsByExtension.Add("vfl", "vfl"); + _iconsByExtension.Add("kl", "kl"); + _iconsByExtension.Add("pcss", "postcss"); + _iconsByExtension.Add("sss", "postcss"); + _iconsByExtension.Add("todo", "todo"); + _iconsByExtension.Add("cfml", "coldfusion"); + _iconsByExtension.Add("cfc", "coldfusion"); + _iconsByExtension.Add("lucee", "coldfusion"); + _iconsByExtension.Add("cfm", "coldfusion"); + _iconsByExtension.Add("cabal", "cabal"); + _iconsByExtension.Add("nix", "nix"); + _iconsByExtension.Add("slim", "slim"); + _iconsByExtension.Add("http", "http"); + _iconsByExtension.Add("rest", "http"); + _iconsByExtension.Add("rql", "restql"); + _iconsByExtension.Add("restql", "restql"); + _iconsByExtension.Add("kv", "kivy"); + _iconsByExtension.Add("graphcool", "graphcool"); + _iconsByExtension.Add("sbt", "sbt"); + _iconsByExtension.Add("apk", "android"); + _iconsByExtension.Add("smali", "android"); + _iconsByExtension.Add("dex", "android"); + _iconsByExtension.Add("env", "tune"); + _iconsByExtension.Add("gitlab-ci.yml", "gitlab"); + _iconsByExtension.Add("jenkinsfile", "jenkins"); + _iconsByExtension.Add("jenkins", "jenkins"); + _iconsByExtension.Add("cr", "crystal"); + _iconsByExtension.Add("ecr", "crystal"); + _iconsByExtension.Add("drone.yml", "drone"); + _iconsByExtension.Add("cu", "cuda"); + _iconsByExtension.Add("cuh", "cuda"); + _iconsByExtension.Add("log", "log"); + _iconsByExtension.Add("def", "dotjs"); + _iconsByExtension.Add("dot", "dotjs"); + _iconsByExtension.Add("jst", "dotjs"); + _iconsByExtension.Add("ejs", "ejs"); + _iconsByExtension.Add(".wakatime-project", "wakatime"); + _iconsByExtension.Add("pde", "processing"); + _iconsByExtension.Add("stories.js", "storybook"); + _iconsByExtension.Add("stories.jsx", "storybook"); + _iconsByExtension.Add("stories.mdx", "storybook"); + _iconsByExtension.Add("story.js", "storybook"); + _iconsByExtension.Add("story.jsx", "storybook"); + _iconsByExtension.Add("stories.ts", "storybook"); + _iconsByExtension.Add("stories.tsx", "storybook"); + _iconsByExtension.Add("story.ts", "storybook"); + _iconsByExtension.Add("story.tsx", "storybook"); + _iconsByExtension.Add("stories.svelte", "storybook"); + _iconsByExtension.Add("story.mdx", "storybook"); + _iconsByExtension.Add("wpy", "wepy"); + _iconsByExtension.Add("hcl", "hcl"); + _iconsByExtension.Add("san", "san"); + _iconsByExtension.Add("djt", "django"); + _iconsByExtension.Add("red", "red"); + _iconsByExtension.Add("fxp", "foxpro"); + _iconsByExtension.Add("prg", "foxpro"); + _iconsByExtension.Add("pot", "i18n"); + _iconsByExtension.Add("po", "i18n"); + _iconsByExtension.Add("mo", "i18n"); + _iconsByExtension.Add("wat", "webassembly"); + _iconsByExtension.Add("wasm", "webassembly"); + _iconsByExtension.Add("ipynb", "jupyter"); + _iconsByExtension.Add("d", "d"); + _iconsByExtension.Add("mdx", "mdx"); + _iconsByExtension.Add("bal", "ballerina"); + _iconsByExtension.Add("balx", "ballerina"); + _iconsByExtension.Add("rkt", "racket"); + _iconsByExtension.Add("bzl", "bazel"); + _iconsByExtension.Add("bazel", "bazel"); + _iconsByExtension.Add("mint", "mint"); + _iconsByExtension.Add("vm", "velocity"); + _iconsByExtension.Add("fhtml", "velocity"); + _iconsByExtension.Add("vtl", "velocity"); + _iconsByExtension.Add("gd", "godot"); + _iconsByExtension.Add("godot", "godot-assets"); + _iconsByExtension.Add("tres", "godot-assets"); + _iconsByExtension.Add("tscn", "godot-assets"); + _iconsByExtension.Add("azure-pipelines.yml", "azure-pipelines"); + _iconsByExtension.Add("azure-pipelines.yaml", "azure-pipelines"); + _iconsByExtension.Add("azcli", "azure"); + _iconsByExtension.Add("vagrantfile", "vagrant"); + _iconsByExtension.Add("prisma", "prisma"); + _iconsByExtension.Add("cshtml", "razor"); + _iconsByExtension.Add("vbhtml", "razor"); + _iconsByExtension.Add("abc", "abc"); + _iconsByExtension.Add("ad", "asciidoc"); + _iconsByExtension.Add("adoc", "asciidoc"); + _iconsByExtension.Add("asciidoc", "asciidoc"); + _iconsByExtension.Add("edge", "edge"); + _iconsByExtension.Add("ss", "scheme"); + _iconsByExtension.Add("scm", "scheme"); + _iconsByExtension.Add("lisp", "lisp"); + _iconsByExtension.Add("lsp", "lisp"); + _iconsByExtension.Add("cl", "lisp"); + _iconsByExtension.Add("fast", "lisp"); + _iconsByExtension.Add("stl", "3d"); + _iconsByExtension.Add("obj", "3d"); + _iconsByExtension.Add("ac", "3d"); + _iconsByExtension.Add("blend", "3d"); + _iconsByExtension.Add("mesh", "3d"); + _iconsByExtension.Add("mqo", "3d"); + _iconsByExtension.Add("pmd", "3d"); + _iconsByExtension.Add("pmx", "3d"); + _iconsByExtension.Add("skp", "3d"); + _iconsByExtension.Add("vac", "3d"); + _iconsByExtension.Add("vdp", "3d"); + _iconsByExtension.Add("vox", "3d"); + _iconsByExtension.Add("svg", "svg"); + _iconsByExtension.Add("svelte", "svelte"); + _iconsByExtension.Add("vimrc", "vim"); + _iconsByExtension.Add("gvimrc", "vim"); + _iconsByExtension.Add("exrc", "vim"); + _iconsByExtension.Add("vim", "vim"); + _iconsByExtension.Add("viminfo", "vim"); + _iconsByExtension.Add("moon", "moonscript"); + _iconsByExtension.Add("prw", "advpl_prw"); + _iconsByExtension.Add("prx", "advpl_prw"); + _iconsByExtension.Add("ptm", "advpl_ptm"); + _iconsByExtension.Add("tlpp", "advpl_tlpp"); + _iconsByExtension.Add("ch", "advpl_include"); + _iconsByExtension.Add("iso", "disc"); + _iconsByExtension.Add("f", "fortran"); + _iconsByExtension.Add("f77", "fortran"); + _iconsByExtension.Add("f90", "fortran"); + _iconsByExtension.Add("f95", "fortran"); + _iconsByExtension.Add("f03", "fortran"); + _iconsByExtension.Add("f08", "fortran"); + _iconsByExtension.Add("tcl", "tcl"); + _iconsByExtension.Add("liquid", "liquid"); + _iconsByExtension.Add("p", "prolog"); + _iconsByExtension.Add("pro", "prolog"); + _iconsByExtension.Add("pl", "prolog"); + _iconsByExtension.Add("coco", "coconut"); + _iconsByExtension.Add("sketch", "sketch"); + _iconsByExtension.Add("pwn", "pawn"); + _iconsByExtension.Add("amx", "pawn"); + _iconsByExtension.Add("4th", "forth"); + _iconsByExtension.Add("fth", "forth"); + _iconsByExtension.Add("frt", "forth"); + _iconsByExtension.Add("iuml", "uml"); + _iconsByExtension.Add("pu", "uml"); + _iconsByExtension.Add("puml", "uml"); + _iconsByExtension.Add("plantuml", "uml"); + _iconsByExtension.Add("wsd", "uml"); + _iconsByExtension.Add("wrap", "meson"); + _iconsByExtension.Add("dhall", "dhall"); + _iconsByExtension.Add("dhallb", "dhall"); + _iconsByExtension.Add("sml", "sml"); + _iconsByExtension.Add("mlton", "sml"); + _iconsByExtension.Add("mlb", "sml"); + _iconsByExtension.Add("sig", "sml"); + _iconsByExtension.Add("fun", "sml"); + _iconsByExtension.Add("cm", "sml"); + _iconsByExtension.Add("lex", "sml"); + _iconsByExtension.Add("use", "sml"); + _iconsByExtension.Add("grm", "sml"); + _iconsByExtension.Add("opam", "opam"); + _iconsByExtension.Add("imba", "imba"); + _iconsByExtension.Add("drawio", "drawio"); + _iconsByExtension.Add("dio", "drawio"); + _iconsByExtension.Add("pas", "pascal"); + _iconsByExtension.Add("unity", "shaderlab"); + _iconsByExtension.Add("sas", "sas"); + _iconsByExtension.Add("sas7bdat", "sas"); + _iconsByExtension.Add("sashdat", "sas"); + _iconsByExtension.Add("astore", "sas"); + _iconsByExtension.Add("ast", "sas"); + _iconsByExtension.Add("sast", "sas"); + _iconsByExtension.Add("nupkg", "nuget"); + _iconsByExtension.Add("command", "command"); + _iconsByExtension.Add("dsc", "denizenscript"); + _iconsByExtension.Add("code-search", "search"); + _iconsByExtension.Add("mcfunction", "minecraft"); + _iconsByExtension.Add("mcmeta", "minecraft"); + _iconsByExtension.Add("mcr", "minecraft"); + _iconsByExtension.Add("mca", "minecraft"); + _iconsByExtension.Add("mcgame", "minecraft"); + _iconsByExtension.Add("mclevel", "minecraft"); + _iconsByExtension.Add("mcworld", "minecraft"); + _iconsByExtension.Add("mine", "minecraft"); + _iconsByExtension.Add("mus", "minecraft"); + _iconsByExtension.Add("res", "rescript"); + _iconsByExtension.Add("resi", "rescript"); + _iconsByExtension.Add("b", "brainfuck"); + _iconsByExtension.Add("bf", "brainfuck"); + _iconsByExtension.Add("bicep", "bicep"); + _iconsByExtension.Add("cob", "cobol"); + _iconsByExtension.Add("cbl", "cobol"); + _iconsByExtension.Add("gr", "grain"); + _iconsByExtension.Add("lol", "lolcode"); + _iconsByExtension.Add("idr", "idris"); + _iconsByExtension.Add("ibc", "idris"); + _iconsByExtension.Add("pipeline", "pipeline"); + _iconsByExtension.Add("rego", "opa"); + _iconsByExtension.Add("windi", "windicss"); + _iconsByExtension.Add("scala", "scala"); + _iconsByExtension.Add("sc", "scala"); + _iconsByExtension.Add("ly", "lilypond"); + _iconsByExtension.Add("v", "vlang"); + _iconsByExtension.Add("pgn", "chess"); + _iconsByExtension.Add("fen", "chess"); + _iconsByExtension.Add("gmi", "gemini"); + _iconsByExtension.Add("gemini", "gemini"); + _iconsByExtension.Add("tsconfig.json", "tsconfig"); + _iconsByExtension.Add("tauri", "tauri"); + _iconsByExtension.Add("jsconfig.json", "jsconfig"); + _iconsByExtension.Add("ada", "ada"); + _iconsByExtension.Add("adb", "ada"); + _iconsByExtension.Add("ads", "ada"); + _iconsByExtension.Add("ali", "ada"); + _iconsByExtension.Add("horusec-config.json", "horusec"); + _iconsByExtension.Add("coarc", "coala"); + _iconsByExtension.Add("coafile", "coala"); + _iconsByExtension.Add("bubble", "dinophp"); + _iconsByExtension.Add("html.bubble", "dinophp"); + _iconsByExtension.Add("php.bubble", "dinophp"); + _iconsByExtension.Add("tl", "teal"); + _iconsByExtension.Add("template", "template"); + _iconsByExtension.Add("sy", "siyuan"); + _iconsByExtension.Add("ndst.yml", "ndst"); + _iconsByExtension.Add("ndst.yaml", "ndst"); + _iconsByExtension.Add("ndst.json", "ndst"); + _iconsByExtension.Add("tobi", "tobi"); + _iconsByFileName.Add(".pug-lintrc", "pug"); + _iconsByFileName.Add(".pug-lintrc.js", "pug"); + _iconsByFileName.Add(".pug-lintrc.json", "pug"); + _iconsByFileName.Add(".jscsrc", "json"); + _iconsByFileName.Add(".jshintrc", "json"); + _iconsByFileName.Add("composer.lock", "json"); + _iconsByFileName.Add(".jsbeautifyrc", "json"); + _iconsByFileName.Add(".esformatter", "json"); + _iconsByFileName.Add("cdp.pid", "json"); + _iconsByFileName.Add(".lintstagedrc", "json"); + _iconsByFileName.Add(".htaccess", "xml"); + _iconsByFileName.Add(".jshintignore", "settings"); + _iconsByFileName.Add(".buildignore", "settings"); + _iconsByFileName.Add(".mrconfig", "settings"); + _iconsByFileName.Add(".yardopts", "settings"); + _iconsByFileName.Add("manifest.mf", "settings"); + _iconsByFileName.Add(".clang-format", "settings"); + _iconsByFileName.Add(".clang-tidy", "settings"); + _iconsByFileName.Add("astro.config.js", "astro"); + _iconsByFileName.Add("astro.config.mjs", "astro"); + _iconsByFileName.Add("astro.config.cjs", "astro"); + _iconsByFileName.Add("go.mod", "go-mod"); + _iconsByFileName.Add("go.sum", "go-mod"); + _iconsByFileName.Add("requirements.txt", "python-misc"); + _iconsByFileName.Add("pipfile", "python-misc"); + _iconsByFileName.Add(".python-version", "python-misc"); + _iconsByFileName.Add("manifest.in", "python-misc"); + _iconsByFileName.Add("pylintrc", "python-misc"); + _iconsByFileName.Add(".pylintrc", "python-misc"); + _iconsByFileName.Add("pre-commit", "console"); + _iconsByFileName.Add("pre-push", "console"); + _iconsByFileName.Add("post-merge", "console"); + _iconsByFileName.Add("gradle.properties", "gradle"); + _iconsByFileName.Add("gradlew", "gradle"); + _iconsByFileName.Add("gradle-wrapper.properties", "gradle"); + _iconsByFileName.Add("copying", "certificate"); + _iconsByFileName.Add("copying.md", "certificate"); + _iconsByFileName.Add("copying.txt", "certificate"); + _iconsByFileName.Add("copyright", "certificate"); + _iconsByFileName.Add("copyright.txt", "certificate"); + _iconsByFileName.Add("copyright.md", "certificate"); + _iconsByFileName.Add("license", "certificate"); + _iconsByFileName.Add("license.md", "certificate"); + _iconsByFileName.Add("license.txt", "certificate"); + _iconsByFileName.Add("licence", "certificate"); + _iconsByFileName.Add("licence.md", "certificate"); + _iconsByFileName.Add("licence.txt", "certificate"); + _iconsByFileName.Add(".htpasswd", "key"); + _iconsByFileName.Add("gemfile", "gemfile"); + _iconsByFileName.Add(".rubocop.yml", "rubocop"); + _iconsByFileName.Add(".rubocop-todo.yml", "rubocop"); + _iconsByFileName.Add(".rubocop_todo.yml", "rubocop"); + _iconsByFileName.Add("dockerfile", "docker"); + _iconsByFileName.Add("dockerfile.prod", "docker"); + _iconsByFileName.Add("dockerfile.production", "docker"); + _iconsByFileName.Add("dockerfile.alpha", "docker"); + _iconsByFileName.Add("dockerfile.beta", "docker"); + _iconsByFileName.Add("dockerfile.stage", "docker"); + _iconsByFileName.Add("dockerfile.staging", "docker"); + _iconsByFileName.Add("dockerfile.dev", "docker"); + _iconsByFileName.Add("dockerfile.development", "docker"); + _iconsByFileName.Add("dockerfile.local", "docker"); + _iconsByFileName.Add("dockerfile.test", "docker"); + _iconsByFileName.Add("dockerfile.testing", "docker"); + _iconsByFileName.Add("dockerfile.ci", "docker"); + _iconsByFileName.Add("dockerfile.web", "docker"); + _iconsByFileName.Add("dockerfile.worker", "docker"); + _iconsByFileName.Add("docker-compose.yml", "docker"); + _iconsByFileName.Add("docker-compose.override.yml", "docker"); + _iconsByFileName.Add("docker-compose.prod.yml", "docker"); + _iconsByFileName.Add("docker-compose.production.yml", "docker"); + _iconsByFileName.Add("docker-compose.alpha.yml", "docker"); + _iconsByFileName.Add("docker-compose.beta.yml", "docker"); + _iconsByFileName.Add("docker-compose.stage.yml", "docker"); + _iconsByFileName.Add("docker-compose.staging.yml", "docker"); + _iconsByFileName.Add("docker-compose.dev.yml", "docker"); + _iconsByFileName.Add("docker-compose.development.yml", "docker"); + _iconsByFileName.Add("docker-compose.local.yml", "docker"); + _iconsByFileName.Add("docker-compose.test.yml", "docker"); + _iconsByFileName.Add("docker-compose.testing.yml", "docker"); + _iconsByFileName.Add("docker-compose.ci.yml", "docker"); + _iconsByFileName.Add("docker-compose.web.yml", "docker"); + _iconsByFileName.Add("docker-compose.worker.yml", "docker"); + _iconsByFileName.Add("docker-compose.yaml", "docker"); + _iconsByFileName.Add("docker-compose.override.yaml", "docker"); + _iconsByFileName.Add("docker-compose.prod.yaml", "docker"); + _iconsByFileName.Add("docker-compose.production.yaml", "docker"); + _iconsByFileName.Add("docker-compose.alpha.yaml", "docker"); + _iconsByFileName.Add("docker-compose.beta.yaml", "docker"); + _iconsByFileName.Add("docker-compose.stage.yaml", "docker"); + _iconsByFileName.Add("docker-compose.staging.yaml", "docker"); + _iconsByFileName.Add("docker-compose.dev.yaml", "docker"); + _iconsByFileName.Add("docker-compose.development.yaml", "docker"); + _iconsByFileName.Add("docker-compose.local.yaml", "docker"); + _iconsByFileName.Add("docker-compose.test.yaml", "docker"); + _iconsByFileName.Add("docker-compose.testing.yaml", "docker"); + _iconsByFileName.Add("docker-compose.ci.yaml", "docker"); + _iconsByFileName.Add("docker-compose.web.yaml", "docker"); + _iconsByFileName.Add("docker-compose.worker.yaml", "docker"); + _iconsByFileName.Add(".mailmap", "email"); + _iconsByFileName.Add(".graphqlconfig", "graphql"); + _iconsByFileName.Add(".graphqlrc", "graphql"); + _iconsByFileName.Add(".graphqlrc.json", "graphql"); + _iconsByFileName.Add(".graphqlrc.js", "graphql"); + _iconsByFileName.Add(".graphqlrc.ts", "graphql"); + _iconsByFileName.Add(".graphqlrc.toml", "graphql"); + _iconsByFileName.Add(".graphqlrc.yaml", "graphql"); + _iconsByFileName.Add(".graphqlrc.yml", "graphql"); + _iconsByFileName.Add("graphql.config.json", "graphql"); + _iconsByFileName.Add("graphql.config.js", "graphql"); + _iconsByFileName.Add("graphql.config.ts", "graphql"); + _iconsByFileName.Add("graphql.config.toml", "graphql"); + _iconsByFileName.Add("graphql.config.yaml", "graphql"); + _iconsByFileName.Add("graphql.config.yml", "graphql"); + _iconsByFileName.Add(".gitignore", "git"); + _iconsByFileName.Add(".gitignore_global", "git"); + _iconsByFileName.Add(".gitconfig", "git"); + _iconsByFileName.Add(".gitattributes", "git"); + _iconsByFileName.Add(".gitmodules", "git"); + _iconsByFileName.Add(".gitkeep", "git"); + _iconsByFileName.Add(".gitinclude", "git"); + _iconsByFileName.Add("git-history", "git"); + _iconsByFileName.Add(".luacheckrc", "lua"); + _iconsByFileName.Add(".Rhistory", "r"); + _iconsByFileName.Add(".pubignore", "dart"); + _iconsByFileName.Add("cmakelists.txt", "cmake"); + _iconsByFileName.Add("cmakecache.txt", "cmake"); + _iconsByFileName.Add("vue.config.js", "vue-config"); + _iconsByFileName.Add("vue.config.ts", "vue-config"); + _iconsByFileName.Add("vetur.config.js", "vue-config"); + _iconsByFileName.Add("vetur.config.ts", "vue-config"); + _iconsByFileName.Add("nuxt.config.js", "nuxt"); + _iconsByFileName.Add("nuxt.config.ts", "nuxt"); + _iconsByFileName.Add("security.md", "lock"); + _iconsByFileName.Add("security.txt", "lock"); + _iconsByFileName.Add("security", "lock"); + _iconsByFileName.Add(".mjmlconfig", "mjml"); + _iconsByFileName.Add("vercel.json", "vercel"); + _iconsByFileName.Add(".vercelignore", "vercel"); + _iconsByFileName.Add("now.json", "vercel"); + _iconsByFileName.Add(".nowignore", "vercel"); + _iconsByFileName.Add("next.config.js", "next"); + _iconsByFileName.Add("next.config.ts", "next"); + _iconsByFileName.Add("next.config.mjs", "next"); + _iconsByFileName.Add("artisan", "laravel"); + _iconsByFileName.Add(".vfl", "vfl"); + _iconsByFileName.Add(".kl", "kl"); + _iconsByFileName.Add("postcss.config.js", "postcss"); + _iconsByFileName.Add("postcss.config.cjs", "postcss"); + _iconsByFileName.Add(".postcssrc.js", "postcss"); + _iconsByFileName.Add(".postcssrc", "postcss"); + _iconsByFileName.Add(".postcssrc.json", "postcss"); + _iconsByFileName.Add(".postcssrc.yml", "postcss"); + _iconsByFileName.Add("posthtml.config.js", "posthtml"); + _iconsByFileName.Add(".posthtmlrc.js", "posthtml"); + _iconsByFileName.Add(".posthtmlrc", "posthtml"); + _iconsByFileName.Add(".posthtmlrc.json", "posthtml"); + _iconsByFileName.Add(".posthtmlrc.yml", "posthtml"); + _iconsByFileName.Add("cabal.project", "cabal"); + _iconsByFileName.Add("cabal.project.freeze", "cabal"); + _iconsByFileName.Add("cabal.project.local", "cabal"); + _iconsByFileName.Add("CNAME", "http"); + _iconsByFileName.Add("project.graphcool", "graphcool"); + _iconsByFileName.Add("webpack.js", "webpack"); + _iconsByFileName.Add("webpack.cjs", "webpack"); + _iconsByFileName.Add("webpack.ts", "webpack"); + _iconsByFileName.Add("webpack.base.js", "webpack"); + _iconsByFileName.Add("webpack.base.cjs", "webpack"); + _iconsByFileName.Add("webpack.base.ts", "webpack"); + _iconsByFileName.Add("webpack.config.js", "webpack"); + _iconsByFileName.Add("webpack.config.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.ts", "webpack"); + _iconsByFileName.Add("webpack.common.js", "webpack"); + _iconsByFileName.Add("webpack.common.cjs", "webpack"); + _iconsByFileName.Add("webpack.common.ts", "webpack"); + _iconsByFileName.Add("webpack.config.common.js", "webpack"); + _iconsByFileName.Add("webpack.config.common.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.common.ts", "webpack"); + _iconsByFileName.Add("webpack.config.common.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.common.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.dev.js", "webpack"); + _iconsByFileName.Add("webpack.dev.cjs", "webpack"); + _iconsByFileName.Add("webpack.dev.ts", "webpack"); + _iconsByFileName.Add("webpack.development.js", "webpack"); + _iconsByFileName.Add("webpack.development.cjs", "webpack"); + _iconsByFileName.Add("webpack.development.ts", "webpack"); + _iconsByFileName.Add("webpack.config.dev.js", "webpack"); + _iconsByFileName.Add("webpack.config.dev.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.dev.ts", "webpack"); + _iconsByFileName.Add("webpack.config.dev.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.dev.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.mix.js", "webpack"); + _iconsByFileName.Add("webpack.mix.cjs", "webpack"); + _iconsByFileName.Add("webpack.prod.js", "webpack"); + _iconsByFileName.Add("webpack.prod.cjs", "webpack"); + _iconsByFileName.Add("webpack.prod.config.js", "webpack"); + _iconsByFileName.Add("webpack.prod.config.cjs", "webpack"); + _iconsByFileName.Add("webpack.prod.ts", "webpack"); + _iconsByFileName.Add("webpack.production.js", "webpack"); + _iconsByFileName.Add("webpack.production.cjs", "webpack"); + _iconsByFileName.Add("webpack.production.ts", "webpack"); + _iconsByFileName.Add("webpack.server.js", "webpack"); + _iconsByFileName.Add("webpack.server.cjs", "webpack"); + _iconsByFileName.Add("webpack.server.ts", "webpack"); + _iconsByFileName.Add("webpack.client.js", "webpack"); + _iconsByFileName.Add("webpack.client.cjs", "webpack"); + _iconsByFileName.Add("webpack.client.ts", "webpack"); + _iconsByFileName.Add("webpack.config.server.js", "webpack"); + _iconsByFileName.Add("webpack.config.server.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.server.ts", "webpack"); + _iconsByFileName.Add("webpack.config.client.js", "webpack"); + _iconsByFileName.Add("webpack.config.client.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.client.ts", "webpack"); + _iconsByFileName.Add("webpack.config.production.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.production.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.config.prod.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.prod.babel.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.prod.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.config.prod.js", "webpack"); + _iconsByFileName.Add("webpack.config.prod.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.prod.ts", "webpack"); + _iconsByFileName.Add("webpack.config.production.js", "webpack"); + _iconsByFileName.Add("webpack.config.production.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.production.ts", "webpack"); + _iconsByFileName.Add("webpack.config.staging.js", "webpack"); + _iconsByFileName.Add("webpack.config.staging.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.staging.ts", "webpack"); + _iconsByFileName.Add("webpack.config.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.config.base.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.base.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.config.base.js", "webpack"); + _iconsByFileName.Add("webpack.config.base.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.base.ts", "webpack"); + _iconsByFileName.Add("webpack.config.staging.babel.js", "webpack"); + _iconsByFileName.Add("webpack.config.staging.babel.ts", "webpack"); + _iconsByFileName.Add("webpack.config.coffee", "webpack"); + _iconsByFileName.Add("webpack.config.test.js", "webpack"); + _iconsByFileName.Add("webpack.config.test.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.test.ts", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.js", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.ts", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.production.js", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.production.cjs", "webpack"); + _iconsByFileName.Add("webpack.config.vendor.production.ts", "webpack"); + _iconsByFileName.Add("webpack.test.js", "webpack"); + _iconsByFileName.Add("webpack.test.cjs", "webpack"); + _iconsByFileName.Add("webpack.test.ts", "webpack"); + _iconsByFileName.Add("webpack.dist.js", "webpack"); + _iconsByFileName.Add("webpack.dist.cjs", "webpack"); + _iconsByFileName.Add("webpack.dist.ts", "webpack"); + _iconsByFileName.Add("webpackfile.js", "webpack"); + _iconsByFileName.Add("webpackfile.cjs", "webpack"); + _iconsByFileName.Add("webpackfile.ts", "webpack"); + _iconsByFileName.Add("ionic.config.json", "ionic"); + _iconsByFileName.Add(".io-config.json", "ionic"); + _iconsByFileName.Add("gulpfile.js", "gulp"); + _iconsByFileName.Add("gulpfile.mjs", "gulp"); + _iconsByFileName.Add("gulpfile.ts", "gulp"); + _iconsByFileName.Add("gulpfile.babel.js", "gulp"); + _iconsByFileName.Add("package.json", "nodejs"); + _iconsByFileName.Add("package-lock.json", "nodejs"); + _iconsByFileName.Add(".nvmrc", "nodejs"); + _iconsByFileName.Add(".esmrc", "nodejs"); + _iconsByFileName.Add(".node-version", "nodejs"); + _iconsByFileName.Add(".npmignore", "npm"); + _iconsByFileName.Add(".npmrc", "npm"); + _iconsByFileName.Add(".yarnrc", "yarn"); + _iconsByFileName.Add("yarn.lock", "yarn"); + _iconsByFileName.Add(".yarnclean", "yarn"); + _iconsByFileName.Add(".yarn-integrity", "yarn"); + _iconsByFileName.Add("yarn-error.log", "yarn"); + _iconsByFileName.Add(".yarnrc.yml", "yarn"); + _iconsByFileName.Add(".yarnrc.yaml", "yarn"); + _iconsByFileName.Add("androidmanifest.xml", "android"); + _iconsByFileName.Add(".env.defaults", "tune"); + _iconsByFileName.Add(".env.example", "tune"); + _iconsByFileName.Add(".env.sample", "tune"); + _iconsByFileName.Add(".env.template", "tune"); + _iconsByFileName.Add(".env.schema", "tune"); + _iconsByFileName.Add(".env.local", "tune"); + _iconsByFileName.Add(".env.dev", "tune"); + _iconsByFileName.Add(".env.development", "tune"); + _iconsByFileName.Add(".env.qa", "tune"); + _iconsByFileName.Add(".env.dist", "tune"); + _iconsByFileName.Add(".env.prod", "tune"); + _iconsByFileName.Add(".env.production", "tune"); + _iconsByFileName.Add(".env.stage", "tune"); + _iconsByFileName.Add(".env.staging", "tune"); + _iconsByFileName.Add(".env.preview", "tune"); + _iconsByFileName.Add(".env.test", "tune"); + _iconsByFileName.Add(".env.testing", "tune"); + _iconsByFileName.Add(".env.development.local", "tune"); + _iconsByFileName.Add(".env.qa.local", "tune"); + _iconsByFileName.Add(".env.production.local", "tune"); + _iconsByFileName.Add(".env.staging.local", "tune"); + _iconsByFileName.Add(".env.test.local", "tune"); + _iconsByFileName.Add(".babelrc", "babel"); + _iconsByFileName.Add(".babelrc.cjs", "babel"); + _iconsByFileName.Add(".babelrc.js", "babel"); + _iconsByFileName.Add(".babelrc.mjs", "babel"); + _iconsByFileName.Add(".babelrc.json", "babel"); + _iconsByFileName.Add("babel.config.cjs", "babel"); + _iconsByFileName.Add("babel.config.js", "babel"); + _iconsByFileName.Add("babel.config.mjs", "babel"); + _iconsByFileName.Add("babel.config.json", "babel"); + _iconsByFileName.Add("babel-transform.js", "babel"); + _iconsByFileName.Add(".babel-plugin-macrosrc", "babel"); + _iconsByFileName.Add(".babel-plugin-macrosrc.json", "babel"); + _iconsByFileName.Add(".babel-plugin-macrosrc.yaml", "babel"); + _iconsByFileName.Add(".babel-plugin-macrosrc.yml", "babel"); + _iconsByFileName.Add(".babel-plugin-macrosrc.js", "babel"); + _iconsByFileName.Add("babel-plugin-macros.config.js", "babel"); + _iconsByFileName.Add("contributing.md", "contributing"); + _iconsByFileName.Add("readme.md", "readme"); + _iconsByFileName.Add("readme.txt", "readme"); + _iconsByFileName.Add("readme", "readme"); + _iconsByFileName.Add("changelog", "changelog"); + _iconsByFileName.Add("changelog.md", "changelog"); + _iconsByFileName.Add("changelog.txt", "changelog"); + _iconsByFileName.Add("changes", "changelog"); + _iconsByFileName.Add("changes.md", "changelog"); + _iconsByFileName.Add("changes.txt", "changelog"); + _iconsByFileName.Add("credits", "credits"); + _iconsByFileName.Add("credits.txt", "credits"); + _iconsByFileName.Add("credits.md", "credits"); + _iconsByFileName.Add("authors", "authors"); + _iconsByFileName.Add("authors.md", "authors"); + _iconsByFileName.Add("authors.txt", "authors"); + _iconsByFileName.Add(".flowconfig", "flow"); + _iconsByFileName.Add("favicon.ico", "favicon"); + _iconsByFileName.Add("karma.conf.js", "karma"); + _iconsByFileName.Add("karma.conf.ts", "karma"); + _iconsByFileName.Add("karma.conf.coffee", "karma"); + _iconsByFileName.Add("karma.config.js", "karma"); + _iconsByFileName.Add("karma.config.ts", "karma"); + _iconsByFileName.Add("karma-main.js", "karma"); + _iconsByFileName.Add("karma-main.ts", "karma"); + _iconsByFileName.Add(".bithoundrc", "bithound"); + _iconsByFileName.Add("svgo.config.js", "svgo"); + _iconsByFileName.Add(".appveyor.yml", "appveyor"); + _iconsByFileName.Add("appveyor.yml", "appveyor"); + _iconsByFileName.Add(".travis.yml", "travis"); + _iconsByFileName.Add(".codecov.yml", "codecov"); + _iconsByFileName.Add("codecov.yml", "codecov"); + _iconsByFileName.Add("protractor.conf.js", "protractor"); + _iconsByFileName.Add("protractor.conf.ts", "protractor"); + _iconsByFileName.Add("protractor.conf.coffee", "protractor"); + _iconsByFileName.Add("protractor.config.js", "protractor"); + _iconsByFileName.Add("protractor.config.ts", "protractor"); + _iconsByFileName.Add("fuse.js", "fusebox"); + _iconsByFileName.Add("procfile", "heroku"); + _iconsByFileName.Add("procfile.windows", "heroku"); + _iconsByFileName.Add(".editorconfig", "editorconfig"); + _iconsByFileName.Add(".bowerrc", "bower"); + _iconsByFileName.Add("bower.json", "bower"); + _iconsByFileName.Add(".eslintrc.js", "eslint"); + _iconsByFileName.Add(".eslintrc.cjs", "eslint"); + _iconsByFileName.Add(".eslintrc.yaml", "eslint"); + _iconsByFileName.Add(".eslintrc.yml", "eslint"); + _iconsByFileName.Add(".eslintrc.json", "eslint"); + _iconsByFileName.Add(".eslintrc-md.js", "eslint"); + _iconsByFileName.Add(".eslintrc-jsdoc.js", "eslint"); + _iconsByFileName.Add(".eslintrc", "eslint"); + _iconsByFileName.Add(".eslintignore", "eslint"); + _iconsByFileName.Add(".eslintcache", "eslint"); + _iconsByFileName.Add("code_of_conduct.md", "conduct"); + _iconsByFileName.Add("code_of_conduct.txt", "conduct"); + _iconsByFileName.Add(".watchmanconfig", "watchman"); + _iconsByFileName.Add("aurelia.json", "aurelia"); + _iconsByFileName.Add("mocha.opts", "mocha"); + _iconsByFileName.Add(".mocharc.yml", "mocha"); + _iconsByFileName.Add(".mocharc.yaml", "mocha"); + _iconsByFileName.Add(".mocharc.js", "mocha"); + _iconsByFileName.Add(".mocharc.json", "mocha"); + _iconsByFileName.Add(".mocharc.jsonc", "mocha"); + _iconsByFileName.Add("jenkinsfile", "jenkins"); + _iconsByFileName.Add("firebase.json", "firebase"); + _iconsByFileName.Add(".firebaserc", "firebase"); + _iconsByFileName.Add("firestore.rules", "firebase"); + _iconsByFileName.Add("firestore.indexes.json", "firebase"); + _iconsByFileName.Add("rollup.config.js", "rollup"); + _iconsByFileName.Add("rollup.config.ts", "rollup"); + _iconsByFileName.Add("rollup-config.js", "rollup"); + _iconsByFileName.Add("rollup-config.ts", "rollup"); + _iconsByFileName.Add("rollup.config.common.js", "rollup"); + _iconsByFileName.Add("rollup.config.common.ts", "rollup"); + _iconsByFileName.Add("rollup.config.base.js", "rollup"); + _iconsByFileName.Add("rollup.config.base.ts", "rollup"); + _iconsByFileName.Add("rollup.config.prod.js", "rollup"); + _iconsByFileName.Add("rollup.config.prod.ts", "rollup"); + _iconsByFileName.Add("rollup.config.dev.js", "rollup"); + _iconsByFileName.Add("rollup.config.dev.ts", "rollup"); + _iconsByFileName.Add("rollup.config.prod.vendor.js", "rollup"); + _iconsByFileName.Add("rollup.config.prod.vendor.ts", "rollup"); + _iconsByFileName.Add(".hhconfig", "hack"); + _iconsByFileName.Add(".stylelintrc", "stylelint"); + _iconsByFileName.Add("stylelint.config.js", "stylelint"); + _iconsByFileName.Add("stylelint.config.cjs", "stylelint"); + _iconsByFileName.Add(".stylelintrc.json", "stylelint"); + _iconsByFileName.Add(".stylelintrc.yaml", "stylelint"); + _iconsByFileName.Add(".stylelintrc.yml", "stylelint"); + _iconsByFileName.Add(".stylelintrc.js", "stylelint"); + _iconsByFileName.Add(".stylelintrc.cjs", "stylelint"); + _iconsByFileName.Add(".stylelintignore", "stylelint"); + _iconsByFileName.Add(".codeclimate.yml", "code-climate"); + _iconsByFileName.Add(".prettierrc", "prettier"); + _iconsByFileName.Add("prettier.config.js", "prettier"); + _iconsByFileName.Add("prettier.config.cjs", "prettier"); + _iconsByFileName.Add(".prettierrc.js", "prettier"); + _iconsByFileName.Add(".prettierrc.cjs", "prettier"); + _iconsByFileName.Add(".prettierrc.json", "prettier"); + _iconsByFileName.Add(".prettierrc.json5", "prettier"); + _iconsByFileName.Add(".prettierrc.yaml", "prettier"); + _iconsByFileName.Add(".prettierrc.yml", "prettier"); + _iconsByFileName.Add(".prettierignore", "prettier"); + _iconsByFileName.Add(".prettierrc.toml", "prettier"); + _iconsByFileName.Add(".renovaterc", "renovate"); + _iconsByFileName.Add(".renovaterc.json", "renovate"); + _iconsByFileName.Add("renovate-config.json", "renovate"); + _iconsByFileName.Add("renovate.json", "renovate"); + _iconsByFileName.Add("renovate.json5", "renovate"); + _iconsByFileName.Add("apollo.config.js", "apollo"); + _iconsByFileName.Add("nodemon.json", "nodemon"); + _iconsByFileName.Add("nodemon-debug.json", "nodemon"); + _iconsByFileName.Add(".hintrc", "webhint"); + _iconsByFileName.Add("browserslist", "browserlist"); + _iconsByFileName.Add(".browserslistrc", "browserlist"); + _iconsByFileName.Add(".snyk", "snyk"); + _iconsByFileName.Add(".drone.yml", "drone"); + _iconsByFileName.Add(".sequelizerc", "sequelize"); + _iconsByFileName.Add("gatsby.config.js", "gatsby"); + _iconsByFileName.Add("gatsby-config.js", "gatsby"); + _iconsByFileName.Add("gatsby-node.js", "gatsby"); + _iconsByFileName.Add("gatsby-browser.js", "gatsby"); + _iconsByFileName.Add("gatsby-ssr.js", "gatsby"); + _iconsByFileName.Add(".wakatime-project", "wakatime"); + _iconsByFileName.Add("circle.yml", "circleci"); + _iconsByFileName.Add(".cfignore", "cloudfoundry"); + _iconsByFileName.Add("gruntfile.js", "grunt"); + _iconsByFileName.Add("gruntfile.ts", "grunt"); + _iconsByFileName.Add("gruntfile.coffee", "grunt"); + _iconsByFileName.Add("gruntfile.babel.js", "grunt"); + _iconsByFileName.Add("gruntfile.babel.ts", "grunt"); + _iconsByFileName.Add("gruntfile.babel.coffee", "grunt"); + _iconsByFileName.Add("jest.config.js", "jest"); + _iconsByFileName.Add("jest.config.ts", "jest"); + _iconsByFileName.Add("jest.config.cjs", "jest"); + _iconsByFileName.Add("jest.config.mjs", "jest"); + _iconsByFileName.Add("jest.config.json", "jest"); + _iconsByFileName.Add("jest.e2e.config.js", "jest"); + _iconsByFileName.Add("jest.e2e.config.ts", "jest"); + _iconsByFileName.Add("jest.e2e.config.cjs", "jest"); + _iconsByFileName.Add("jest.e2e.config.mjs", "jest"); + _iconsByFileName.Add("jest.e2e.config.json", "jest"); + _iconsByFileName.Add("jest.e2e.json", "jest"); + _iconsByFileName.Add("jest-unit.config.js", "jest"); + _iconsByFileName.Add("jest-e2e.config.js", "jest"); + _iconsByFileName.Add("jest-e2e.config.ts", "jest"); + _iconsByFileName.Add("jest-e2e.config.cjs", "jest"); + _iconsByFileName.Add("jest-e2e.config.mjs", "jest"); + _iconsByFileName.Add("jest-e2e.config.json", "jest"); + _iconsByFileName.Add("jest-e2e.json", "jest"); + _iconsByFileName.Add("jest-github-actions-reporter.js", "jest"); + _iconsByFileName.Add("jest.setup.js", "jest"); + _iconsByFileName.Add("jest.setup.ts", "jest"); + _iconsByFileName.Add("jest.json", "jest"); + _iconsByFileName.Add(".jestrc", "jest"); + _iconsByFileName.Add(".jestrc.js", "jest"); + _iconsByFileName.Add(".jestrc.json", "jest"); + _iconsByFileName.Add("jest.teardown.js", "jest"); + _iconsByFileName.Add("fastfile", "fastlane"); + _iconsByFileName.Add("appfile", "fastlane"); + _iconsByFileName.Add(".helmignore", "helm"); + _iconsByFileName.Add("wallaby.js", "wallaby"); + _iconsByFileName.Add("wallaby.conf.js", "wallaby"); + _iconsByFileName.Add("stencil.config.js", "stencil"); + _iconsByFileName.Add("stencil.config.ts", "stencil"); + _iconsByFileName.Add("makefile", "makefile"); + _iconsByFileName.Add(".releaserc", "semantic-release"); + _iconsByFileName.Add(".releaserc.yaml", "semantic-release"); + _iconsByFileName.Add(".releaserc.yml", "semantic-release"); + _iconsByFileName.Add(".releaserc.json", "semantic-release"); + _iconsByFileName.Add(".releaserc.js", "semantic-release"); + _iconsByFileName.Add("release.config.js", "semantic-release"); + _iconsByFileName.Add("bitbucket-pipelines.yaml", "bitbucket"); + _iconsByFileName.Add("bitbucket-pipelines.yml", "bitbucket"); + _iconsByFileName.Add(".bazelignore", "bazel"); + _iconsByFileName.Add(".bazelrc", "bazel"); + _iconsByFileName.Add(".bazelversion", "bazel"); + _iconsByFileName.Add("azure-pipelines.yml", "azure-pipelines"); + _iconsByFileName.Add("azure-pipelines.yaml", "azure-pipelines"); + _iconsByFileName.Add("vagrantfile", "vagrant"); + _iconsByFileName.Add("prisma.yml", "prisma"); + _iconsByFileName.Add(".nycrc", "istanbul"); + _iconsByFileName.Add(".nycrc.json", "istanbul"); + _iconsByFileName.Add("tailwind.js", "tailwindcss"); + _iconsByFileName.Add("tailwind.ts", "tailwindcss"); + _iconsByFileName.Add("tailwind.config.js", "tailwindcss"); + _iconsByFileName.Add("tailwind.config.ts", "tailwindcss"); + _iconsByFileName.Add("tailwind.config.cjs", "tailwindcss"); + _iconsByFileName.Add("buildkite.yml", "buildkite"); + _iconsByFileName.Add("buildkite.yaml", "buildkite"); + _iconsByFileName.Add("netlify.json", "netlify"); + _iconsByFileName.Add("netlify.yml", "netlify"); + _iconsByFileName.Add("netlify.yaml", "netlify"); + _iconsByFileName.Add("netlify.toml", "netlify"); + _iconsByFileName.Add("svelte.config.js", "svelte"); + _iconsByFileName.Add("svelte.config.cjs", "svelte"); + _iconsByFileName.Add("nest-cli.json", "nest"); + _iconsByFileName.Add(".nest-cli.json", "nest"); + _iconsByFileName.Add("nestconfig.json", "nest"); + _iconsByFileName.Add(".nestconfig.json", "nest"); + _iconsByFileName.Add(".percy.yml", "percy"); + _iconsByFileName.Add(".gitpod.yml", "gitpod"); + _iconsByFileName.Add("codeowners", "codeowners"); + _iconsByFileName.Add(".gcloudignore", "gcp"); + _iconsByFileName.Add(".huskyrc", "husky"); + _iconsByFileName.Add("husky.config.js", "husky"); + _iconsByFileName.Add(".huskyrc.json", "husky"); + _iconsByFileName.Add(".huskyrc.js", "husky"); + _iconsByFileName.Add(".huskyrc.yaml", "husky"); + _iconsByFileName.Add(".huskyrc.yml", "husky"); + _iconsByFileName.Add("tiltfile", "tilt"); + _iconsByFileName.Add("capacitor.config.json", "capacitor"); + _iconsByFileName.Add(".adonisrc.json", "adonis"); + _iconsByFileName.Add("ace", "adonis"); + _iconsByFileName.Add("meson.build", "meson"); + _iconsByFileName.Add("meson_options.txt", "meson"); + _iconsByFileName.Add(".commitlintrc", "commitlint"); + _iconsByFileName.Add(".commitlintrc.js", "commitlint"); + _iconsByFileName.Add("commitlint.config.js", "commitlint"); + _iconsByFileName.Add(".commitlintrc.json", "commitlint"); + _iconsByFileName.Add(".commitlint.yaml", "commitlint"); + _iconsByFileName.Add(".commitlint.yml", "commitlint"); + _iconsByFileName.Add(".commitlintrc.yaml", "commitlint"); + _iconsByFileName.Add(".commitlintrc.yml", "commitlint"); + _iconsByFileName.Add("commitlint.config.cjs", "commitlint"); + _iconsByFileName.Add("commitlint.config.ts", "commitlint"); + _iconsByFileName.Add(".commitlintrc.ts", "commitlint"); + _iconsByFileName.Add(".commitlintrc.cjs", "commitlint"); + _iconsByFileName.Add(".buckconfig", "buck"); + _iconsByFileName.Add("nx.json", "nrwl"); + _iconsByFileName.Add(".nxignore", "nrwl"); + _iconsByFileName.Add("dune", "dune"); + _iconsByFileName.Add("dune-project", "dune"); + _iconsByFileName.Add("dune-workspace", "dune"); + _iconsByFileName.Add("dune-workspace.dev", "dune"); + _iconsByFileName.Add("roadmap.md", "roadmap"); + _iconsByFileName.Add("roadmap.txt", "roadmap"); + _iconsByFileName.Add("timeline.md", "roadmap"); + _iconsByFileName.Add("timeline.txt", "roadmap"); + _iconsByFileName.Add("milestones.md", "roadmap"); + _iconsByFileName.Add("milestones.txt", "roadmap"); + _iconsByFileName.Add("nuget.config", "nuget"); + _iconsByFileName.Add(".nuspec", "nuget"); + _iconsByFileName.Add("nuget.exe", "nuget"); + _iconsByFileName.Add("stryker.conf.js", "stryker"); + _iconsByFileName.Add("stryker.conf.json", "stryker"); + _iconsByFileName.Add(".modernizrrc", "modernizr"); + _iconsByFileName.Add(".modernizrrc.js", "modernizr"); + _iconsByFileName.Add(".modernizrrc.json", "modernizr"); + _iconsByFileName.Add(".slugignore", "slug"); + _iconsByFileName.Add("stitches.config.js", "stitches"); + _iconsByFileName.Add("stitches.config.ts", "stitches"); + _iconsByFileName.Add("nginx.conf", "nginx"); + _iconsByFileName.Add(".replit", "replit"); + _iconsByFileName.Add("snowpack.config.cjs", "snowpack"); + _iconsByFileName.Add("snowpack.config.js", "snowpack"); + _iconsByFileName.Add("snowpack.config.mjs", "snowpack"); + _iconsByFileName.Add("snowpack.deps.json", "snowpack"); + _iconsByFileName.Add("snowpack.config.ts", "snowpack"); + _iconsByFileName.Add("snowpack.config.json", "snowpack"); + _iconsByFileName.Add("quasar.conf.js", "quasar"); + _iconsByFileName.Add("dependabot.yml", "dependabot"); + _iconsByFileName.Add("vite.config.js", "vite"); + _iconsByFileName.Add("vite.config.mjs", "vite"); + _iconsByFileName.Add("vite.config.cjs", "vite"); + _iconsByFileName.Add("vite.config.ts", "vite"); + _iconsByFileName.Add("lerna.json", "lerna"); + _iconsByFileName.Add("windi.config.js", "windicss"); + _iconsByFileName.Add("windi.config.ts", "windicss"); + _iconsByFileName.Add("windi.config.cjs", "windicss"); + _iconsByFileName.Add("windi.config.json", "windicss"); + _iconsByFileName.Add(".textlintrc", "textlint"); + _iconsByFileName.Add("vpkg.json", "vlang"); + _iconsByFileName.Add("v.mod", "vlang"); + _iconsByFileName.Add(".sentryclirc", "sentry"); + _iconsByFileName.Add(".phpunit.result.cache", "phpunit"); + _iconsByFileName.Add(".phpunit-watcher.yml", "phpunit"); + _iconsByFileName.Add("phpunit.xml", "phpunit"); + _iconsByFileName.Add("phpunit.xml.dist", "phpunit"); + _iconsByFileName.Add("phpunit-watcher.yml", "phpunit"); + _iconsByFileName.Add("phpunit-watcher.yml.dist", "phpunit"); + _iconsByFileName.Add(".php_cs", "php-cs-fixer"); + _iconsByFileName.Add(".php_cs.dist", "php-cs-fixer"); + _iconsByFileName.Add(".php_cs.php", "php-cs-fixer"); + _iconsByFileName.Add(".php_cs.dist.php", "php-cs-fixer"); + _iconsByFileName.Add(".php-cs-fixer.php", "php-cs-fixer"); + _iconsByFileName.Add(".php-cs-fixer.dist.php", "php-cs-fixer"); + _iconsByFileName.Add("robots.txt", "robots"); + _iconsByFileName.Add("tsconfig.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.app.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.editor.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.spec.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.base.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.build.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.eslint.json", "tsconfig"); + _iconsByFileName.Add("tsconfig.lib.json", "tsconfig"); + _iconsByFileName.Add("tauri.config.json", "tauri"); + _iconsByFileName.Add("tauri.linux.conf.json", "tauri"); + _iconsByFileName.Add("tauri.windows.conf.json", "tauri"); + _iconsByFileName.Add("tauri.macos.conf.json", "tauri"); + _iconsByFileName.Add("jsconfig.json", "jsconfig"); + _iconsByFileName.Add("maven.config", "maven"); + _iconsByFileName.Add("jvm.config", "maven"); + _iconsByFileName.Add(".ember-cli", "ember"); + _iconsByFileName.Add(".ember-cli.js", "ember"); + _iconsByFileName.Add("ember-cli-builds.js", "ember"); + _iconsByFileName.Add("horusec-config.json", "horusec"); + _iconsByFileName.Add(".astylerc", "astyle"); + _iconsByFileName.Add(".lighthouserc.js", "lighthouse"); + _iconsByFileName.Add("lighthouserc.js", "lighthouse"); + _iconsByFileName.Add(".lighthouserc.json", "lighthouse"); + _iconsByFileName.Add("lighthouserc.json", "lighthouse"); + _iconsByFileName.Add(".lighthouserc.yml", "lighthouse"); + _iconsByFileName.Add("lighthouserc.yml", "lighthouse"); + _iconsByFileName.Add(".lighthouserc.yaml", "lighthouse"); + _iconsByFileName.Add("lighthouserc.yaml", "lighthouse"); + _iconsByFileName.Add(".svgrrc", "svgr"); + _iconsByFileName.Add("svgr.config.js", "svgr"); + _iconsByFileName.Add(".svgrrc.js", "svgr"); + _iconsByFileName.Add(".svgrrc.yaml", "svgr"); + _iconsByFileName.Add(".svgrrc.yml", "svgr"); + _iconsByFileName.Add(".svgrrc.json", "svgr"); + _iconsByFileName.Add("rome.json", "rome"); + _iconsByFileName.Add("cypress.json", "cypress"); + _iconsByFileName.Add("cypress.env.json", "cypress"); + _iconsByFileName.Add(".tobimake", "tobimake"); + } } } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs index 4db83ce..ce05175 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using FileTime.Avalonia.Application; +using System.Threading; namespace FileTime.Avalonia.ViewModels { @@ -130,21 +131,22 @@ namespace FileTime.Avalonia.ViewModels public void InvalidateDisplayName() => OnPropertyChanged(nameof(DisplayName)); - public async Task Init(bool initializeChildren = true) + public async Task Init(bool initializeChildren = true, CancellationToken token = default) { - await Refresh(initializeChildren); + await Refresh(initializeChildren, token); } - private async Task Container_Refreshed(object? sender, AsyncEventArgs e) + private async Task Container_Refreshed(object? sender, AsyncEventArgs e, CancellationToken token = default) { - await Refresh(false); + await Refresh(false, token); } + [Obsolete($"Use the parametrizable version of {nameof(Refresh)}.")] private async Task Refresh() { await Refresh(true); } - private async Task Refresh(bool initializeChildren) + private async Task Refresh(bool initializeChildren, CancellationToken token = default) { if (_isRefreshing) return; @@ -157,6 +159,9 @@ namespace FileTime.Avalonia.ViewModels var containers = (await _container.GetContainers())!.Select(c => AdoptOrReuseOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList(); var elements = (await _container.GetElements())!.Select(e => AdoptOrReuseOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList(); + + if (token.IsCancellationRequested) return; + Exceptions = new List(_container.Exceptions); foreach (var containerToRemove in _containers.Except(containers)) @@ -168,7 +173,8 @@ namespace FileTime.Avalonia.ViewModels { foreach (var container in containers) { - await container.Init(false); + if (token.IsCancellationRequested) return; + await container.Init(false, token); } } @@ -220,21 +226,21 @@ namespace FileTime.Avalonia.ViewModels _items = new ObservableCollection(); } - public async Task> GetContainers() + public async Task> GetContainers(CancellationToken token = default) { - if (!_isInitialized) await Task.Run(Refresh); + if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token); return _containers; } - public async Task> GetElements() + public async Task> GetElements(CancellationToken token = default) { - if (!_isInitialized) await Task.Run(Refresh); + if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token); return _elements; } - public async Task> GetItems() + public async Task> GetItems(CancellationToken token = default) { - if (!_isInitialized) await Task.Run(Refresh); + if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token); return _items; } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs index b5925ac..2e9b1b8 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs @@ -605,7 +605,7 @@ namespace FileTime.Avalonia.ViewModels private async Task RefreshCurrentLocation() { - await AppState.SelectedTab.CurrentLocation.Container.Refresh(); + await AppState.SelectedTab.CurrentLocation.Container.RefreshAsync(); await AppState.SelectedTab.UpdateCurrentSelectedItem(); } @@ -640,7 +640,7 @@ namespace FileTime.Avalonia.ViewModels var possibleContainer = await contentProvider.GetByPath(path); if (possibleContainer is IContainer container) { - AppState.SelectedTab.OpenContainer(container).Wait(); + await AppState.SelectedTab.OpenContainer(container); } //TODO: multiple possible content provider handler return; @@ -873,7 +873,7 @@ namespace FileTime.Avalonia.ViewModels var selectedItemName = AppState.SelectedTab.SelectedItem?.Item.Name; var currentLocationItems = await AppState.SelectedTab.CurrentLocation.GetItems(); - if (currentLocationItems.FirstOrDefault(i => i.Item.Name.ToLower() == AppState.RapidTravelText.ToLower()) is IItemViewModel matchItem) + if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, AppState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem) { await AppState.SelectedTab.SetCurrentSelectedItem(matchItem.Item); } @@ -882,7 +882,6 @@ namespace FileTime.Avalonia.ViewModels await AppState.SelectedTab.MoveCursorToFirst(); } } - } return true; @@ -899,7 +898,7 @@ namespace FileTime.Avalonia.ViewModels } private void ReadInputs(List inputs, Func inputHandler) { - Inputs = inputs.Select(i => new InputElementWrapper(i, i.DefaultValue)).ToList(); + Inputs = inputs.ConvertAll(i => new InputElementWrapper(i, i.DefaultValue)); _inputHandler = inputHandler; } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ParallelCommandViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ParallelCommandViewModel.cs index 41abb03..6248434 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ParallelCommandViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ParallelCommandViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AsyncEvent; using FileTime.Core.Command; @@ -27,7 +28,7 @@ namespace FileTime.Avalonia.ViewModels _commandTimeState.Command.ProgressChanged.Add(HandleProgressChange); } - private Task HandleProgressChange(object? sender, AsyncEventArgs e) + private Task HandleProgressChange(object? sender, AsyncEventArgs e, CancellationToken token = default) { Progress = _commandTimeState.Command.Progress; return Task.CompletedTask; diff --git a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs index ec867af..40209b5 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs +++ b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs @@ -105,7 +105,7 @@ namespace FileTime.Avalonia.Views && sender is StyledElement control && control.DataContext is PlaceInfo placeInfo) { - ViewModel.OpenContainer(placeInfo.Container).Wait(); + ViewModel.OpenContainer(placeInfo.Container); e.Handled = true; } } diff --git a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs index f02e095..b25c2b6 100644 --- a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs +++ b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs @@ -69,7 +69,7 @@ namespace FileTime.Providers.Local return remainingPath.Length == 0 ? rootContainer : await rootContainer.GetByPath(remainingPath, acceptDeepestMatch); } - public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + public async Task RefreshAsync(CancellationToken token = default) => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); public Task Clone() => Task.FromResult((IContainer)this); diff --git a/src/Providers/FileTime.Providers.Local/LocalFile.cs b/src/Providers/FileTime.Providers.Local/LocalFile.cs index 8ea7e1e..1c19bfe 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFile.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFile.cs @@ -59,7 +59,7 @@ namespace FileTime.Providers.Local if (_parent is LocalFolder parentFolder) { System.IO.File.Move(File.FullName, Path.Combine(parentFolder.Directory.FullName, newName)); - await _parent.Refresh(); + await _parent.RefreshAsync(); } } diff --git a/src/Providers/FileTime.Providers.Local/LocalFolder.cs b/src/Providers/FileTime.Providers.Local/LocalFolder.cs index 8971d65..96536f9 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFolder.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFolder.cs @@ -59,16 +59,22 @@ namespace FileTime.Providers.Local public Task Clone() => Task.FromResult((IContainer)new LocalFolder(Directory, Provider, _parent)); - public Task Refresh() + public Task RefreshAsync(CancellationToken token = default) { _containers = new List(); _elements = new List(); + _items = new List(); _exceptions.Clear(); try { + if (token.IsCancellationRequested) return Task.CompletedTask; _containers = Directory.GetDirectories().Select(d => new LocalFolder(d, Provider, this)).OrderBy(d => d.Name).ToList().AsReadOnly(); + + if (token.IsCancellationRequested) return Task.CompletedTask; _elements = Directory.GetFiles().Select(f => new LocalFile(f, this, Provider)).OrderBy(f => f.Name).ToList().AsReadOnly(); + + if (token.IsCancellationRequested) return Task.CompletedTask; } catch (Exception e) { @@ -76,24 +82,24 @@ namespace FileTime.Providers.Local } _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - Refreshed?.InvokeAsync(this, AsyncEventArgs.Empty); + Refreshed?.InvokeAsync(this, AsyncEventArgs.Empty, token); return Task.CompletedTask; } public async Task?> GetItems(CancellationToken token = default) { - if (_items == null) await Refresh(); + if (_items == null) await RefreshAsync(token); return _items; } public async Task?> GetContainers(CancellationToken token = default) { - if (_containers == null) await Refresh(); + if (_containers == null) await RefreshAsync(token); return _containers; } public async Task?> GetElements(CancellationToken token = default) { - if (_elements == null) await Refresh(); + if (_elements == null) await RefreshAsync(token); return _elements; } @@ -118,7 +124,7 @@ namespace FileTime.Providers.Local public async Task CreateContainer(string name) { Directory.CreateSubdirectory(name); - await Refresh(); + await RefreshAsync(); return _containers!.FirstOrDefault(c => Provider.NormalizePath(c.Name) == Provider.NormalizePath(name))!; } @@ -126,7 +132,7 @@ namespace FileTime.Providers.Local public async Task CreateElement(string name) { using (File.Create(Path.Combine(Directory.FullName, name))) { } - await Refresh(); + await RefreshAsync(); return _elements!.FirstOrDefault(e => Provider.NormalizePath(e.Name) == Provider.NormalizePath(name))!; } @@ -150,7 +156,7 @@ namespace FileTime.Providers.Local if (_parent is LocalFolder parentFolder) { System.IO.Directory.Move(Directory.FullName, Path.Combine(parentFolder.Directory.FullName, newName)); - await _parent.Refresh(); + await _parent.RefreshAsync(); } } diff --git a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs index e7d13b2..331b587 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs @@ -51,7 +51,7 @@ namespace FileTime.Providers.Smb _items = _rootContainers.OrderBy(c => c.Name).ToList().AsReadOnly(); } - await Refresh(); + await RefreshAsync(); return container; } @@ -89,7 +89,7 @@ namespace FileTime.Providers.Smb public async Task IsExists(string name) => (await GetItems())?.Any(i => i.Name == name) ?? false; - public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + public async Task RefreshAsync(CancellationToken token = default) => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); public bool CanHandlePath(string path) => path.StartsWith("smb://") || path.StartsWith(@"\\"); diff --git a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs index 67ae469..b1450f4 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs @@ -88,7 +88,7 @@ namespace FileTime.Providers.Smb throw new NotImplementedException(); } - public async Task Refresh() + public async Task RefreshAsync(CancellationToken token = default) { var containers = new List(); var elements = new List(); @@ -96,7 +96,7 @@ namespace FileTime.Providers.Smb try { var path = FullName![(_smbShare.FullName!.Length + 1)..]; - (containers, elements) = await _smbShare.ListFolder(this, _smbShare.Name, path); + (containers, elements) = await _smbShare.ListFolder(this, _smbShare.Name, path, token); } catch { } @@ -104,22 +104,22 @@ namespace FileTime.Providers.Smb _elements = elements.AsReadOnly(); _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); } public async Task?> GetItems(CancellationToken token = default) { - if (_items == null) await Refresh(); + if (_items == null) await RefreshAsync(); return _items; } public async Task?> GetContainers(CancellationToken token = default) { - if (_containers == null) await Refresh(); + if (_containers == null) await RefreshAsync(); return _containers; } public async Task?> GetElements(CancellationToken token = default) { - if (_elements == null) await Refresh(); + if (_elements == null) await RefreshAsync(); return _elements; } public Task CanOpen() => Task.FromResult(true); diff --git a/src/Providers/FileTime.Providers.Smb/SmbServer.cs b/src/Providers/FileTime.Providers.Smb/SmbServer.cs index 3657316..ec39e58 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbServer.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbServer.cs @@ -51,12 +51,12 @@ namespace FileTime.Providers.Smb public async Task?> GetItems(CancellationToken token = default) { - if (_shares == null) await Refresh(); + if (_shares == null) await RefreshAsync(); return _shares; } public async Task?> GetContainers(CancellationToken token = default) { - if (_shares == null) await Refresh(); + if (_shares == null) await RefreshAsync(); return _shares; } public Task?> GetElements(CancellationToken token = default) @@ -91,7 +91,7 @@ namespace FileTime.Providers.Smb throw new NotImplementedException(); } - public async Task Refresh() + public async Task RefreshAsync(CancellationToken token = default) { List shares = await _smbClientContext.RunWithSmbClientAsync((client) => client.ListShares(out var status)); diff --git a/src/Providers/FileTime.Providers.Smb/SmbShare.cs b/src/Providers/FileTime.Providers.Smb/SmbShare.cs index c36551d..7b543d4 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbShare.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbShare.cs @@ -43,17 +43,17 @@ namespace FileTime.Providers.Smb public async Task?> GetItems(CancellationToken token = default) { - if (_items == null) await Refresh(); + if (_items == null) await RefreshAsync(); return _items; } public async Task?> GetContainers(CancellationToken token = default) { - if (_containers == null) await Refresh(); + if (_containers == null) await RefreshAsync(); return _containers; } public async Task?> GetElements(CancellationToken token = default) { - if (_elements == null) await Refresh(); + if (_elements == null) await RefreshAsync(); return _elements; } @@ -100,14 +100,14 @@ namespace FileTime.Providers.Smb throw new NotImplementedException(); } - public async Task Refresh() + public async Task RefreshAsync(CancellationToken token = default) { var containers = new List(); var elements = new List(); try { - (containers, elements) = await ListFolder(this, Name, string.Empty); + (containers, elements) = await ListFolder(this, Name, string.Empty, token); } catch { } @@ -115,10 +115,10 @@ namespace FileTime.Providers.Smb _elements = elements.AsReadOnly(); _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); } - public async Task<(List containers, List elements)> ListFolder(IContainer parent, string shareName, string folderName) + public async Task<(List containers, List elements)> ListFolder(IContainer parent, string shareName, string folderName, CancellationToken token = default) { return await _smbClientContext.RunWithSmbClientAsync(client => {