diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..3c0721e4 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "csharpier": { + "version": "1.2.1", + "commands": [ + "csharpier" + ], + "rollForward": false + }, + "jetbrains.resharper.globaltools": { + "version": "2025.2.4", + "commands": [ + "jb" + ] + } + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..4759af6a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,189 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# All files +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +end_of_line = lf + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# JSON files +[*.json] +indent_size = 2 + +# YAML files +[*.{yml,yaml}] +indent_size = 2 + +# Markdown files +[*.md] +trim_trailing_whitespace = false + +# Shell scripts +[*.sh] +end_of_line = lf + +# Batch files +[*.{cmd,bat}] +end_of_line = crlf + +# TypeScript/JavaScript files +[*.{ts,tsx,js,jsx}] +indent_size = 2 +end_of_line = lf + +# C# files +[*.cs] + +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = one_less_than_current +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents_when_block = false + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_parentheses = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_after_comma = true +csharp_space_before_comma = false +csharp_space_after_dot = false +csharp_space_before_dot = false +csharp_space_after_semicolon_in_for_statement = true +csharp_space_before_semicolon_in_for_statement = false +csharp_space_around_declaration_statements = false +csharp_space_before_open_square_brackets = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_square_brackets = false + +# Organize usings +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false + +# Code style rules +csharp_prefer_braces = true:suggestion +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = false:suggestion + +# Expression preferences +csharp_style_inlined_variable_declaration = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion + +# Null checking preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +# File header +file_header_template = unset + +# Naming conventions +dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = warning +dotnet_naming_rule.interfaces_should_be_prefixed_with_i.symbols = interface +dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = warning +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none diff --git a/.github/scripts/install_deps.sh b/.github/scripts/install_deps.sh old mode 100644 new mode 100755 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d4942ab..d4e00160 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,6 +60,23 @@ jobs: fi echo "Generated version: $VERSION" + lint-and-format: + name: Lint and Format Check + needs: prepare + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v5 + - name: Setup Environment + uses: ./.github/actions/setup-environment + with: + install-build-tools: "false" + - name: Check C# formatting + run: make format-check-csharp + - name: Check TypeScript/JavaScript formatting and linting + run: make format-check-typescript lint-typescript + test: name: Run All Tests needs: prepare @@ -81,7 +98,7 @@ jobs: build: name: Build Binaries - needs: [prepare, test] + needs: [prepare, lint-and-format, test] runs-on: ${{ matrix.os }} if: needs.prepare.outputs.sync == 'false' strategy: @@ -121,7 +138,7 @@ jobs: build-browser: name: Build Browser for Pages - needs: [prepare, test] + needs: [prepare, lint-and-format, test] runs-on: ubuntu-latest steps: - name: Check out code @@ -172,7 +189,6 @@ jobs: deploy-pages: name: Deploy to GitHub Pages needs: [release, build-browser] - if: always() && needs.build-browser.result runs-on: ubuntu-latest environment: name: github-pages diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d6e7fe3..b0b6b26d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,25 @@ concurrency: cancel-in-progress: true jobs: + lint-and-format: + name: Lint and Format Check + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out code + uses: actions/checkout@v5 + + - name: Setup Environment + uses: ./.github/actions/setup-environment + with: + install-build-tools: "false" + + - name: Check C# formatting + run: make format-check-csharp + + - name: Check TypeScript/JavaScript formatting and linting + run: make format-check-typescript lint-typescript + test: name: Run All Tests runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 4971f35e..6d0bece3 100644 --- a/.gitignore +++ b/.gitignore @@ -491,4 +491,6 @@ src/*/.avalonia*/* src/AvaloniaXKCD.Browser/wwwroot # Build output -out/ \ No newline at end of file +out/ + +.lfs-files.txt \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e01109e..dbe7d5a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,4 +22,28 @@ Use the [Dev Container](https://code.visualstudio.com/docs/remote/containers) fo 1. Tests must pass. 2. Include tests for new functionality. -3. Ensure code formatted using `make format`. +3. Ensure code is formatted and linted before submitting: + - Run `make format` to format all code (C# and TypeScript). + - Run `make lint` to check for linting issues in TypeScript. + - Run `make format-check` to verify formatting without making changes. + +### Code Quality Standards + +This project uses automated linting and formatting tools to maintain code quality and consistency: + +- **C#**: Uses CSharpier for opinionated formatting and `dotnet format` for style analysis. ReSharper is available for advanced local linting (optional, requires significant disk space). +- **TypeScript/JavaScript**: Uses Prettier for formatting and ESLint for linting + +**Available Commands:** + +- `make format` - Format all code (C# and TypeScript) +- `make format-csharp` - Format only C# code +- `make format-typescript` - Format only TypeScript code +- `make lint` - Run all linters (TypeScript in CI) +- `make lint-typescript` - Lint TypeScript code +- `make lint-csharp-local` - Lint C# with ReSharper (local development only, resource-intensive) +- `make format-check` - Check formatting without making changes (used in CI) + +**Note on C# Linting:** ReSharper linting (`make lint-csharp-local`) is available for local development but requires building the entire solution and significant disk space (~3GB+). It is not run in CI due to resource constraints. The CI pipeline focuses on formatting checks with CSharpier and dotnet format. + +The CI pipeline will automatically check formatting and linting on all pull requests. diff --git a/makefile b/makefile index ea7dee8a..0f1d5aab 100644 --- a/makefile +++ b/makefile @@ -183,15 +183,46 @@ endif @dotnet tool install --global verify.tool @dotnet tool install --global dotnet-outdated-tool @dotnet tool install --global KuiperZone.PupNet - @cd src; dotnet workload restore - @cd src/AvaloniaXKCD.Site; bun ci + @dotnet tool restore + @cd src/AvaloniaXKCD.Site; npm ci + @cd src; sudo dotnet workload restore setup-playwright: ## Setup playwright browsers for testing. @cd src; dotnet build; dotnet dnx -y Microsoft.Playwright.CLI -p ./AvaloniaXKCD.Tests install --with-deps -format: ## Format source code. +format-csharp: ## Format C# source code with CSharpier and dotnet format. + @$(ECHO) "--- Formatting C# code ---" + @dotnet csharpier format . @cd src; dotnet format +format-typescript: ## Format TypeScript/JavaScript source code with Prettier. + @$(ECHO) "--- Formatting TypeScript/JavaScript code with Prettier ---" + @cd src/AvaloniaXKCD.Site; npm run format + +format: format-csharp format-typescript ## Format all source code (C# and TypeScript). + +format-check-csharp: ## Check C# formatting without making changes. + @$(ECHO) "--- Checking C# formatting ---" + @dotnet csharpier check . + @cd src; dotnet format --verify-no-changes + +format-check-typescript: ## Check TypeScript/JavaScript formatting without making changes. + @$(ECHO) "--- Checking TypeScript/JavaScript formatting ---" + @cd src/AvaloniaXKCD.Site; npm run format:check + +format-check: format-check-csharp format-check-typescript ## Check all code formatting (C# and TypeScript). + +lint-csharp-local: ## Lint C# source code with ReSharper (local development only - requires significant disk space). + @$(ECHO) "--- Linting C# code with ReSharper (this may take several minutes) ---" + @cd src; dotnet jb inspectcode AvaloniaXKCD.slnx --output=/tmp/resharper-report.xml --severity=WARNING --build + @$(ECHO) "ReSharper report generated at /tmp/resharper-report.xml" + +lint-typescript: ## Lint TypeScript/JavaScript source code. + @$(ECHO) "--- Linting TypeScript/JavaScript code ---" + @cd src/AvaloniaXKCD.Site; npm run lint + +lint: lint-typescript ## Lint all source code (TypeScript only in CI). + clean: ## Clean local environment (bin/obj folders). @cd src; dotnet clean diff --git a/src/.csharpierignore b/src/.csharpierignore new file mode 100644 index 00000000..b3cb54d2 --- /dev/null +++ b/src/.csharpierignore @@ -0,0 +1 @@ +AvaloniaXKCD.Tests/Setup/GlobalUsings.Tests.cs \ No newline at end of file diff --git a/src/.csharpierrc.json b/src/.csharpierrc.json new file mode 100644 index 00000000..e071b2a9 --- /dev/null +++ b/src/.csharpierrc.json @@ -0,0 +1,6 @@ +{ + "printWidth": 120, + "useTabs": false, + "tabWidth": 4, + "endOfLine": "lf" +} diff --git a/src/AvaloniaXKCD.Browser/AvaloniaXKCD.Browser.csproj b/src/AvaloniaXKCD.Browser/AvaloniaXKCD.Browser.csproj index d79df0ee..900ad7b1 100644 --- a/src/AvaloniaXKCD.Browser/AvaloniaXKCD.Browser.csproj +++ b/src/AvaloniaXKCD.Browser/AvaloniaXKCD.Browser.csproj @@ -1,25 +1,29 @@ - - - net10.0-browser - Exe - true - true - false - true - true - InterpreterAndAOT - false - - - - - - - - - - - - - - + + + net10.0-browser + Exe + true + true + false + true + true + InterpreterAndAOT + false + + + + + + + + + + + + + + diff --git a/src/AvaloniaXKCD.Browser/BuildSite.targets b/src/AvaloniaXKCD.Browser/BuildSite.targets index 42370afe..7a3450b2 100644 --- a/src/AvaloniaXKCD.Browser/BuildSite.targets +++ b/src/AvaloniaXKCD.Browser/BuildSite.targets @@ -12,9 +12,17 @@ - - + + - \ No newline at end of file + diff --git a/src/AvaloniaXKCD.Browser/CSharpEventBridge.cs b/src/AvaloniaXKCD.Browser/CSharpEventBridge.cs index 8b7555e4..e1d0c7e9 100644 --- a/src/AvaloniaXKCD.Browser/CSharpEventBridge.cs +++ b/src/AvaloniaXKCD.Browser/CSharpEventBridge.cs @@ -19,14 +19,13 @@ private Handler(object original, Action wrapped) WrappedHandler = wrapped; } - public static implicit operator Handler(Action action) - => new(action, action); + public static implicit operator Handler(Action action) => new(action, action); - public static implicit operator Handler(EventHandler eventHandler) - => new(eventHandler, data => eventHandler(null, data)); + public static implicit operator Handler(EventHandler eventHandler) => + new(eventHandler, data => eventHandler(null, data)); - public static implicit operator Handler(CSharpGenericEventHandler csharpGenericEventHandler) - => new(csharpGenericEventHandler, data => csharpGenericEventHandler(data)); + public static implicit operator Handler(CSharpGenericEventHandler csharpGenericEventHandler) => + new(csharpGenericEventHandler, data => csharpGenericEventHandler(data)); } public abstract class EventBridge @@ -112,12 +111,10 @@ public static partial class CSharpEventBridgeFactory } } - public static string? Add(string handlerName, Action callback) - => GetBridge(handlerName)?.Add(callback); + public static string? Add(string handlerName, Action callback) => GetBridge(handlerName)?.Add(callback); - public static void Remove(string handlerName, string subscription) - => GetBridge(handlerName)?.Remove(subscription); + public static void Remove(string handlerName, string subscription) => + GetBridge(handlerName)?.Remove(subscription); - public static void Invoke(string handlerName, T data) - => GetBridge(handlerName)?.Invoke(data); -} \ No newline at end of file + public static void Invoke(string handlerName, T data) => GetBridge(handlerName)?.Invoke(data); +} diff --git a/src/AvaloniaXKCD.Browser/Exports/Config.cs b/src/AvaloniaXKCD.Browser/Exports/Config.cs index 43a68d0e..b6157a48 100644 --- a/src/AvaloniaXKCD.Browser/Exports/Config.cs +++ b/src/AvaloniaXKCD.Browser/Exports/Config.cs @@ -4,11 +4,20 @@ namespace AvaloniaXKCD.Browser; public class Config : IConfig { - public PlatformType PlatformType { get => PlatformType.Browser; } + public PlatformType PlatformType + { + get => PlatformType.Browser; + } #if DEBUG - public LogLevel LogLevel { get => LogLevel.Trace; } + public LogLevel LogLevel + { + get => LogLevel.Trace; + } #else - public LogLevel LogLevel { get => LogLevel.Critical; } + public LogLevel LogLevel + { + get => LogLevel.Critical; + } #endif -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Browser/Exports/LocalizationService.cs b/src/AvaloniaXKCD.Browser/Exports/LocalizationService.cs index cc637055..f02be996 100644 --- a/src/AvaloniaXKCD.Browser/Exports/LocalizationService.cs +++ b/src/AvaloniaXKCD.Browser/Exports/LocalizationService.cs @@ -19,11 +19,11 @@ public partial class BrowserLocalizationService : LocalizationService [JSImport("getString", "interop")] internal static partial string GetBrowserString(string key); - public override CultureInfo GetCulture() - => GetBrowserLocale() switch + public override CultureInfo GetCulture() => + GetBrowserLocale() switch { null or "" => CultureInfo.GetCultureInfo("en"), - var locale => CultureInfo.GetCultureInfo(locale) + var locale => CultureInfo.GetCultureInfo(locale), }; public override string GetString(string key) @@ -31,7 +31,8 @@ public override string GetString(string key) return GetBrowserString(key); } - public BrowserLocalizationService() : base() + public BrowserLocalizationService() + : base() { CultureChanged += OnCultureChangedHandler; } diff --git a/src/AvaloniaXKCD.Browser/Exports/Logger.cs b/src/AvaloniaXKCD.Browser/Exports/Logger.cs index 35469dd9..4630b530 100644 --- a/src/AvaloniaXKCD.Browser/Exports/Logger.cs +++ b/src/AvaloniaXKCD.Browser/Exports/Logger.cs @@ -12,21 +12,29 @@ public partial class BrowserLogger : ILogger { [JSImport("globalThis.console.log")] internal static partial Task Log([JSMarshalAs] string message); + [JSImport("globalThis.console.info")] internal static partial Task Info([JSMarshalAs] string message); + [JSImport("globalThis.console.warn")] internal static partial Task Warn([JSMarshalAs] string message); + [JSImport("globalThis.console.debug")] internal static partial Task Debug([JSMarshalAs] string message); + [JSImport("globalThis.console.error")] internal static partial Task Error([JSMarshalAs] string message); + [JSImport("globalThis.console.trace")] internal static partial Task Trace([JSMarshalAs] string message); - public bool ShouldLog(LogLevel level) => level.ShouldLog(App.Config.LogLevel); - public void Log(LogLevel level, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) + + public void Log( + LogLevel level, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) { var messageTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); var category = Path.GetFileNameWithoutExtension(file); @@ -54,7 +62,10 @@ public void Log(LogLevel level, string message, break; } } - public void Log(LogLevel level, Exception err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => Log(level, err.ToString(), file); -} \ No newline at end of file + + public void Log( + LogLevel level, + Exception err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => Log(level, err.ToString(), file); +} diff --git a/src/AvaloniaXKCD.Browser/Exports/SettingsRepo.cs b/src/AvaloniaXKCD.Browser/Exports/SettingsRepo.cs index fbecdf9b..f4da0cc9 100644 --- a/src/AvaloniaXKCD.Browser/Exports/SettingsRepo.cs +++ b/src/AvaloniaXKCD.Browser/Exports/SettingsRepo.cs @@ -1,11 +1,11 @@ using System; -using AvaloniaXKCD.Exports; +using System.Runtime.InteropServices.JavaScript; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; -using System.Runtime.InteropServices.JavaScript; using System.Threading.Tasks; +using AvaloniaXKCD.Exports; namespace AvaloniaXKCD.Browser; @@ -21,7 +21,6 @@ public LocalStorageSettingsRepo() Load(); } - // JS-imported localStorage [JSImport("globalThis.localStorage.getItem")] internal static partial Task LocalStorage_GetItem(string key); @@ -75,4 +74,4 @@ public override void Set(T obj, JsonTypeInfo typeInfo) Save(); } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Browser/Exports/SystemActions.cs b/src/AvaloniaXKCD.Browser/Exports/SystemActions.cs index e3371065..f853754f 100644 --- a/src/AvaloniaXKCD.Browser/Exports/SystemActions.cs +++ b/src/AvaloniaXKCD.Browser/Exports/SystemActions.cs @@ -11,13 +11,16 @@ public partial class BrowserSystemActions : ISystemActions { #region Handle URI Change [JSExport] - public static string? AddOnUriChangeCallback([JSMarshalAs>()] Action callback) + public static string? AddOnUriChangeCallback( + [JSMarshalAs>()] Action callback + ) { if (App.SystemActions is BrowserSystemActions self && self._uriChangeBridge != null) { return self._uriChangeBridge.Add(callback); } - else throw new NullReferenceException(); + else + throw new NullReferenceException(); } [JSExport] @@ -27,7 +30,8 @@ public static void RemoveOnUriChangeCallback(string subscription) { self._uriChangeBridge.Remove(subscription); } - else throw new NullReferenceException(); + else + throw new NullReferenceException(); } [JSExport] @@ -37,21 +41,25 @@ public static void InvokeOnUriChangeCallback(string uri) { self._uriChangeBridge.Invoke(uri); } - else throw new NullReferenceException(); + else + throw new NullReferenceException(); } - private readonly CSharpGenericEventBridge? _uriChangeBridge = - CSharpEventBridgeFactory.GetBridge($"{nameof(BrowserSystemActions)}.${nameof(OnUriChange)}"); + private readonly CSharpGenericEventBridge? _uriChangeBridge = CSharpEventBridgeFactory.GetBridge( + $"{nameof(BrowserSystemActions)}.${nameof(OnUriChange)}" + ); public event EventHandler? OnUriChange { add { - if (value != null) _uriChangeBridge?.Add(value); + if (value != null) + _uriChangeBridge?.Add(value); } remove { - if (value != null) _uriChangeBridge?.Remove(value); + if (value != null) + _uriChangeBridge?.Remove(value); } } @@ -85,4 +93,4 @@ public void SetTitle(string title) { SetTitleInternal(title); } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Browser/Program.cs b/src/AvaloniaXKCD.Browser/Program.cs index c00b01e7..10d2b0bf 100644 --- a/src/AvaloniaXKCD.Browser/Program.cs +++ b/src/AvaloniaXKCD.Browser/Program.cs @@ -1,28 +1,32 @@ -using System; -using System.Runtime.Versioning; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Browser; -using AvaloniaXKCD; -using AvaloniaXKCD.Browser; -using AvaloniaXKCD.Exports; - -internal sealed partial class Program -{ - private static Task Main(string[] args) => - CommandLineParser.Instance.Invoke(args, async (parsedArguments) => - await BuildAvaloniaApp(parsedArguments) - .WithInterFont() - .StartBrowserAppAsync("out")).ContinueWith(result => - { - if (result.IsFaulted) - { - ExportContainer.Get()?.HandleError(result.Exception); - Environment.FailFast(result.Exception.ToString()); - } - }); - - public static AppBuilder BuildAvaloniaApp() => BuildAvaloniaApp(new ParsedArguments()); - public static AppBuilder BuildAvaloniaApp(ParsedArguments parsedArguments) - => AppBuilder.Configure(() => new App(parsedArguments)); -} \ No newline at end of file +using System; +using System.Runtime.Versioning; +using System.Threading.Tasks; +using Avalonia; +using Avalonia.Browser; +using AvaloniaXKCD; +using AvaloniaXKCD.Browser; +using AvaloniaXKCD.Exports; + +internal sealed partial class Program +{ + private static Task Main(string[] args) => + CommandLineParser + .Instance.Invoke( + args, + async (parsedArguments) => + await BuildAvaloniaApp(parsedArguments).WithInterFont().StartBrowserAppAsync("out") + ) + .ContinueWith(result => + { + if (result.IsFaulted) + { + ExportContainer.Get()?.HandleError(result.Exception); + Environment.FailFast(result.Exception.ToString()); + } + }); + + public static AppBuilder BuildAvaloniaApp() => BuildAvaloniaApp(new ParsedArguments()); + + public static AppBuilder BuildAvaloniaApp(ParsedArguments parsedArguments) => + AppBuilder.Configure(() => new App(parsedArguments)); +} diff --git a/src/AvaloniaXKCD.Browser/Properties/AssemblyInfo.cs b/src/AvaloniaXKCD.Browser/Properties/AssemblyInfo.cs index e64d71fd..c4039b7b 100644 --- a/src/AvaloniaXKCD.Browser/Properties/AssemblyInfo.cs +++ b/src/AvaloniaXKCD.Browser/Properties/AssemblyInfo.cs @@ -1 +1 @@ -[assembly: System.Runtime.Versioning.SupportedOSPlatform("browser")] +[assembly: System.Runtime.Versioning.SupportedOSPlatform("browser")] diff --git a/src/AvaloniaXKCD.Desktop/AvaloniaXKCD.Desktop.csproj b/src/AvaloniaXKCD.Desktop/AvaloniaXKCD.Desktop.csproj index 0366eb30..a0bdf224 100644 --- a/src/AvaloniaXKCD.Desktop/AvaloniaXKCD.Desktop.csproj +++ b/src/AvaloniaXKCD.Desktop/AvaloniaXKCD.Desktop.csproj @@ -1,44 +1,48 @@ - - - WinExe - net10.0 - true - true - true - false - Assets\avalonia-logo.ico - AXKCD - - - - app.manifest - - - - - - None - All - - - - - - - - - - - - - - WINDOWS - $(NoWarn);CA1416 - - - MACOS - - - LINUX - - + + + WinExe + net10.0 + true + true + true + false + Assets\avalonia-logo.ico + AXKCD + + + + app.manifest + + + + + + None + All + + + + + + + + + + + + + + WINDOWS + $(NoWarn);CA1416 + + + MACOS + + + LINUX + + diff --git a/src/AvaloniaXKCD.Desktop/Exports/Config.cs b/src/AvaloniaXKCD.Desktop/Exports/Config.cs index 50862806..58aed52b 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/Config.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/Config.cs @@ -4,11 +4,20 @@ namespace AvaloniaXKCD.Desktop; public class Config : IConfig { - public PlatformType PlatformType { get => PlatformType.Desktop; } + public PlatformType PlatformType + { + get => PlatformType.Desktop; + } #if DEBUG - public LogLevel LogLevel { get => LogLevel.Trace; } + public LogLevel LogLevel + { + get => LogLevel.Trace; + } #else - public LogLevel LogLevel { get => LogLevel.Critical; } + public LogLevel LogLevel + { + get => LogLevel.Critical; + } #endif -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Desktop/Exports/LocalizationService.cs b/src/AvaloniaXKCD.Desktop/Exports/LocalizationService.cs index 1dc7879c..5042ffad 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/LocalizationService.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/LocalizationService.cs @@ -8,6 +8,5 @@ namespace AvaloniaXKCD.Desktop; /// public class DesktopLocalizationService : LocalizationService { - public override CultureInfo GetCulture() - => CultureInfo.CurrentUICulture; + public override CultureInfo GetCulture() => CultureInfo.CurrentUICulture; } diff --git a/src/AvaloniaXKCD.Desktop/Exports/Logger.cs b/src/AvaloniaXKCD.Desktop/Exports/Logger.cs index 9c1f31fc..b1f39880 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/Logger.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/Logger.cs @@ -16,13 +16,14 @@ public class DesktopLogger : Exports.ILogger public DesktopLogger() { _innerFactory = LoggerFactory.Create(builder => - builder.AddSimpleConsole(options => - { - options.IncludeScopes = false; - options.SingleLine = true; - options.TimestampFormat = "HH:mm:ss "; - }) - .SetMinimumLevel(MapLevel(App.Config.LogLevel)) + builder + .AddSimpleConsole(options => + { + options.IncludeScopes = false; + options.SingleLine = true; + options.TimestampFormat = "HH:mm:ss "; + }) + .SetMinimumLevel(MapLevel(App.Config.LogLevel)) ); } @@ -35,20 +36,25 @@ private Microsoft.Extensions.Logging.LogLevel MapLevel(Exports.LogLevel level) = Exports.LogLevel.Warning => Microsoft.Extensions.Logging.LogLevel.Warning, Exports.LogLevel.Error => Microsoft.Extensions.Logging.LogLevel.Error, Exports.LogLevel.Critical => Microsoft.Extensions.Logging.LogLevel.Critical, - _ => Microsoft.Extensions.Logging.LogLevel.None + _ => Microsoft.Extensions.Logging.LogLevel.None, }; public bool ShouldLog(Exports.LogLevel level) => level.ShouldLog(App.Config.LogLevel); - public void Log(Exports.LogLevel level, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) + public void Log( + Exports.LogLevel level, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) { var category = Path.GetFileNameWithoutExtension(file); var logger = _innerFactory.CreateLogger(category ?? "Logger"); logger.Log(MapLevel(level), message); } - public void Log(Exports.LogLevel level, Exception ex, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => Log(level, ex.Message, file); -} \ No newline at end of file + public void Log( + Exports.LogLevel level, + Exception ex, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => Log(level, ex.Message, file); +} diff --git a/src/AvaloniaXKCD.Desktop/Exports/SettingsRepo.cs b/src/AvaloniaXKCD.Desktop/Exports/SettingsRepo.cs index 0eaf78e7..f23d7f70 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/SettingsRepo.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/SettingsRepo.cs @@ -1,10 +1,10 @@ using System; using System.IO; -using AvaloniaXKCD.Exports; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; +using AvaloniaXKCD.Exports; namespace AvaloniaXKCD.Desktop; @@ -23,6 +23,7 @@ public JsonSettingsRepo() } private bool _isDirty = false; + public override void Save() { if (!_isDirty) @@ -73,4 +74,4 @@ public override void Set(T obj, JsonTypeInfo typeInfo) _isDirty = true; } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Linux.cs b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Linux.cs index d877509a..beb984e6 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Linux.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Linux.cs @@ -27,4 +27,4 @@ internal static partial class NativeMethods [LibraryImport("libc", EntryPoint = "syslog")] internal static partial void syslog(int priority, byte[] message); } -#endif \ No newline at end of file +#endif diff --git a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Windows.cs b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Windows.cs index 4fa219fe..bc87deb3 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Windows.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.Windows.cs @@ -28,4 +28,4 @@ internal bool HandleErrorWindows(Exception error) } } } -#endif \ No newline at end of file +#endif diff --git a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.cs b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.cs index 6b0ec39b..e6f20496 100644 --- a/src/AvaloniaXKCD.Desktop/Exports/SystemActions.cs +++ b/src/AvaloniaXKCD.Desktop/Exports/SystemActions.cs @@ -38,4 +38,4 @@ public void SetTitle(string title) { // Noop } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Desktop/Program.cs b/src/AvaloniaXKCD.Desktop/Program.cs index a5efa457..bc88d806 100644 --- a/src/AvaloniaXKCD.Desktop/Program.cs +++ b/src/AvaloniaXKCD.Desktop/Program.cs @@ -1,48 +1,53 @@ -using System; -using System.Runtime.Loader; -using System.Threading; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Controls; -using AvaloniaXKCD.Exports; - -namespace AvaloniaXKCD.Desktop; - -sealed class Program -{ - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. - [STAThread] - public static async Task Main(string[] args) - { - var cts = new CancellationTokenSource(); - Console.CancelKeyPress += (s, e) => - { - cts.Cancel(); - e.Cancel = true; - }; - - return await CommandLineParser.Instance.Invoke(args, async (parsedArgs) => - { - try - { - return BuildAvaloniaApp(parsedArgs, cts.Token) - .StartWithClassicDesktopLifetime(args); - } - catch (Exception err) - { - ExportContainer.Get()?.HandleError(err); - throw; - } - }, cts.Token); - } - - // Avalonia configuration, don't remove; also used by visual designer. - public static AppBuilder BuildAvaloniaApp() => BuildAvaloniaApp(new ParsedArguments(), CancellationToken.None); - public static AppBuilder BuildAvaloniaApp(ParsedArguments parsedArguments, CancellationToken cancellationToken) - => AppBuilder.Configure(() => new App(parsedArguments, cancellationToken)) - .UsePlatformDetect() - .WithInterFont() - .LogToTrace(); -} +using System; +using System.Runtime.Loader; +using System.Threading; +using System.Threading.Tasks; +using Avalonia; +using Avalonia.Controls; +using AvaloniaXKCD.Exports; + +namespace AvaloniaXKCD.Desktop; + +sealed class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static async Task Main(string[] args) + { + var cts = new CancellationTokenSource(); + Console.CancelKeyPress += (s, e) => + { + cts.Cancel(); + e.Cancel = true; + }; + + return await CommandLineParser.Instance.Invoke( + args, + async (parsedArgs) => + { + try + { + return BuildAvaloniaApp(parsedArgs, cts.Token).StartWithClassicDesktopLifetime(args); + } + catch (Exception err) + { + ExportContainer.Get()?.HandleError(err); + throw; + } + }, + cts.Token + ); + } + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() => BuildAvaloniaApp(new ParsedArguments(), CancellationToken.None); + + public static AppBuilder BuildAvaloniaApp(ParsedArguments parsedArguments, CancellationToken cancellationToken) => + AppBuilder + .Configure(() => new App(parsedArguments, cancellationToken)) + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} diff --git a/src/AvaloniaXKCD.Exports/AvaloniaXKCD.Exports.csproj b/src/AvaloniaXKCD.Exports/AvaloniaXKCD.Exports.csproj index bdc90881..6ae00721 100644 --- a/src/AvaloniaXKCD.Exports/AvaloniaXKCD.Exports.csproj +++ b/src/AvaloniaXKCD.Exports/AvaloniaXKCD.Exports.csproj @@ -1,5 +1,4 @@  - netstandard2.0 @@ -7,5 +6,4 @@ - diff --git a/src/AvaloniaXKCD.Exports/ExportContainer.cs b/src/AvaloniaXKCD.Exports/ExportContainer.cs index 3b7c1ce2..e10ed625 100644 --- a/src/AvaloniaXKCD.Exports/ExportContainer.cs +++ b/src/AvaloniaXKCD.Exports/ExportContainer.cs @@ -6,15 +6,22 @@ public partial class ExportContainer { private static readonly Dictionary>> _multiFactories = new(); - public static void Add(string name, Func factory) where T : IExport => AddMulti(name, factory); - - public static void Add(Func factory) where T : IExport => Add(typeof(T).FullName, factory); - - public static void Add(string name) where T : IExport where C : T, new() => Add(name, () => new C()); - - public static void Add() where T : IExport where C : T, new() => Add(() => new C()); - - public static void AddMulti(string name, Func factory) where T : IExport + public static void Add(string name, Func factory) + where T : IExport => AddMulti(name, factory); + + public static void Add(Func factory) + where T : IExport => Add(typeof(T).FullName, factory); + + public static void Add(string name) + where T : IExport + where C : T, new() => Add(name, () => new C()); + + public static void Add() + where T : IExport + where C : T, new() => Add(() => new C()); + + public static void AddMulti(string name, Func factory) + where T : IExport { if (!_multiFactories.ContainsKey(name)) { @@ -22,19 +29,29 @@ public static void AddMulti(string name, Func factory) where T : IExport } _multiFactories[name].Add(new Lazy(() => factory())); } - - public static void AddMulti(Func factory) where T : IExport => AddMulti(typeof(T).FullName, factory); - - public static void AddMulti(string name) where T : IExport where C : T, new() => AddMulti(name, () => new C()); - - public static void AddMulti() where T : IExport where C : T, new() => AddMulti(() => new C()); - - public static T? Get(string name) where T : IExport => GetAllEnumerable(name).SingleOrDefault(); - - public static T? Get() where T : IExport => Get(typeof(T).FullName); - - public static T[] GetAll(string name) where T : IExport => GetAllEnumerable(name).ToArray(); - static IEnumerable GetAllEnumerable(string name) where T : IExport + + public static void AddMulti(Func factory) + where T : IExport => AddMulti(typeof(T).FullName, factory); + + public static void AddMulti(string name) + where T : IExport + where C : T, new() => AddMulti(name, () => new C()); + + public static void AddMulti() + where T : IExport + where C : T, new() => AddMulti(() => new C()); + + public static T? Get(string name) + where T : IExport => GetAllEnumerable(name).SingleOrDefault(); + + public static T? Get() + where T : IExport => Get(typeof(T).FullName); + + public static T[] GetAll(string name) + where T : IExport => GetAllEnumerable(name).ToArray(); + + static IEnumerable GetAllEnumerable(string name) + where T : IExport { if (!_multiFactories.TryGetValue(name, out var lazyList)) { @@ -42,6 +59,7 @@ static IEnumerable GetAllEnumerable(string name) where T : IExport } return lazyList.Select(lazy => (T)lazy.Value); } - - public static T[] GetAll() where T : IExport => GetAll(typeof(T).FullName); -} \ No newline at end of file + + public static T[] GetAll() + where T : IExport => GetAll(typeof(T).FullName); +} diff --git a/src/AvaloniaXKCD.Exports/IConfig.cs b/src/AvaloniaXKCD.Exports/IConfig.cs index 0e28b0a2..87b7bf77 100644 --- a/src/AvaloniaXKCD.Exports/IConfig.cs +++ b/src/AvaloniaXKCD.Exports/IConfig.cs @@ -11,5 +11,5 @@ public enum PlatformType { Headless, Browser, - Desktop -}; \ No newline at end of file + Desktop, +}; diff --git a/src/AvaloniaXKCD.Exports/IExport.cs b/src/AvaloniaXKCD.Exports/IExport.cs index 4b9542dc..20637e7c 100644 --- a/src/AvaloniaXKCD.Exports/IExport.cs +++ b/src/AvaloniaXKCD.Exports/IExport.cs @@ -1,3 +1,3 @@ -namespace AvaloniaXKCD.Exports; +namespace AvaloniaXKCD.Exports; public interface IExport { } diff --git a/src/AvaloniaXKCD.Exports/ILogger.cs b/src/AvaloniaXKCD.Exports/ILogger.cs index 9ef57c14..6b98c2f7 100644 --- a/src/AvaloniaXKCD.Exports/ILogger.cs +++ b/src/AvaloniaXKCD.Exports/ILogger.cs @@ -4,61 +4,110 @@ public interface ILogger : IExport { bool ShouldLog(LogLevel level); - void Log(LogLevel level, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null); - public void Log(LogLevel level, Exception err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null); + void Log(LogLevel level, string message, [System.Runtime.CompilerServices.CallerFilePath] string? file = null); + public void Log( + LogLevel level, + Exception err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ); } public abstract class BaseLogger : ILogger { - public bool ShouldLogTrace { get => ShouldLog(LogLevel.Trace); } - public bool ShouldLogDebug { get => ShouldLog(LogLevel.Debug); } - public bool ShouldLogInformation { get => ShouldLog(LogLevel.Information); } - public bool ShouldLogWarning { get => ShouldLog(LogLevel.Warning); } - public bool ShouldLogError { get => ShouldLog(LogLevel.Error); } - public bool ShouldLogCritical { get => ShouldLog(LogLevel.Critical); } + public bool ShouldLogTrace + { + get => ShouldLog(LogLevel.Trace); + } + public bool ShouldLogDebug + { + get => ShouldLog(LogLevel.Debug); + } + public bool ShouldLogInformation + { + get => ShouldLog(LogLevel.Information); + } + public bool ShouldLogWarning + { + get => ShouldLog(LogLevel.Warning); + } + public bool ShouldLogError + { + get => ShouldLog(LogLevel.Error); + } + public bool ShouldLogCritical + { + get => ShouldLog(LogLevel.Critical); + } public abstract bool ShouldLog(LogLevel level); - - public abstract void Log(LogLevel level, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null); - public abstract void Log(LogLevel level, Exception err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null); + public abstract void Log( + LogLevel level, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ); + public abstract void Log( + LogLevel level, + Exception err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ); } public static class LoggerExtensions { - public static void LogTrace(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Trace, message, file); - public static void LogDebug(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Debug, message, file); - public static void LogInformation(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Information, message, file); - public static void LogWarning(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Warning, message, file); - public static void LogError(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Error, message, file); - public static void LogError(this ILogger logger, Exception err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Error, err, file); - public static void LogCritical(this ILogger logger, string message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Critical, message, file); - public static void LogCritical(this ILogger logger, Exception err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.Log(LogLevel.Error, err, file); + public static void LogTrace( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Trace, message, file); + + public static void LogDebug( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Debug, message, file); + + public static void LogInformation( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Information, message, file); + + public static void LogWarning( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Warning, message, file); + + public static void LogError( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Error, message, file); + + public static void LogError( + this ILogger logger, + Exception err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Error, err, file); + + public static void LogCritical( + this ILogger logger, + string message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Critical, message, file); + + public static void LogCritical( + this ILogger logger, + Exception err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.Log(LogLevel.Error, err, file); public static bool IfShouldLog( this ILogger logger, LogLevel level, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) { if (logger.ShouldLog(level)) { @@ -67,11 +116,13 @@ public static bool IfShouldLog( } return false; } + public static bool IfShouldLog( this ILogger logger, LogLevel level, Func err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) { if (logger.ShouldLog(level)) { @@ -81,33 +132,55 @@ public static bool IfShouldLog( return false; } - public static bool IfShouldLogTrace(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Trace, message, file); - public static bool IfShouldLogDebug(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Debug, message, file); - public static bool IfShouldLogInformation(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Information, message, file); - public static bool IfShouldLogWarning(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Warning, message, file); - public static bool IfShouldLogError(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Error, message, file); - public static bool IfShouldLogError(this ILogger logger, Func err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Error, err, file); - public static bool IfShouldLogCritical(this ILogger logger, Func message, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Critical, message, file); - public static bool IfShouldLogCritical(this ILogger logger, Func err, - [System.Runtime.CompilerServices.CallerFilePath] string? file = null) - => logger.IfShouldLog(LogLevel.Error, err, file); - - public static bool ShouldLog(this LogLevel currentLevel, LogLevel desiredLevel) - => currentLevel >= desiredLevel; + public static bool IfShouldLogTrace( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Trace, message, file); + + public static bool IfShouldLogDebug( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Debug, message, file); + + public static bool IfShouldLogInformation( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Information, message, file); + + public static bool IfShouldLogWarning( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Warning, message, file); + + public static bool IfShouldLogError( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Error, message, file); + + public static bool IfShouldLogError( + this ILogger logger, + Func err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Error, err, file); + + public static bool IfShouldLogCritical( + this ILogger logger, + Func message, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Critical, message, file); + + public static bool IfShouldLogCritical( + this ILogger logger, + Func err, + [System.Runtime.CompilerServices.CallerFilePath] string? file = null + ) => logger.IfShouldLog(LogLevel.Error, err, file); + + public static bool ShouldLog(this LogLevel currentLevel, LogLevel desiredLevel) => currentLevel >= desiredLevel; } public enum LogLevel @@ -118,5 +191,5 @@ public enum LogLevel Warning, Error, Critical, - None -} \ No newline at end of file + None, +} diff --git a/src/AvaloniaXKCD.Exports/ISettingsRepo.cs b/src/AvaloniaXKCD.Exports/ISettingsRepo.cs index cf73a115..4267a060 100644 --- a/src/AvaloniaXKCD.Exports/ISettingsRepo.cs +++ b/src/AvaloniaXKCD.Exports/ISettingsRepo.cs @@ -10,7 +10,8 @@ public interface ISettingsRepo : IExport, IDisposable void Load(); void Save(); - T? Get(JsonTypeInfo typeInfo) where T : class, new(); + T? Get(JsonTypeInfo typeInfo) + where T : class, new(); void Set(T obj, JsonTypeInfo typeInfo); } @@ -20,7 +21,8 @@ public abstract class BaseSettingsRepo : ISettingsRepo public abstract void Load(); - public abstract T? Get(JsonTypeInfo typeInfo) where T : class, new(); + public abstract T? Get(JsonTypeInfo typeInfo) + where T : class, new(); public abstract void Set(T obj, JsonTypeInfo typeInfo); void IDisposable.Dispose() @@ -36,4 +38,4 @@ protected virtual void Dispose(bool disposing) Save(); } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Exports/ISystemActions.cs b/src/AvaloniaXKCD.Exports/ISystemActions.cs index 7dc9ba24..e103a66f 100644 --- a/src/AvaloniaXKCD.Exports/ISystemActions.cs +++ b/src/AvaloniaXKCD.Exports/ISystemActions.cs @@ -7,4 +7,4 @@ public interface ISystemActions : IExport public event EventHandler? OnUriChange; public void InvokeOnUriChange(string newUri); public void SetTitle(string title); -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Generators/AvaloniaXKCD.Generators.csproj b/src/AvaloniaXKCD.Generators/AvaloniaXKCD.Generators.csproj index c210097f..9ff797e9 100644 --- a/src/AvaloniaXKCD.Generators/AvaloniaXKCD.Generators.csproj +++ b/src/AvaloniaXKCD.Generators/AvaloniaXKCD.Generators.csproj @@ -1,5 +1,4 @@  - netstandard2.0 true @@ -25,7 +24,12 @@ - + @@ -41,8 +45,10 @@ - + - - \ No newline at end of file + diff --git a/src/AvaloniaXKCD.Generators/ExportRegistrarGenerator.cs b/src/AvaloniaXKCD.Generators/ExportRegistrarGenerator.cs index 3c4a8883..860834f1 100644 --- a/src/AvaloniaXKCD.Generators/ExportRegistrarGenerator.cs +++ b/src/AvaloniaXKCD.Generators/ExportRegistrarGenerator.cs @@ -16,7 +16,13 @@ public class ExportRegistrarGenerator : IIncrementalGenerator // Models for the Scriban template public record ConstructorDependency(string Type); - public record ExportedType(string FullTypeName, List Interfaces, List ConstructorDependencies); + + public record ExportedType( + string FullTypeName, + List Interfaces, + List ConstructorDependencies + ); + public record ExportedInterface(string Name, List Implementations); public void Initialize(IncrementalGeneratorInitializationContext context) @@ -27,10 +33,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context) Debugger.Launch(); } #endif - var exportsProvider = context.SyntaxProvider - .CreateSyntaxProvider( + var exportsProvider = context + .SyntaxProvider.CreateSyntaxProvider( static (syntax, _) => syntax is ClassDeclarationSyntax { BaseList: not null }, - static (ctx, _) => TransformClass(ctx)) + static (ctx, _) => TransformClass(ctx) + ) .Where(static model => model is not null); context.RegisterSourceOutput(exportsProvider.Collect(), GenerateSource); @@ -41,7 +48,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context) if (ctx.Node is not ClassDeclarationSyntax classDecl) return null; - if (ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol || typeSymbol.IsAbstract) + if ( + ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol + || typeSymbol.IsAbstract + ) return null; var iExportInterface = ctx.SemanticModel.Compilation.GetTypeByMetadataName(IExportFullName); @@ -55,12 +65,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return null; // Find interfaces that derive from IExport (but are not IExport itself) - var exportInterfaces = typeSymbol.AllInterfaces - .Where(i => - !SymbolEqualityComparer.Default.Equals(i, iExportInterface) && - (i.AllInterfaces.Any(x => SymbolEqualityComparer.Default.Equals(x, iExportInterface)) || - i.AllInterfaces.Any(x => x.ToDisplayString() == IExportFullName) || - i.ToDisplayString() == IExportFullName)) + var exportInterfaces = typeSymbol + .AllInterfaces.Where(i => + !SymbolEqualityComparer.Default.Equals(i, iExportInterface) + && ( + i.AllInterfaces.Any(x => SymbolEqualityComparer.Default.Equals(x, iExportInterface)) + || i.AllInterfaces.Any(x => x.ToDisplayString() == IExportFullName) + || i.ToDisplayString() == IExportFullName + ) + ) .Select(i => i.ToDisplayString()) .Distinct() .ToList(); @@ -68,13 +81,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context) if (exportInterfaces.Count == 0) return null; - var constructor = typeSymbol.InstanceConstructors - .OrderByDescending(c => c.Parameters.Length) + var constructor = typeSymbol + .InstanceConstructors.OrderByDescending(c => c.Parameters.Length) .FirstOrDefault(); - var deps = constructor?.Parameters - .Select(p => new ConstructorDependency(p.Type.ToDisplayString())) - .ToList() ?? new(); + var deps = + constructor?.Parameters.Select(p => new ConstructorDependency(p.Type.ToDisplayString())).ToList() + ?? new(); return new ExportedType(typeSymbol.ToDisplayString(), exportInterfaces, deps); } @@ -83,24 +96,38 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray e?.FullTypeName == "IEXPORT_NOT_FOUND")) { - Report(spc, "XKC002", "IExport interface not found", - $"The required interface '{IExportFullName}' was not found in the compilation.", DiagnosticSeverity.Warning); + Report( + spc, + "XKC002", + "IExport interface not found", + $"The required interface '{IExportFullName}' was not found in the compilation.", + DiagnosticSeverity.Warning + ); return; } var validExports = exports.Where(e => e is not null).ToList(); if (validExports.Count == 0) { - Report(spc, "XKC003", "No valid exports found", + Report( + spc, + "XKC003", + "No valid exports found", "The ExportRegistrarGenerator found IExport but no concrete classes implementing it with service interfaces.", - DiagnosticSeverity.Info); + DiagnosticSeverity.Info + ); return; } @@ -125,8 +152,13 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray m.Message)); - Report(spc, "XKC005", "Scriban template parsing error", - $"The Scriban template has errors:\n{errors}", DiagnosticSeverity.Error); + Report( + spc, + "XKC005", + "Scriban template parsing error", + $"The Scriban template has errors:\n{errors}", + DiagnosticSeverity.Error + ); return; } @@ -142,18 +174,27 @@ private static string GetEmbeddedResource(string resourceName) var assembly = typeof(ExportRegistrarGenerator).Assembly; var fullName = $"AvaloniaXKCD.Generators.{resourceName}"; - using var stream = assembly.GetManifestResourceStream(fullName) + using var stream = + assembly.GetManifestResourceStream(fullName) ?? throw new FileNotFoundException( - $"Embedded resource '{fullName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}"); + $"Embedded resource '{fullName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}" + ); using var reader = new StreamReader(stream); return reader.ReadToEnd(); } - private static void Report(SourceProductionContext spc, string id, string title, string message, DiagnosticSeverity severity) + private static void Report( + SourceProductionContext spc, + string id, + string title, + string message, + DiagnosticSeverity severity + ) { - spc.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null)); + spc.ReportDiagnostic( + Diagnostic.Create(new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null) + ); } } } diff --git a/src/AvaloniaXKCD.Generators/IsExternalInit.cs b/src/AvaloniaXKCD.Generators/IsExternalInit.cs index b770df78..2f67a905 100644 --- a/src/AvaloniaXKCD.Generators/IsExternalInit.cs +++ b/src/AvaloniaXKCD.Generators/IsExternalInit.cs @@ -5,4 +5,4 @@ namespace System.Runtime.CompilerServices { internal static class IsExternalInit { } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Generators/Resources/ServiceAttribute.cs b/src/AvaloniaXKCD.Generators/Resources/ServiceAttribute.cs index 29d85004..4478ff9c 100644 --- a/src/AvaloniaXKCD.Generators/Resources/ServiceAttribute.cs +++ b/src/AvaloniaXKCD.Generators/Resources/ServiceAttribute.cs @@ -12,4 +12,4 @@ public ServiceAttribute(ServiceLifetime lifetime = ServiceLifetime.Transient) Lifetime = lifetime; } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Generators/Resources/ServiceLifetime.cs b/src/AvaloniaXKCD.Generators/Resources/ServiceLifetime.cs index 489b69fd..7a35c7c0 100644 --- a/src/AvaloniaXKCD.Generators/Resources/ServiceLifetime.cs +++ b/src/AvaloniaXKCD.Generators/Resources/ServiceLifetime.cs @@ -4,6 +4,6 @@ internal enum ServiceLifetime { Singleton, Scoped, - Transient + Transient, } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Generators/Resources/ServiceProviderAttribute.cs b/src/AvaloniaXKCD.Generators/Resources/ServiceProviderAttribute.cs index 35918683..7ea4b4bd 100644 --- a/src/AvaloniaXKCD.Generators/Resources/ServiceProviderAttribute.cs +++ b/src/AvaloniaXKCD.Generators/Resources/ServiceProviderAttribute.cs @@ -3,7 +3,5 @@ namespace AvaloniaXKCD.Generators { [AttributeUsage(AttributeTargets.Class, Inherited = false)] - internal sealed class ServiceProviderAttribute : Attribute - { - } -} \ No newline at end of file + internal sealed class ServiceProviderAttribute : Attribute { } +} diff --git a/src/AvaloniaXKCD.Generators/Resources/ViewLocatorAttribute.cs b/src/AvaloniaXKCD.Generators/Resources/ViewLocatorAttribute.cs index 1c0554f6..32cf509a 100644 --- a/src/AvaloniaXKCD.Generators/Resources/ViewLocatorAttribute.cs +++ b/src/AvaloniaXKCD.Generators/Resources/ViewLocatorAttribute.cs @@ -1,7 +1,5 @@ namespace AvaloniaXKCD.Generators { [System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - internal sealed class ViewLocatorAttribute : System.Attribute - { - } -} \ No newline at end of file + internal sealed class ViewLocatorAttribute : System.Attribute { } +} diff --git a/src/AvaloniaXKCD.Generators/ServiceProviderGenerator.cs b/src/AvaloniaXKCD.Generators/ServiceProviderGenerator.cs index 966b929e..d4e979e7 100644 --- a/src/AvaloniaXKCD.Generators/ServiceProviderGenerator.cs +++ b/src/AvaloniaXKCD.Generators/ServiceProviderGenerator.cs @@ -3,11 +3,11 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Scriban; -using System.Text; using Microsoft.CodeAnalysis.Text; +using Scriban; namespace AvaloniaXKCD.Generators { @@ -18,6 +18,7 @@ public class ServiceProviderGenerator : IIncrementalGenerator private const string ServiceProviderAttributeName = "AvaloniaXKCD.Generators.ServiceProviderAttribute"; public record ServiceInfo(string ImplementationType, string? ServiceType, string Lifetime); + public record TargetClassInfo(string Namespace, string ClassName); public void Initialize(IncrementalGeneratorInitializationContext context) @@ -38,18 +39,22 @@ public void Initialize(IncrementalGeneratorInitializationContext context) ctx.AddSource("ServiceAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); var serviceProviderAttributeSource = GetEmbeddedResource("Resources.ServiceProviderAttribute.cs"); - ctx.AddSource("ServiceProviderAttribute.g.cs", SourceText.From(serviceProviderAttributeSource, Encoding.UTF8)); + ctx.AddSource( + "ServiceProviderAttribute.g.cs", + SourceText.From(serviceProviderAttributeSource, Encoding.UTF8) + ); }); - var servicesProvider = context.SyntaxProvider - .CreateSyntaxProvider( + var servicesProvider = context + .SyntaxProvider.CreateSyntaxProvider( static (syntax, _) => syntax is ClassDeclarationSyntax { AttributeLists.Count: > 0 }, - static (ctx, _) => TransformService(ctx)) + static (ctx, _) => TransformService(ctx) + ) .Where(static model => model is not null) .Collect(); - var targetClassProvider = context.SyntaxProvider - .CreateSyntaxProvider( + var targetClassProvider = context + .SyntaxProvider.CreateSyntaxProvider( static (node, _) => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 }, static (ctx, _) => { @@ -59,34 +64,44 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return null; } - var hasAttribute = typeSymbol.GetAttributes() + var hasAttribute = typeSymbol + .GetAttributes() .Any(attr => attr.AttributeClass?.ToDisplayString() == ServiceProviderAttributeName); if (hasAttribute) { - return new TargetClassInfo(typeSymbol.ContainingNamespace.ToDisplayString(), typeSymbol.Name); + return new TargetClassInfo( + typeSymbol.ContainingNamespace.ToDisplayString(), + typeSymbol.Name + ); } return null; - }) + } + ) .Where(static model => model is not null); var combinedProvider = servicesProvider.Combine(targetClassProvider.Collect()); - context.RegisterSourceOutput(combinedProvider, (spc, source) => - GenerateSource(spc, source.Left, source.Right!)); + context.RegisterSourceOutput( + combinedProvider, + (spc, source) => GenerateSource(spc, source.Left, source.Right!) + ); } private static ServiceInfo? TransformService(GeneratorSyntaxContext ctx) { - if (ctx.Node is not ClassDeclarationSyntax classDecl || - ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol || - typeSymbol.IsAbstract) + if ( + ctx.Node is not ClassDeclarationSyntax classDecl + || ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol + || typeSymbol.IsAbstract + ) { return null; } - var serviceAttribute = typeSymbol.GetAttributes() + var serviceAttribute = typeSymbol + .GetAttributes() .FirstOrDefault(attr => attr.AttributeClass?.ToDisplayString() == ServiceAttributeName); if (serviceAttribute == null) @@ -106,13 +121,17 @@ public void Initialize(IncrementalGeneratorInitializationContext context) 0 => "Singleton", 1 => "Scoped", 2 => "Transient", - _ => "Transient" + _ => "Transient", }; return new ServiceInfo(typeSymbol.ToDisplayString(), null, lifetimeString); } - private static void GenerateSource(SourceProductionContext spc, ImmutableArray services, ImmutableArray targets) + private static void GenerateSource( + SourceProductionContext spc, + ImmutableArray services, + ImmutableArray targets + ) { if (targets.IsDefaultOrEmpty || targets.Length == 0) { @@ -122,9 +141,13 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray 1) { - Report(spc, "SPG001", "Multiple ServiceProvider classes", - $"Only one class can be decorated with the [ServiceProvider] attribute.", - DiagnosticSeverity.Error); + Report( + spc, + "SPG001", + "Multiple ServiceProvider classes", + $"Only one class can be decorated with the [ServiceProvider] attribute.", + DiagnosticSeverity.Error + ); return; } @@ -145,7 +168,13 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray m.Message)); - Report(spc, "SPG103", "Scriban template parsing error", $"The Scriban template has errors:\n{errors}", DiagnosticSeverity.Error); + Report( + spc, + "SPG103", + "Scriban template parsing error", + $"The Scriban template has errors:\n{errors}", + DiagnosticSeverity.Error + ); return; } @@ -153,7 +182,7 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray s is not null).ToList() + Services = services.Where(s => s is not null).ToList(), }; var result = template.Render(model, member => member.Name); @@ -174,10 +203,17 @@ private static string GetEmbeddedResource(string resourceName) return reader.ReadToEnd(); } - private static void Report(SourceProductionContext spc, string id, string title, string message, DiagnosticSeverity severity) + private static void Report( + SourceProductionContext spc, + string id, + string title, + string message, + DiagnosticSeverity severity + ) { - spc.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null)); + spc.ReportDiagnostic( + Diagnostic.Create(new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null) + ); } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Generators/ViewLocatorGenerator.cs b/src/AvaloniaXKCD.Generators/ViewLocatorGenerator.cs index bed78380..37f431b8 100644 --- a/src/AvaloniaXKCD.Generators/ViewLocatorGenerator.cs +++ b/src/AvaloniaXKCD.Generators/ViewLocatorGenerator.cs @@ -3,11 +3,11 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Scriban; -using System.Text; using Microsoft.CodeAnalysis.Text; +using Scriban; namespace AvaloniaXKCD.Generators { @@ -15,8 +15,11 @@ namespace AvaloniaXKCD.Generators public class ViewLocatorGenerator : IIncrementalGenerator { private const string AttributeName = "AvaloniaXKCD.Generators.ViewLocatorAttribute"; + public record DiscoveredType(string FullTypeName, string ClassName, string Suffix); + public record ViewModelViewPair(string ViewModel, string View); + public record TargetClassInfo(string Namespace, string ClassName); public void Initialize(IncrementalGeneratorInitializationContext context) @@ -34,14 +37,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context) ctx.AddSource("ViewLocatorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); }); - var typesProvider = context.SyntaxProvider - .CreateSyntaxProvider( + var typesProvider = context + .SyntaxProvider.CreateSyntaxProvider( static (syntax, _) => syntax is ClassDeclarationSyntax, - static (ctx, _) => TransformClass(ctx)) + static (ctx, _) => TransformClass(ctx) + ) .Where(static model => model is not null); - var targetClassProvider = context.SyntaxProvider - .CreateSyntaxProvider( + var targetClassProvider = context + .SyntaxProvider.CreateSyntaxProvider( static (node, _) => node is ClassDeclarationSyntax c && c.AttributeLists.Count > 0, static (ctx, _) => { @@ -51,29 +55,38 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return null; } - var hasAttribute = typeSymbol.GetAttributes() + var hasAttribute = typeSymbol + .GetAttributes() .Any(attr => attr.AttributeClass?.ToDisplayString() == AttributeName); if (hasAttribute) { - return new TargetClassInfo(typeSymbol.ContainingNamespace.ToDisplayString(), typeSymbol.Name); + return new TargetClassInfo( + typeSymbol.ContainingNamespace.ToDisplayString(), + typeSymbol.Name + ); } return null; - }) + } + ) .Where(static model => model is not null); var combinedProvider = typesProvider.Collect().Combine(targetClassProvider.Collect()); - context.RegisterSourceOutput(combinedProvider, (spc, source) => - GenerateSource(spc, source.Left, source.Right)); + context.RegisterSourceOutput( + combinedProvider, + (spc, source) => GenerateSource(spc, source.Left, source.Right) + ); } private static DiscoveredType? TransformClass(GeneratorSyntaxContext ctx) { - if (ctx.Node is not ClassDeclarationSyntax classDecl || - ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol || - typeSymbol.IsAbstract) + if ( + ctx.Node is not ClassDeclarationSyntax classDecl + || ctx.SemanticModel.GetDeclaredSymbol(classDecl) is not INamedTypeSymbol typeSymbol + || typeSymbol.IsAbstract + ) { return null; } @@ -94,7 +107,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return null; } - private static void GenerateSource(SourceProductionContext spc, ImmutableArray types, ImmutableArray targets) + private static void GenerateSource( + SourceProductionContext spc, + ImmutableArray types, + ImmutableArray targets + ) { if (targets.IsDefaultOrEmpty || targets.Length == 0) { @@ -104,9 +121,13 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray 1) { - Report(spc, "XKC001", "Multiple ViewLocator classes", - $"Only one class can be decorated with the [ViewLocator] attribute.", - DiagnosticSeverity.Error); + Report( + spc, + "XKC001", + "Multiple ViewLocator classes", + $"Only one class can be decorated with the [ViewLocator] attribute.", + DiagnosticSeverity.Error + ); return; } @@ -118,15 +139,15 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray t!.Suffix == "View") - .ToDictionary( - t => t!.ClassName.Substring(0, t.ClassName.Length - "View".Length), - t => t!.FullTypeName - ); + .ToDictionary(t => t!.ClassName.Substring(0, t.ClassName.Length - "View".Length), t => t!.FullTypeName); var pairs = new List(); foreach (var viewModel in viewModels) { - var viewModelBaseName = viewModel!.ClassName.Substring(0, viewModel.ClassName.Length - "ViewModel".Length); + var viewModelBaseName = viewModel!.ClassName.Substring( + 0, + viewModel.ClassName.Length - "ViewModel".Length + ); if (viewsByBaseName.TryGetValue(viewModelBaseName, out var matchedViewFullName)) { @@ -135,9 +156,13 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray m.Message)); - Report(spc, "XKC103", "Scriban template parsing error", $"The Scriban template has errors:\n{errors}", DiagnosticSeverity.Error); + Report( + spc, + "XKC103", + "Scriban template parsing error", + $"The Scriban template has errors:\n{errors}", + DiagnosticSeverity.Error + ); return; } @@ -164,7 +195,7 @@ private static void GenerateSource(SourceProductionContext spc, ImmutableArray member.Name); @@ -176,17 +207,27 @@ private static string GetEmbeddedResource(string resourceName) var assembly = typeof(ViewLocatorGenerator).Assembly; var fullName = $"AvaloniaXKCD.Generators.{resourceName}"; - using var stream = assembly.GetManifestResourceStream(fullName) - ?? throw new FileNotFoundException($"Embedded resource '{fullName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}"); + using var stream = + assembly.GetManifestResourceStream(fullName) + ?? throw new FileNotFoundException( + $"Embedded resource '{fullName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}" + ); using var reader = new StreamReader(stream); return reader.ReadToEnd(); } - private static void Report(SourceProductionContext spc, string id, string title, string message, DiagnosticSeverity severity) + private static void Report( + SourceProductionContext spc, + string id, + string title, + string message, + DiagnosticSeverity severity + ) { - spc.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null)); + spc.ReportDiagnostic( + Diagnostic.Create(new DiagnosticDescriptor(id, title, message, "Generator", severity, true), null) + ); } } -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Site/.prettierignore b/src/AvaloniaXKCD.Site/.prettierignore new file mode 100644 index 00000000..caaa7803 --- /dev/null +++ b/src/AvaloniaXKCD.Site/.prettierignore @@ -0,0 +1,10 @@ +node_modules +dist +out +build +.vite +xliff +bun.lock +package-lock.json +*.config.js +*.config.ts diff --git a/src/AvaloniaXKCD.Site/.prettierrc.json b/src/AvaloniaXKCD.Site/.prettierrc.json new file mode 100644 index 00000000..c0143348 --- /dev/null +++ b/src/AvaloniaXKCD.Site/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "useTabs": false, + "printWidth": 100, + "trailingComma": "es5", + "arrowParens": "always", + "endOfLine": "lf" +} diff --git a/src/AvaloniaXKCD.Site/README.md b/src/AvaloniaXKCD.Site/README.md index 75e23a30..3ee54166 100644 --- a/src/AvaloniaXKCD.Site/README.md +++ b/src/AvaloniaXKCD.Site/README.md @@ -4,23 +4,23 @@ Contains web frontend for AvaloniaXKCD. Hosts WASM application and provides Type ## Project provides -- **WASM Hosting:** Hosts `AvaloniaXKCD.Browser` WASM app and provides infrastructure. -- **TypeScript Integration:** Contains TypeScript code integrating with C# WASM app for communication. -- **Asset Management:** Manages web assets (HTML, CSS, JS). +- **WASM Hosting:** Hosts `AvaloniaXKCD.Browser` WASM app and provides infrastructure. +- **TypeScript Integration:** Contains TypeScript code integrating with C# WASM app for communication. +- **Asset Management:** Manages web assets (HTML, CSS, JS). ## TypeScript layer responsibilities -- Initializes WASM app and provides configuration. -- Integrates WASM app with DOM for UI rendering. -- Handles browser events, forwards to WASM app. +- Initializes WASM app and provides configuration. +- Integrates WASM app with DOM for UI rendering. +- Handles browser events, forwards to WASM app. ## Development ### Prerequisites -- Bun -- TypeScript -- .NET SDK +- Bun +- TypeScript +- .NET SDK ### Local Development @@ -40,11 +40,11 @@ make publish-browser ## Integration -- Handles TypeScript/web logic. -- `AvaloniaXKCD.Browser`: C# WASM code. -- Components work together for web experience. +- Handles TypeScript/web logic. +- `AvaloniaXKCD.Browser`: C# WASM code. +- Components work together for web experience. ## Resources - [Project Architecture](../README.md) -- [Browser Component](../AvaloniaXKCD.Browser/README.md) \ No newline at end of file +- [Browser Component](../AvaloniaXKCD.Browser/README.md) diff --git a/src/AvaloniaXKCD.Site/bun.lock b/src/AvaloniaXKCD.Site/bun.lock index 15ba4a17..2cb0d34c 100644 --- a/src/AvaloniaXKCD.Site/bun.lock +++ b/src/AvaloniaXKCD.Site/bun.lock @@ -9,17 +9,22 @@ "lit": "^3.3.1", }, "devDependencies": { + "@eslint/js": "^9.18.0", "@lit/localize-tools": "^0.8.0", + "@types/eslint__js": "^8.42.3", "@types/fs-extra": "^11.0.4", "@types/glob": "^9.0.0", "@types/html-minifier-terser": "^7.0.2", "@types/node": "^24.10.0", "@vite-pwa/assets-generator": "^1.0.2", + "eslint": "^9.18.0", "fs-extra": "^11.3.2", "glob": "^11.0.3", "html-minifier-terser": "^7.2.0", + "prettier": "^3.4.2", "rollup-plugin-minify-template-literals": "^1.1.7", "typescript": "~5.9.3", + "typescript-eslint": "^8.19.1", "vite": "npm:rolldown-vite@7.1.14", "vite-plugin-pwa": "^1.1.0", "vite-plugin-singlefile": "^2.3.0", @@ -220,6 +225,32 @@ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="], + + "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="], + + "@eslint/js": ["@eslint/js@9.39.1", "", {}, "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="], + + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], + + "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], @@ -388,6 +419,10 @@ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="], + + "@types/eslint__js": ["@types/eslint__js@8.42.3", "", { "dependencies": { "@types/eslint": "*" } }, "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/fs-extra": ["@types/fs-extra@11.0.4", "", { "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ=="], @@ -396,6 +431,8 @@ "@types/html-minifier-terser": ["@types/html-minifier-terser@7.0.2", "", {}, "sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="], "@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], @@ -404,20 +441,44 @@ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.4", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/type-utils": "8.46.4", "@typescript-eslint/utils": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.4", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.4", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.4", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.4", "@typescript-eslint/types": "^8.46.4", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4" } }, "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA=="], + + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.4", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/utils": "8.46.4", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@8.46.4", "", {}, "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.4", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.4", "@typescript-eslint/tsconfig-utils": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "eslint-visitor-keys": "^4.2.1" } }, "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw=="], + "@vite-pwa/assets-generator": ["@vite-pwa/assets-generator@1.0.2", "", { "dependencies": { "cac": "^6.7.14", "colorette": "^2.0.20", "consola": "^3.4.2", "sharp": "^0.33.5", "sharp-ico": "^0.1.5", "unconfig": "^7.3.1" }, "bin": { "pwa-assets-generator": "bin/pwa-assets-generator.mjs" } }, "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg=="], "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], - "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], @@ -456,10 +517,14 @@ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + "camel-case": ["camel-case@4.1.2", "", { "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw=="], "caniuse-lite": ["caniuse-lite@1.0.30001753", "", {}, "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw=="], + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "clean-css": ["clean-css@5.3.3", "", { "dependencies": { "source-map": "~0.6.0" } }, "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg=="], "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], @@ -500,6 +565,8 @@ "decode-ico": ["decode-ico@0.4.1", "", { "dependencies": { "@canvas/image-data": "^1.0.0", "decode-bmp": "^0.2.0", "to-data-view": "^1.1.0" } }, "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA=="], + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], @@ -538,6 +605,22 @@ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@9.39.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.1", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g=="], + + "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + + "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + + "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], + + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], @@ -548,16 +631,26 @@ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], @@ -588,7 +681,9 @@ "glob": ["glob@11.0.3", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA=="], - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], @@ -596,8 +691,12 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], + "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], "has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="], @@ -614,6 +713,12 @@ "idb": ["idb@7.1.1", "", {}, "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="], + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], @@ -694,11 +799,17 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + "json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="], - "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], @@ -708,8 +819,12 @@ "jsonschema": ["jsonschema@1.5.0", "", {}, "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw=="], + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], @@ -740,10 +855,14 @@ "lit-html": ["lit-html@3.3.1", "", { "dependencies": { "@types/trusted-types": "^2.0.2" } }, "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + "lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="], "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], @@ -760,7 +879,7 @@ "minify-literals": ["minify-literals@1.0.10", "", { "dependencies": { "clean-css": "^5.3.3", "html-minifier-terser": "^7.2.0", "magic-string": "^0.30.7", "parse-literals": "^1.2.1" } }, "sha512-3gzrwHTd7kRTqsoGhGw4iySDy7JGgc3RozKZ7IT9vcXPyno5egKkpFqud+F1ECSPxi/ls2JwQCUYZr5SeUci0Q=="], - "minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], + "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], @@ -770,6 +889,8 @@ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + "no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="], "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], @@ -782,18 +903,28 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], "param-case": ["param-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parse-literals": ["parse-literals@1.2.1", "", { "dependencies": { "typescript": "^2.9.2 || ^3.0.0 || ^4.0.0" } }, "sha512-Ml0w104Ph2wwzuRdxrg9booVWsngXbB4bZ5T2z6WyF8b5oaNkUmBiDtahi34yUIpXD8Y13JjAK6UyIyApJ73RQ=="], "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], "pascal-case": ["pascal-case@3.1.2", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g=="], + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], @@ -810,6 +941,10 @@ "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + + "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], + "pretty-bytes": ["pretty-bytes@6.1.1", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -840,6 +975,8 @@ "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], "rolldown": ["rolldown@1.0.0-beta.41", "", { "dependencies": { "@oxc-project/types": "=0.93.0", "@rolldown/pluginutils": "1.0.0-beta.41", "ansis": "=4.2.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-beta.41", "@rolldown/binding-darwin-arm64": "1.0.0-beta.41", "@rolldown/binding-darwin-x64": "1.0.0-beta.41", "@rolldown/binding-freebsd-x64": "1.0.0-beta.41", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.41", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.41", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.41", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.41", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.41", "@rolldown/binding-openharmony-arm64": "1.0.0-beta.41", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.41", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.41", "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.41", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.41" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg=="], @@ -920,6 +1057,10 @@ "strip-comments": ["strip-comments@2.0.1", "", {}, "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw=="], + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], "temp-dir": ["temp-dir@2.0.0", "", {}, "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg=="], @@ -936,8 +1077,12 @@ "tr46": ["tr46@1.0.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="], + "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + "type-fest": ["type-fest@0.16.0", "", {}, "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg=="], "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], @@ -950,6 +1095,8 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "typescript-eslint": ["typescript-eslint@8.46.4", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.4", "@typescript-eslint/parser": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/utils": "8.46.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg=="], + "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], "unconfig": ["unconfig@7.3.3", "", { "dependencies": { "@quansync/fs": "^0.1.5", "defu": "^6.1.4", "jiti": "^2.5.1", "quansync": "^0.2.11" } }, "sha512-QCkQoOnJF8L107gxfHL0uavn7WD9b3dpBcFX6HtfQYmjw2YzWxGuFQ0N0J6tE9oguCBJn9KOvfqYDCMPHIZrBA=="], @@ -972,6 +1119,8 @@ "update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="], + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "vite": ["rolldown-vite@7.1.14", "", { "dependencies": { "@oxc-project/runtime": "0.92.0", "fdir": "^6.5.0", "lightningcss": "^1.30.1", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-beta.41", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "esbuild": "^0.25.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-eSiiRJmovt8qDJkGyZuLnbxAOAdie6NCmmd0NkTC0RJI9duiSBTfr8X2mBYJOUFzxQa2USaHmL99J9uMxkjCyw=="], "vite-plugin-pwa": ["vite-plugin-pwa@1.1.0", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-VsSpdubPzXhHWVINcSx6uHRMpOHVHQcHsef1QgkOlEoaIDAlssFEW88LBq1a59BuokAhsh2kUDJbaX1bZv4Bjw=="], @@ -992,6 +1141,8 @@ "which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="], + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + "workbox-background-sync": ["workbox-background-sync@7.3.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" } }, "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg=="], "workbox-broadcast-update": ["workbox-broadcast-update@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA=="], @@ -1032,6 +1183,10 @@ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "@apideck/better-ajv-errors/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], @@ -1044,6 +1199,8 @@ "@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "@lit/localize-tools/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], "@lit/localize-tools/typescript": ["typescript@5.5.4", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q=="], @@ -1064,10 +1221,18 @@ "@types/jsonfile/@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "parse-literals/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="], @@ -1082,6 +1247,8 @@ "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "workbox-build/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "workbox-build/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], "workbox-build/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], @@ -1092,12 +1259,14 @@ "workbox-build/source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="], - "wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "@apideck/better-ajv-errors/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "@rollup/plugin-babel/@rollup/pluginutils/@types/estree": ["@types/estree@0.0.39", "", {}, "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="], "@rollup/plugin-babel/@rollup/pluginutils/estree-walker": ["estree-walker@1.0.1", "", {}, "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="], @@ -1110,11 +1279,13 @@ "@rollup/plugin-replace/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "workbox-build/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + "workbox-build/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], diff --git a/src/AvaloniaXKCD.Site/eslint.config.js b/src/AvaloniaXKCD.Site/eslint.config.js new file mode 100644 index 00000000..6f78e8e1 --- /dev/null +++ b/src/AvaloniaXKCD.Site/eslint.config.js @@ -0,0 +1,57 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + languageOptions: { + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/out/**', + '**/build/**', + '**/.vite/**', + '**/xliff/**', + 'src/localization/locales/**', + 'vite.config.ts', + 'pwa-assets.config.ts', + '**/types/dotnet.d.ts', + 'plugins/**', + 'scripts/**', + 'eslint.config.js', + ], + }, + { + rules: { + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/unbound-method': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + }, + } +); diff --git a/src/AvaloniaXKCD.Site/index.html b/src/AvaloniaXKCD.Site/index.html index 74b3b33e..699c37d0 100644 --- a/src/AvaloniaXKCD.Site/index.html +++ b/src/AvaloniaXKCD.Site/index.html @@ -1,63 +1,132 @@ - + + + A(valonia)XKCD + + + + + + - - A(valonia)XKCD - - - - - - - - -
-

