diff --git a/Auth/AuthServices/AuthServices.csproj b/Auth/AuthServices/AuthServices.csproj
index 17dac02d..1c8fb5f6 100644
--- a/Auth/AuthServices/AuthServices.csproj
+++ b/Auth/AuthServices/AuthServices.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/Auth/MauiAuth/MauiAuth.csproj b/Auth/MauiAuth/MauiAuth.csproj
index 3ce1bc7b..0618a01b 100644
--- a/Auth/MauiAuth/MauiAuth.csproj
+++ b/Auth/MauiAuth/MauiAuth.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/Auth/MauiAuthBlazor/MauiAuthBlazor.csproj b/Auth/MauiAuthBlazor/MauiAuthBlazor.csproj
index d05c969a..db3e97bb 100644
--- a/Auth/MauiAuthBlazor/MauiAuthBlazor.csproj
+++ b/Auth/MauiAuthBlazor/MauiAuthBlazor.csproj
@@ -26,7 +26,7 @@
-
+
diff --git a/Database/MauiTaskListApp/MauiTaskListApp.csproj b/Database/MauiTaskListApp/MauiTaskListApp.csproj
index b1fbf980..fde3e343 100644
--- a/Database/MauiTaskListApp/MauiTaskListApp.csproj
+++ b/Database/MauiTaskListApp/MauiTaskListApp.csproj
@@ -30,7 +30,7 @@
-
+
diff --git a/DynamicFab/DynamicFab.csproj b/DynamicFab/DynamicFab.csproj
index 7b5de69d..aaf63c81 100644
--- a/DynamicFab/DynamicFab.csproj
+++ b/DynamicFab/DynamicFab.csproj
@@ -26,7 +26,7 @@
-
+
diff --git a/IPTVPlayer/IPTVPlayer.csproj b/IPTVPlayer/IPTVPlayer.csproj
index 2bf33724..6f90c74b 100644
--- a/IPTVPlayer/IPTVPlayer.csproj
+++ b/IPTVPlayer/IPTVPlayer.csproj
@@ -32,8 +32,8 @@
-
-
+
+
diff --git a/KanbanBoard/KanbanBoard.csproj b/KanbanBoard/KanbanBoard.csproj
index 8b5bf920..6569fcbc 100644
--- a/KanbanBoard/KanbanBoard.csproj
+++ b/KanbanBoard/KanbanBoard.csproj
@@ -27,7 +27,7 @@
-
+
all
diff --git a/MauiAnimation/MauiAnimation.csproj b/MauiAnimation/MauiAnimation.csproj
index e91c78bb..bf4a8e35 100644
--- a/MauiAnimation/MauiAnimation.csproj
+++ b/MauiAnimation/MauiAnimation.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/MauiBank/MauiBank.csproj b/MauiBank/MauiBank.csproj
index a08d17f9..965755ea 100644
--- a/MauiBank/MauiBank.csproj
+++ b/MauiBank/MauiBank.csproj
@@ -32,7 +32,7 @@
-
+
diff --git a/MauiBells/MauiBells.csproj b/MauiBells/MauiBells.csproj
index e4e7a78b..08308189 100644
--- a/MauiBells/MauiBells.csproj
+++ b/MauiBells/MauiBells.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/MauiBluetooth/MauiBluetooth.csproj b/MauiBluetooth/MauiBluetooth.csproj
index 0c4fe906..6338dbc1 100644
--- a/MauiBluetooth/MauiBluetooth.csproj
+++ b/MauiBluetooth/MauiBluetooth.csproj
@@ -26,9 +26,9 @@
-
+
-
+
diff --git a/MauiCaptcha/MauiCaptcha.csproj b/MauiCaptcha/MauiCaptcha.csproj
index 6c82c667..139c14d7 100644
--- a/MauiCaptcha/MauiCaptcha.csproj
+++ b/MauiCaptcha/MauiCaptcha.csproj
@@ -32,7 +32,7 @@
-
+
diff --git a/MauiLocalization/MauiLocalization.csproj b/MauiLocalization/MauiLocalization.csproj
index b288e5f3..5111658f 100644
--- a/MauiLocalization/MauiLocalization.csproj
+++ b/MauiLocalization/MauiLocalization.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/MauiMaps/MauiMaps.csproj b/MauiMaps/MauiMaps.csproj
index a05b31e6..29b0ccec 100644
--- a/MauiMaps/MauiMaps.csproj
+++ b/MauiMaps/MauiMaps.csproj
@@ -29,9 +29,9 @@
-
+
-
+
diff --git a/MauiMultiWindow/MauiMultiWindow.csproj b/MauiMultiWindow/MauiMultiWindow.csproj
index 99871bcb..47d21918 100644
--- a/MauiMultiWindow/MauiMultiWindow.csproj
+++ b/MauiMultiWindow/MauiMultiWindow.csproj
@@ -25,6 +25,6 @@
-
+
\ No newline at end of file
diff --git a/MauiNotifications/App.xaml b/MauiNotifications/App.xaml
new file mode 100644
index 00000000..30f427dc
--- /dev/null
+++ b/MauiNotifications/App.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MauiNotifications/App.xaml.cs b/MauiNotifications/App.xaml.cs
new file mode 100644
index 00000000..e3fe7a35
--- /dev/null
+++ b/MauiNotifications/App.xaml.cs
@@ -0,0 +1,20 @@
+namespace MauiNotifications;
+
+public partial class App
+{
+ private readonly DeviceInstallationService deviceInstallationService;
+
+ public App(DeviceInstallationService deviceInstallationService)
+ {
+ this.deviceInstallationService = deviceInstallationService;
+ InitializeComponent();
+
+ MainPage = new AppShell();
+ }
+
+ protected override async void OnStart()
+ {
+ base.OnStart();
+ await deviceInstallationService.RegisterDevice();
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/AppShell.xaml b/MauiNotifications/AppShell.xaml
new file mode 100644
index 00000000..b07f536d
--- /dev/null
+++ b/MauiNotifications/AppShell.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/MauiNotifications/AppShell.xaml.cs b/MauiNotifications/AppShell.xaml.cs
new file mode 100644
index 00000000..4481b486
--- /dev/null
+++ b/MauiNotifications/AppShell.xaml.cs
@@ -0,0 +1,9 @@
+namespace MauiNotifications;
+
+public partial class AppShell : Shell
+{
+ public AppShell()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/DeviceInstallationService.cs b/MauiNotifications/DeviceInstallationService.cs
new file mode 100644
index 00000000..57eef5cd
--- /dev/null
+++ b/MauiNotifications/DeviceInstallationService.cs
@@ -0,0 +1,22 @@
+namespace MauiNotifications;
+
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService(IConnectivity connectivity, INotificationHubClient notificationHubClient)
+{
+ public async Task RegisterDevice()
+ {
+ if (connectivity.NetworkAccess != NetworkAccess.Internet)
+ {
+ return;
+ }
+
+ var installation = await GetInstallation();
+ if (installation == null)
+ {
+ return;
+ }
+
+ await notificationHubClient.CreateOrUpdateInstallationAsync(installation);
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/MainPage.xaml b/MauiNotifications/MainPage.xaml
new file mode 100644
index 00000000..a7535c0a
--- /dev/null
+++ b/MauiNotifications/MainPage.xaml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MauiNotifications/MainPage.xaml.cs b/MauiNotifications/MainPage.xaml.cs
new file mode 100644
index 00000000..13545017
--- /dev/null
+++ b/MauiNotifications/MainPage.xaml.cs
@@ -0,0 +1,23 @@
+namespace MauiNotifications;
+
+public partial class MainPage : ContentPage
+{
+ int count = 0;
+
+ public MainPage()
+ {
+ InitializeComponent();
+ }
+
+ private void OnCounterClicked(object sender, EventArgs e)
+ {
+ count++;
+
+ if (count == 1)
+ CounterBtn.Text = $"Clicked {count} time";
+ else
+ CounterBtn.Text = $"Clicked {count} times";
+
+ SemanticScreenReader.Announce(CounterBtn.Text);
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/MauiNotifications.csproj b/MauiNotifications/MauiNotifications.csproj
new file mode 100644
index 00000000..09363ee6
--- /dev/null
+++ b/MauiNotifications/MauiNotifications.csproj
@@ -0,0 +1,45 @@
+
+
+
+ Exe
+ MauiNotifications
+
+
+ MauiNotifications
+
+
+ com.vladislavantonyuk.mauinotifications
+
+
+ 1.0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MauiNotifications/MauiProgram.cs b/MauiNotifications/MauiProgram.cs
new file mode 100644
index 00000000..83a31b72
--- /dev/null
+++ b/MauiNotifications/MauiProgram.cs
@@ -0,0 +1,24 @@
+namespace MauiNotifications;
+
+using CommunityToolkit.Maui;
+using Microsoft.Azure.NotificationHubs;
+using Microsoft.Extensions.Logging;
+
+public static class MauiProgram
+{
+ public static MauiApp CreateMauiApp()
+ {
+ var builder = MauiApp.CreateBuilder();
+ builder.UseMauiApp()
+ .UseMauiCommunityToolkit();
+
+ builder.Services.AddSingleton(Connectivity.Current);
+
+ builder.Services.AddSingleton();
+
+ builder.Services.AddSingleton(
+ _ => NotificationHubClient.CreateClientFromConnectionString("YOUR CONNECTION STRING", "MauiNotifications", true));
+
+ return builder.Build();
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/AndroidManifest.xml b/MauiNotifications/Platforms/Android/AndroidManifest.xml
new file mode 100644
index 00000000..ce4886fe
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/MainActivity.cs b/MauiNotifications/Platforms/Android/MainActivity.cs
new file mode 100644
index 00000000..3463a263
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/MainActivity.cs
@@ -0,0 +1,9 @@
+namespace MauiNotifications;
+
+using Android.App;
+using Android.Content.PM;
+
+[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
+public class MainActivity : MauiAppCompatActivity
+{
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/MainApplication.cs b/MauiNotifications/Platforms/Android/MainApplication.cs
new file mode 100644
index 00000000..50726382
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/MainApplication.cs
@@ -0,0 +1,15 @@
+namespace MauiNotifications;
+
+using Android.App;
+using Android.Runtime;
+
+[Application]
+public class MainApplication : MauiApplication
+{
+ public MainApplication(IntPtr handle, JniHandleOwnership ownership)
+ : base(handle, ownership)
+ {
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/Notifications/DeviceInstallationService.cs b/MauiNotifications/Platforms/Android/Notifications/DeviceInstallationService.cs
new file mode 100644
index 00000000..0877465a
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/Notifications/DeviceInstallationService.cs
@@ -0,0 +1,41 @@
+namespace MauiNotifications;
+
+using System.Diagnostics;
+using Android.Gms.Common;
+using Android.Gms.Extensions;
+using Android.Provider;
+using Firebase.Messaging;
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService
+{
+ private static bool NotificationsSupported
+ => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Platform.AppContext) == ConnectionResult.Success;
+
+ public static string? GetDeviceId()
+ => Settings.Secure.GetString(Platform.AppContext.ContentResolver, Settings.Secure.AndroidId);
+
+ private static async Task GetInstallation()
+ {
+ if (!NotificationsSupported)
+ {
+ return null;
+ }
+
+ try
+ {
+ var firebaseToken = await FirebaseMessaging.Instance.GetToken();
+ return new Installation
+ {
+ InstallationId = GetDeviceId(),
+ Platform = NotificationPlatform.FcmV1,
+ PushChannel = firebaseToken.ToString()
+ };
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex.Message);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/Notifications/PushNotificationFirebaseMessagingService.cs b/MauiNotifications/Platforms/Android/Notifications/PushNotificationFirebaseMessagingService.cs
new file mode 100644
index 00000000..e95cd46b
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/Notifications/PushNotificationFirebaseMessagingService.cs
@@ -0,0 +1,45 @@
+namespace MauiNotifications;
+
+using Android;
+using Android.App;
+using Android.Content.PM;
+using AndroidX.Core.Content;
+using Firebase.Messaging;
+
+[Service(Exported = false)]
+[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
+public class PushNotificationFirebaseMessagingService : FirebaseMessagingService
+{
+ int messageId;
+ public override void OnMessageReceived(RemoteMessage message)
+ {
+ base.OnMessageReceived(message);
+ MainThread.InvokeOnMainThreadAsync(() =>
+ {
+ if (OperatingSystem.IsAndroidVersionAtLeast(33)
+ && ContextCompat.CheckSelfPermission(this, Manifest.Permission.PostNotifications) != Permission.Granted)
+ {
+ return;
+ }
+
+ if (!OperatingSystem.IsAndroidVersionAtLeast(26))
+ {
+ return;
+ }
+
+ var pushNotification = message.GetNotification();
+
+ var manager = (NotificationManager?)Application.Context.GetSystemService(NotificationService);
+ var channel = new NotificationChannel(pushNotification.ChannelId ?? "MauiNotifications", "MauiNotifications", NotificationImportance.Max);
+ manager?.CreateNotificationChannel(channel);
+
+ var notification = new Notification.Builder(Application.Context, channel.Id)
+ .SetContentTitle(pushNotification.Title)
+ .SetContentText(pushNotification.Body)
+ .SetSmallIcon(Android.Resource.Mipmap.SymDefAppIcon)
+ .Build();
+
+ manager?.Notify(messageId++, notification);
+ });
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/Resources/values/colors.xml b/MauiNotifications/Platforms/Android/Resources/values/colors.xml
new file mode 100644
index 00000000..c04d7492
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/Resources/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #512BD4
+ #2B0B98
+ #2B0B98
+
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Android/google-services.json b/MauiNotifications/Platforms/Android/google-services.json
new file mode 100644
index 00000000..cf2f4c45
--- /dev/null
+++ b/MauiNotifications/Platforms/Android/google-services.json
@@ -0,0 +1,39 @@
+{
+ "project_info": {
+ "project_number": "101175590579",
+ "project_id": "maui-notifications",
+ "storage_bucket": "maui-notifications.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:101175590579:android:98d9b7697016bd4e10fac6",
+ "android_client_info": {
+ "package_name": "com.vladislavantonyuk.mauinotifications"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "101175590579-5032un3bdrvh4b4qa3md6s4o6src7eis.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyAEuFZetrKwzwszXXpda9RzdRuVIWn4pP0"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "101175590579-5032un3bdrvh4b4qa3md6s4o6src7eis.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/MacCatalyst/AppDelegate.cs b/MauiNotifications/Platforms/MacCatalyst/AppDelegate.cs
new file mode 100644
index 00000000..435a0c7a
--- /dev/null
+++ b/MauiNotifications/Platforms/MacCatalyst/AppDelegate.cs
@@ -0,0 +1,9 @@
+namespace MauiNotifications;
+
+using Foundation;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/MacCatalyst/DeviceInstallationService.cs b/MauiNotifications/Platforms/MacCatalyst/DeviceInstallationService.cs
new file mode 100644
index 00000000..9e7a0330
--- /dev/null
+++ b/MauiNotifications/Platforms/MacCatalyst/DeviceInstallationService.cs
@@ -0,0 +1,16 @@
+namespace MauiNotifications;
+
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService
+{
+ public static string GetDeviceId()
+ {
+ return string.Empty;
+ }
+
+ private static Task GetInstallation()
+ {
+ return Task.FromResult(null);
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/MacCatalyst/Entitlements.plist b/MauiNotifications/Platforms/MacCatalyst/Entitlements.plist
new file mode 100644
index 00000000..de4adc94
--- /dev/null
+++ b/MauiNotifications/Platforms/MacCatalyst/Entitlements.plist
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ com.apple.security.app-sandbox
+
+
+ com.apple.security.network.client
+
+
+
+
diff --git a/MauiNotifications/Platforms/MacCatalyst/Info.plist b/MauiNotifications/Platforms/MacCatalyst/Info.plist
new file mode 100644
index 00000000..72689771
--- /dev/null
+++ b/MauiNotifications/Platforms/MacCatalyst/Info.plist
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UIDeviceFamily
+
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/MauiNotifications/Platforms/MacCatalyst/Program.cs b/MauiNotifications/Platforms/MacCatalyst/Program.cs
new file mode 100644
index 00000000..4523399f
--- /dev/null
+++ b/MauiNotifications/Platforms/MacCatalyst/Program.cs
@@ -0,0 +1,15 @@
+namespace MauiNotifications;
+
+using ObjCRuntime;
+using UIKit;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Tizen/DeviceInstallationService.cs b/MauiNotifications/Platforms/Tizen/DeviceInstallationService.cs
new file mode 100644
index 00000000..9e7a0330
--- /dev/null
+++ b/MauiNotifications/Platforms/Tizen/DeviceInstallationService.cs
@@ -0,0 +1,16 @@
+namespace MauiNotifications;
+
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService
+{
+ public static string GetDeviceId()
+ {
+ return string.Empty;
+ }
+
+ private static Task GetInstallation()
+ {
+ return Task.FromResult(null);
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Tizen/Main.cs b/MauiNotifications/Platforms/Tizen/Main.cs
new file mode 100644
index 00000000..166e33f7
--- /dev/null
+++ b/MauiNotifications/Platforms/Tizen/Main.cs
@@ -0,0 +1,17 @@
+namespace MauiNotifications
+{
+ using System;
+ using Microsoft.Maui;
+ using Microsoft.Maui.Hosting;
+
+ internal class Program : MauiApplication
+ {
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ app.Run(args);
+ }
+ }
+}
diff --git a/MauiNotifications/Platforms/Tizen/tizen-manifest.xml b/MauiNotifications/Platforms/Tizen/tizen-manifest.xml
new file mode 100644
index 00000000..2675fdda
--- /dev/null
+++ b/MauiNotifications/Platforms/Tizen/tizen-manifest.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ maui-appicon-placeholder
+
+
+
+
+ http://tizen.org/privilege/internet
+
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Windows/App.xaml b/MauiNotifications/Platforms/Windows/App.xaml
new file mode 100644
index 00000000..269b60f4
--- /dev/null
+++ b/MauiNotifications/Platforms/Windows/App.xaml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/MauiNotifications/Platforms/Windows/App.xaml.cs b/MauiNotifications/Platforms/Windows/App.xaml.cs
new file mode 100644
index 00000000..b0f3659f
--- /dev/null
+++ b/MauiNotifications/Platforms/Windows/App.xaml.cs
@@ -0,0 +1,23 @@
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace MauiNotifications.WinUI;
+
+using Microsoft.UI.Xaml;
+
+///
+/// Provides application-specific behavior to supplement the default Application class.
+///
+public partial class App : MauiWinUIApplication
+{
+ ///
+ /// Initializes the singleton application object. This is the first line of authored code
+ /// executed, and as such is the logical equivalent of main() or WinMain().
+ ///
+ public App()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Windows/DeviceInstallationService.cs b/MauiNotifications/Platforms/Windows/DeviceInstallationService.cs
new file mode 100644
index 00000000..ecead585
--- /dev/null
+++ b/MauiNotifications/Platforms/Windows/DeviceInstallationService.cs
@@ -0,0 +1,32 @@
+namespace MauiNotifications;
+
+using System.Diagnostics;
+using Windows.Networking.PushNotifications;
+using Windows.Security.ExchangeActiveSyncProvisioning;
+using CommunityToolkit.Maui.Alerts;
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService
+{
+ public static string GetDeviceId()
+ {
+ return new EasClientDeviceInformation().Id.ToString();
+ }
+
+ private static async Task GetInstallation()
+ {
+ var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
+ channel.PushNotificationReceived += Channel_PushNotificationReceived;
+ return new Installation
+ {
+ InstallationId = GetDeviceId(),
+ Platform = NotificationPlatform.Wns,
+ PushChannel = channel.Uri
+ };
+ }
+
+ private static async void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)
+ {
+ await Toast.Make(args.RawNotification.Content).Show();
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Windows/Package.appxmanifest b/MauiNotifications/Platforms/Windows/Package.appxmanifest
new file mode 100644
index 00000000..bd76cdc0
--- /dev/null
+++ b/MauiNotifications/Platforms/Windows/Package.appxmanifest
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ $placeholder$
+ Vladislav Antonyuk
+ $placeholder$.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/Windows/app.manifest b/MauiNotifications/Platforms/Windows/app.manifest
new file mode 100644
index 00000000..a667906d
--- /dev/null
+++ b/MauiNotifications/Platforms/Windows/app.manifest
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor
+
+
+
diff --git a/MauiNotifications/Platforms/iOS/AppDelegate.cs b/MauiNotifications/Platforms/iOS/AppDelegate.cs
new file mode 100644
index 00000000..435a0c7a
--- /dev/null
+++ b/MauiNotifications/Platforms/iOS/AppDelegate.cs
@@ -0,0 +1,9 @@
+namespace MauiNotifications;
+
+using Foundation;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/iOS/DeviceInstallationService.cs b/MauiNotifications/Platforms/iOS/DeviceInstallationService.cs
new file mode 100644
index 00000000..9e7a0330
--- /dev/null
+++ b/MauiNotifications/Platforms/iOS/DeviceInstallationService.cs
@@ -0,0 +1,16 @@
+namespace MauiNotifications;
+
+using Microsoft.Azure.NotificationHubs;
+
+public partial class DeviceInstallationService
+{
+ public static string GetDeviceId()
+ {
+ return string.Empty;
+ }
+
+ private static Task GetInstallation()
+ {
+ return Task.FromResult(null);
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Platforms/iOS/Info.plist b/MauiNotifications/Platforms/iOS/Info.plist
new file mode 100644
index 00000000..0004a4fd
--- /dev/null
+++ b/MauiNotifications/Platforms/iOS/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/MauiNotifications/Platforms/iOS/Program.cs b/MauiNotifications/Platforms/iOS/Program.cs
new file mode 100644
index 00000000..4523399f
--- /dev/null
+++ b/MauiNotifications/Platforms/iOS/Program.cs
@@ -0,0 +1,15 @@
+namespace MauiNotifications;
+
+using ObjCRuntime;
+using UIKit;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/Properties/launchSettings.json b/MauiNotifications/Properties/launchSettings.json
new file mode 100644
index 00000000..edf8aadc
--- /dev/null
+++ b/MauiNotifications/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Windows Machine": {
+ "commandName": "MsixPackage",
+ "nativeDebugging": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/MauiNotifications/README.md b/MauiNotifications/README.md
new file mode 100644
index 00000000..46070d2f
--- /dev/null
+++ b/MauiNotifications/README.md
@@ -0,0 +1,7 @@
+# .NET MAUI Push Notifications using Azure Notification Hub
+
+[![Buy Me A Coffee](https://ik.imagekit.io/VladislavAntonyuk/vladislavantonyuk/misc/bmc-button.png)](https://www.buymeacoffee.com/vlad.antonyuk)
+
+Article: https://vladislavantonyuk.github.io/articles/.NET-MAUI-Push-Notifications-using-Azure-Notification-Hub.-Part-2.-Setup-.NET-MAUI/
+
+[![Stand With Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua)
\ No newline at end of file
diff --git a/MauiNotifications/README.mdpp b/MauiNotifications/README.mdpp
new file mode 100644
index 00000000..e3ea4bec
--- /dev/null
+++ b/MauiNotifications/README.mdpp
@@ -0,0 +1,7 @@
+# .NET MAUI Push Notifications using Azure Notification Hub
+
+!INCLUDE "./md/header.mdpp"
+
+Article: https://vladislavantonyuk.github.io/articles/.NET-MAUI-Push-Notifications-using-Azure-Notification-Hub.-Part-2.-Setup-.NET-MAUI/
+
+!INCLUDE "./md/footer.mdpp"
\ No newline at end of file
diff --git a/MauiNotifications/Resources/AppIcon/appicon.svg b/MauiNotifications/Resources/AppIcon/appicon.svg
new file mode 100644
index 00000000..9d63b651
--- /dev/null
+++ b/MauiNotifications/Resources/AppIcon/appicon.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Resources/AppIcon/appiconfg.svg b/MauiNotifications/Resources/AppIcon/appiconfg.svg
new file mode 100644
index 00000000..21dfb25f
--- /dev/null
+++ b/MauiNotifications/Resources/AppIcon/appiconfg.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Resources/Images/dotnet_bot.png b/MauiNotifications/Resources/Images/dotnet_bot.png
new file mode 100644
index 00000000..f93ce025
Binary files /dev/null and b/MauiNotifications/Resources/Images/dotnet_bot.png differ
diff --git a/MauiNotifications/Resources/Splash/splash.svg b/MauiNotifications/Resources/Splash/splash.svg
new file mode 100644
index 00000000..21dfb25f
--- /dev/null
+++ b/MauiNotifications/Resources/Splash/splash.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Resources/Styles/Colors.xaml b/MauiNotifications/Resources/Styles/Colors.xaml
new file mode 100644
index 00000000..30307a5d
--- /dev/null
+++ b/MauiNotifications/Resources/Styles/Colors.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+ #512BD4
+ #ac99ea
+ #242424
+ #DFD8F7
+ #9880e5
+ #2B0B98
+
+ White
+ Black
+ #D600AA
+ #190649
+ #1f1f1f
+
+ #E1E1E1
+ #C8C8C8
+ #ACACAC
+ #919191
+ #6E6E6E
+ #404040
+ #212121
+ #141414
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MauiNotifications/Resources/Styles/Styles.xaml b/MauiNotifications/Resources/Styles/Styles.xaml
new file mode 100644
index 00000000..19ceac51
--- /dev/null
+++ b/MauiNotifications/Resources/Styles/Styles.xaml
@@ -0,0 +1,426 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MauiPaint/MauiPaint.csproj b/MauiPaint/MauiPaint.csproj
index 13e68f1a..2f27f904 100644
--- a/MauiPaint/MauiPaint.csproj
+++ b/MauiPaint/MauiPaint.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/MauiSamples.sln b/MauiSamples.sln
index 9f4f4fb0..4f4ffc78 100644
--- a/MauiSamples.sln
+++ b/MauiSamples.sln
@@ -145,28 +145,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Balloon", "AndroidBindableL
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "AndroidBindableLibraries\Sample\Sample.csproj", "{8782844B-0C34-42AE-8BF9-E2DB2CC95495}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MauiNotifications", "MauiNotifications\MauiNotifications.csproj", "{D10497DF-0FDA-4F52-9C30-8F73C5FCC459}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.Build.0 = Release|Any CPU
- {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Release|Any CPU.Build.0 = Release|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.Build.0 = Release|Any CPU
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.Deploy.0 = Release|Any CPU
{B91198E0-08DE-41B6-9056-95F90C3E0AD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B91198E0-08DE-41B6-9056-95F90C3E0AD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B91198E0-08DE-41B6-9056-95F90C3E0AD8}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
@@ -437,13 +423,33 @@ Global
{5411B28C-9E39-4FAF-BC6E-448C0DC9F0BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5411B28C-9E39-4FAF-BC6E-448C0DC9F0BC}.Release|Any CPU.Build.0 = Release|Any CPU
{5411B28C-9E39-4FAF-BC6E-448C0DC9F0BC}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7139BF92-182F-4CA9-B2A0-DAF4110A8C12}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80BC6E88-5A41-426D-B625-B8EEE1453FF0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D10497DF-0FDA-4F52-9C30-8F73C5FCC459}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {80BC6E88-5A41-426D-B625-B8EEE1453FF0} = {E08722A6-C1B6-4C83-983C-809BF721D6F1}
- {8782844B-0C34-42AE-8BF9-E2DB2CC95495} = {E08722A6-C1B6-4C83-983C-809BF721D6F1}
{B91198E0-08DE-41B6-9056-95F90C3E0AD8} = {14D979DA-85FE-41DC-9C59-A49EE52EC9A5}
{43BACDC9-2889-476E-AF08-727E1B31D0B8} = {671C019C-7DCC-4B9E-AD7D-B9F6F35D044E}
{671C019C-7DCC-4B9E-AD7D-B9F6F35D044E} = {D3C704D0-FB95-42BA-BBF1-E7360491551F}
@@ -466,6 +472,8 @@ Global
{8C5E6060-1051-43D5-8FDF-5B9447756BD1} = {A4982784-AAC5-4C47-A1F8-A0A9DB51D531}
{3459E2A7-DEB6-46B8-AE8E-435908A3F2DE} = {A4982784-AAC5-4C47-A1F8-A0A9DB51D531}
{5411B28C-9E39-4FAF-BC6E-448C0DC9F0BC} = {A4982784-AAC5-4C47-A1F8-A0A9DB51D531}
+ {80BC6E88-5A41-426D-B625-B8EEE1453FF0} = {E08722A6-C1B6-4C83-983C-809BF721D6F1}
+ {8782844B-0C34-42AE-8BF9-E2DB2CC95495} = {E08722A6-C1B6-4C83-983C-809BF721D6F1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
diff --git a/MauiShellCustomization/MauiShellCustomization.csproj b/MauiShellCustomization/MauiShellCustomization.csproj
index fcabdf11..42095f89 100644
--- a/MauiShellCustomization/MauiShellCustomization.csproj
+++ b/MauiShellCustomization/MauiShellCustomization.csproj
@@ -30,6 +30,6 @@
-
+
diff --git a/MauiSpeech/MauiSpeech.csproj b/MauiSpeech/MauiSpeech.csproj
index 577e1bcb..82307316 100644
--- a/MauiSpeech/MauiSpeech.csproj
+++ b/MauiSpeech/MauiSpeech.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/MauiTests/Client.Android.UITests/Client.Android.UITests.csproj b/MauiTests/Client.Android.UITests/Client.Android.UITests.csproj
index 9905a7e6..e28b0a89 100644
--- a/MauiTests/Client.Android.UITests/Client.Android.UITests.csproj
+++ b/MauiTests/Client.Android.UITests/Client.Android.UITests.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/MauiTests/Client.MacCatalyst.UITests/Client.MacCatalyst.UITests.csproj b/MauiTests/Client.MacCatalyst.UITests/Client.MacCatalyst.UITests.csproj
index bda5af5b..11f1fe1c 100644
--- a/MauiTests/Client.MacCatalyst.UITests/Client.MacCatalyst.UITests.csproj
+++ b/MauiTests/Client.MacCatalyst.UITests/Client.MacCatalyst.UITests.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/MauiTests/Client.Tizen.UITests/Client.Tizen.UITests.csproj b/MauiTests/Client.Tizen.UITests/Client.Tizen.UITests.csproj
index f0a80cee..865617c0 100644
--- a/MauiTests/Client.Tizen.UITests/Client.Tizen.UITests.csproj
+++ b/MauiTests/Client.Tizen.UITests/Client.Tizen.UITests.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/MauiTests/Client.Windows.UITests/Client.Windows.UITests.csproj b/MauiTests/Client.Windows.UITests/Client.Windows.UITests.csproj
index 0b4383b4..e5752e9d 100644
--- a/MauiTests/Client.Windows.UITests/Client.Windows.UITests.csproj
+++ b/MauiTests/Client.Windows.UITests/Client.Windows.UITests.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/MauiTests/Client.iOS.UITests/Client.iOS.UITests.csproj b/MauiTests/Client.iOS.UITests/Client.iOS.UITests.csproj
index fac968d2..6af1325c 100644
--- a/MauiTests/Client.iOS.UITests/Client.iOS.UITests.csproj
+++ b/MauiTests/Client.iOS.UITests/Client.iOS.UITests.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/MauiWorkflowBuilder/MauiWorkflowBuilder.csproj b/MauiWorkflowBuilder/MauiWorkflowBuilder.csproj
index 53b07714..834bc7ac 100644
--- a/MauiWorkflowBuilder/MauiWorkflowBuilder.csproj
+++ b/MauiWorkflowBuilder/MauiWorkflowBuilder.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/README.md b/README.md
index 18a4f459..8662b304 100644
--- a/README.md
+++ b/README.md
@@ -79,4 +79,6 @@ The development guide can be found at [SETUP.md](./SETUP.md).
1. [MauiStaggeredCollectionView](MauiStaggeredCollectionView) - Create a Staggered Layout for CollectionView in .NET MAUI.
+1. [MauiNotifications](MauiNotifications) - .NET MAUI Push Notifications using Azure Notification Hub.
+
[![Stand With Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua)
\ No newline at end of file
diff --git a/README.mdpp b/README.mdpp
index dfad368c..d198ab28 100644
--- a/README.mdpp
+++ b/README.mdpp
@@ -79,4 +79,6 @@ The development guide can be found at [SETUP.md](./SETUP.md).
1. [MauiStaggeredCollectionView](MauiStaggeredCollectionView) - Create a Staggered Layout for CollectionView in .NET MAUI.
+1. [MauiNotifications](MauiNotifications) - .NET MAUI Push Notifications using Azure Notification Hub.
+
!INCLUDE "md/footer.mdpp"
diff --git a/TutorialHelp/TutorialHelp.csproj b/TutorialHelp/TutorialHelp.csproj
index d6d12689..344e2ddd 100644
--- a/TutorialHelp/TutorialHelp.csproj
+++ b/TutorialHelp/TutorialHelp.csproj
@@ -25,7 +25,7 @@
-
+