A(valonia)XKCD

-

Because laughing in C# is still (technically) laughing.

- -
-
- -
- + +
+

A(valonia)XKCD

+

Because laughing in C# is still (technically) laughing.

+ - -
-
-

- Made with an amalgamation of technologies that probably shouldn't work together, but somehow does: -

-
- - - - -
-

- - Comics © xkcd.com (CC-BY-NC) • - Explanations © explainxkcd.com - (CC-BY-SA)
- XKCD Font © ipython - (CC-BY-NC) • Website © dylanlangston.com (MIT) -
-

-
- - - + +
+ +
+ +
+
+
+
+

+ Made with an amalgamation of technologies that probably shouldn't work together, but somehow + does: +

+
+ + + + +
+

+ + Comics © + xkcd.com + (CC-BY-NC) • Explanations © + explainxkcd.com + (CC-BY-SA)
+ XKCD Font © + ipython + (CC-BY-NC) • Website © + dylanlangston.com + (MIT) +
+

+
- \ No newline at end of file + + + diff --git a/src/AvaloniaXKCD.Site/package-lock.json b/src/AvaloniaXKCD.Site/package-lock.json index 23fdca21..1648b01f 100644 --- a/src/AvaloniaXKCD.Site/package-lock.json +++ b/src/AvaloniaXKCD.Site/package-lock.json @@ -1,28 +1,33 @@ { "name": "avaloniaxkcd-site", - "version": "1.0.0+0", + "version": "1.0.7+10205", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "avaloniaxkcd-site", - "version": "1.0.0+0", + "version": "1.0.7+10205", "dependencies": { "@lit/localize": "^0.12.2", "lit": "^3.3.1" }, "devDependencies": { + "@eslint/js": "^9.18.0", "@lit/localize-tools": "^0.8.0", + "@types/eslint__js": "^8.42.3", "@types/fs-extra": "^11.0.4", "@types/glob": "^9.0.0", "@types/html-minifier-terser": "^7.0.2", "@types/node": "^24.10.0", "@vite-pwa/assets-generator": "^1.0.2", + "eslint": "^9.18.0", "fs-extra": "^11.3.2", "glob": "^11.0.3", "html-minifier-terser": "^7.2.0", + "prettier": "^3.4.2", "rollup-plugin-minify-template-literals": "^1.1.7", "typescript": "~5.9.3", + "typescript-eslint": "^8.19.1", "vite": "npm:rolldown-vite@7.1.14", "vite-plugin-pwa": "^1.1.0", "vite-plugin-singlefile": "^2.3.0" @@ -1671,6 +1676,274 @@ "tslib": "^2.4.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", @@ -3003,6 +3276,27 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -3039,6 +3333,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/jsonfile": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", @@ -3072,6 +3373,254 @@ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz", + "integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/type-utils": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.4", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz", + "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz", + "integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", + "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vite-pwa/assets-generator": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz", @@ -3119,6 +3668,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", @@ -3172,6 +3731,13 @@ "node": ">=14" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3447,6 +4013,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -3479,6 +4055,39 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -3728,6 +4337,13 @@ "node": ">=8.6" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -4013,6 +4629,224 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -4061,6 +4895,13 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", @@ -4100,10 +4941,23 @@ "peerDependencies": { "picomatch": "^3 || ^4" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/filelist": { @@ -4142,6 +4996,44 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -4374,6 +5266,19 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -4411,6 +5316,13 @@ "dev": true, "license": "ISC" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -4424,6 +5336,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -4531,6 +5453,43 @@ "dev": true, "license": "ISC" }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5079,6 +6038,19 @@ "dev": true, "license": "MIT" }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -5092,6 +6064,13 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -5106,6 +6085,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -5152,6 +6138,16 @@ "node": "*" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -5162,6 +6158,20 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lightningcss": { "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", @@ -5454,6 +6464,22 @@ "@types/trusted-types": "^2.0.2" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -5468,6 +6494,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -5630,6 +6663,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -5702,6 +6742,24 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -5720,6 +6778,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -5738,6 +6828,19 @@ "tslib": "^2.0.3" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parse-literals": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/parse-literals/-/parse-literals-1.2.1.tgz", @@ -5799,6 +6902,16 @@ "tslib": "^2.0.3" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -5902,6 +7015,32 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", @@ -6116,6 +7255,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -6840,6 +7989,32 @@ "node": ">=10" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -6955,6 +8130,19 @@ "punycode": "^2.1.0" } }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -6962,6 +8150,19 @@ "dev": true, "license": "0BSD" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", @@ -7067,6 +8268,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.4.tgz", + "integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.4", + "@typescript-eslint/parser": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/utils": "8.46.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -7233,6 +8458,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/vite": { "name": "rolldown-vite", "version": "7.1.14", @@ -7482,6 +8717,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workbox-background-sync": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz", @@ -7998,6 +9243,19 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/src/AvaloniaXKCD.Site/package.json b/src/AvaloniaXKCD.Site/package.json index bf60b82f..aff48e2e 100644 --- a/src/AvaloniaXKCD.Site/package.json +++ b/src/AvaloniaXKCD.Site/package.json @@ -1,7 +1,7 @@ { "name": "avaloniaxkcd-site", "private": true, - "version": "1.0.0+0", + "version": "1.0.8+32270", "type": "module", "scripts": { "generate-pwa-assets": "pwa-assets-generator", @@ -10,20 +10,29 @@ "dev": "tsc && vite build --watch", "lit-localize": "lit-localize", "lit-localize:extract": "lit-localize extract", - "lit-localize:build": "lit-localize build" + "lit-localize:build": "lit-localize build", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write .", + "format:check": "prettier --check ." }, "devDependencies": { + "@eslint/js": "^9.18.0", "@lit/localize-tools": "^0.8.0", + "@types/eslint__js": "^8.42.3", "@types/fs-extra": "^11.0.4", "@types/glob": "^9.0.0", "@types/html-minifier-terser": "^7.0.2", "@types/node": "^24.10.0", "@vite-pwa/assets-generator": "^1.0.2", + "eslint": "^9.18.0", "fs-extra": "^11.3.2", "glob": "^11.0.3", "html-minifier-terser": "^7.2.0", + "prettier": "^3.4.2", "rollup-plugin-minify-template-literals": "^1.1.7", "typescript": "~5.9.3", + "typescript-eslint": "^8.19.1", "vite": "npm:rolldown-vite@7.1.14", "vite-plugin-pwa": "^1.1.0", "vite-plugin-singlefile": "^2.3.0" diff --git a/src/AvaloniaXKCD.Site/plugins/AutoImportComponents.ts b/src/AvaloniaXKCD.Site/plugins/AutoImportComponents.ts index 66f18b53..7a24cbab 100644 --- a/src/AvaloniaXKCD.Site/plugins/AutoImportComponents.ts +++ b/src/AvaloniaXKCD.Site/plugins/AutoImportComponents.ts @@ -1,27 +1,25 @@ -import path from 'node:path' -import { glob } from 'glob' -import type { Plugin } from 'vite' +import path from 'node:path'; +import { glob } from 'glob'; +import type { Plugin } from 'vite'; interface Component { - name: string; - path: string; + name: string; + path: string; } export function autoImportComponents(): Plugin { - const components: Component[] = glob.sync('src/components/**/*.ts').map((file: string) => ({ - name: path.basename(file, '.ts'), - path: `/${file}` - })); + const components: Component[] = glob.sync('src/components/**/*.ts').map((file: string) => ({ + name: path.basename(file, '.ts'), + path: `/${file}`, + })); - return { - name: 'auto-import-components', - transform(code, id) { - if (id.endsWith('main.ts')) { - const imports = components - .map(component => `import '${component.path}';`) - .join('\n'); - return `${imports}\n${code}`; - } - } - } -} \ No newline at end of file + return { + name: 'auto-import-components', + transform(code, id) { + if (id.endsWith('main.ts')) { + const imports = components.map((component) => `import '${component.path}';`).join('\n'); + return `${imports}\n${code}`; + } + }, + }; +} diff --git a/src/AvaloniaXKCD.Site/plugins/CopyIndexTo404AndMinify.ts b/src/AvaloniaXKCD.Site/plugins/CopyIndexTo404AndMinify.ts index 54057315..58cb4c14 100644 --- a/src/AvaloniaXKCD.Site/plugins/CopyIndexTo404AndMinify.ts +++ b/src/AvaloniaXKCD.Site/plugins/CopyIndexTo404AndMinify.ts @@ -1,7 +1,7 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; -import { Plugin } from "vite"; -import { minify } from "html-minifier-terser"; +import { readFile, writeFile } from 'fs/promises'; +import { resolve } from 'path'; +import { Plugin } from 'vite'; +import { minify } from 'html-minifier-terser'; export function copyIndexTo404AndMinify(): Plugin { return { @@ -10,7 +10,9 @@ export function copyIndexTo404AndMinify(): Plugin { async writeBundle(options) { const outDir = options.dir; if (!outDir) { - console.warn('Could not determine output directory. Skipping 404.html copy and minification.'); + console.warn( + 'Could not determine output directory. Skipping 404.html copy and minification.' + ); return; } @@ -34,10 +36,9 @@ export function copyIndexTo404AndMinify(): Plugin { await writeFile(indexPath, minifiedHtml, 'utf-8'); await writeFile(fourOhFourPath, minifiedHtml, 'utf-8'); - } catch (error) { console.error(`Could not copy and minify index.html to 404.html: ${error}`); } - } + }, }; -} \ No newline at end of file +} diff --git a/src/AvaloniaXKCD.Site/plugins/InjectLatestComic.ts b/src/AvaloniaXKCD.Site/plugins/InjectLatestComic.ts index f157afd5..71f9ed62 100644 --- a/src/AvaloniaXKCD.Site/plugins/InjectLatestComic.ts +++ b/src/AvaloniaXKCD.Site/plugins/InjectLatestComic.ts @@ -3,25 +3,25 @@ import fs from 'node:fs/promises'; import path from 'node:path'; export function injectLatestComic(): Plugin { - return { - name: 'inject-latest-comic', - transformIndexHtml: async (html) => { - try { - const infoPath = path.resolve(__dirname, '../../../mirror/info.0.json'); - const infoContent = await fs.readFile(infoPath, 'utf-8'); - const comicInfo = JSON.parse(infoContent); - - // Get the image path without the extension to construct 2x path - const imgPathWithoutExt = comicInfo.img.replace(/\.[^/.]+$/, ''); - const comicImgPath = `https://dylanlangston.github.io/Axkcd/mirror/${comicInfo.img}`; - const comic2xImgPath = `https://dylanlangston.github.io/Axkcd/mirror/${imgPathWithoutExt}_2x.png`; - const wittyMessage = `It appears you've disabled JavaScript, likely because you're wary of running arbitrary code from a stranger's server. This suggests a healthy level of paranoia, which, coincidentally, is a prerequisite for appreciating the subtle humor in debugging logs and the existential dread of a poorly timed git push. You'll fit right in here. + return { + name: 'inject-latest-comic', + transformIndexHtml: async (html) => { + try { + const infoPath = path.resolve(__dirname, '../../../mirror/info.0.json'); + const infoContent = await fs.readFile(infoPath, 'utf-8'); + const comicInfo = JSON.parse(infoContent); + + // Get the image path without the extension to construct 2x path + const imgPathWithoutExt = comicInfo.img.replace(/\.[^/.]+$/, ''); + const comicImgPath = `https://dylanlangston.github.io/Axkcd/mirror/${comicInfo.img}`; + const comic2xImgPath = `https://dylanlangston.github.io/Axkcd/mirror/${imgPathWithoutExt}_2x.png`; + const wittyMessage = `It appears you've disabled JavaScript, likely because you're wary of running arbitrary code from a stranger's server. This suggests a healthy level of paranoia, which, coincidentally, is a prerequisite for appreciating the subtle humor in debugging logs and the existential dread of a poorly timed git push. You'll fit right in here. However, this site, in its ongoing battle against the forces of static HTML, relies on the very scripting you've forsaken. To unlock the full experience—and to prevent the stick figures from unionizing over unfair rendering conditions—you'll need to re-enable it. (Don't worry, we promise our code is only mostly sentient.)`; - const noscriptContent = `
+ const noscriptContent = `

${wittyMessage}


Here's comic #${comicInfo.num}: "${comicInfo.title}"

@@ -35,31 +35,27 @@ However, this site, in its ongoing battle against the forces of static HTML, rel
`; - const comicUrl = `/${comicInfo.num}`; + const comicUrl = `/${comicInfo.num}`; - const openGraphTags = ` + const openGraphTags = ` `; - let updatedHtml = html.replace( - /