diff --git a/.github/ISSUE_TEMPLATE/02_feature_request.yml b/.github/ISSUE_TEMPLATE/02_feature_request.yml
index 21189e3a30..029830c7c5 100644
--- a/.github/ISSUE_TEMPLATE/02_feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/02_feature_request.yml
@@ -1,6 +1,6 @@
name: 💡 Feature request
description: Suggest an idea for this project
-labels: [feature]
+labels: [feature-request]
body:
- type: checkboxes
attributes:
diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 5018867dd0..c10342758f 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -33,4 +33,4 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
gh pr review auto-merge/rel-7-4/${{github.run_number}} --approve
- gh pr merge auto-merge/rel-7-4/${{github.run_number}} --merge --delete-branch
+ gh pr merge auto-merge/rel-7-4/${{github.run_number}} --merge --delete-branch
\ No newline at end of file
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index c2b1557405..696d401fed 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -17,6 +17,7 @@ on:
- 'templates/**/*.csproj'
- 'templates/**/*.razor'
- 'Directory.Build.props'
+ - 'Directory.Packages.props'
pull_request:
paths:
@@ -33,6 +34,7 @@ on:
- 'templates/**/*.csproj'
- 'templates/**/*.razor'
- 'Directory.Build.props'
+ - 'Directory.Packages.props'
types:
- opened
- synchronize
@@ -49,7 +51,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@master
with:
- dotnet-version: 7.0.100
+ dotnet-version: 8.0.100
- name: chown
run: |
diff --git a/Directory.Build.props b/Directory.Build.props
index eb271341d3..f601750180 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,54 +1,10 @@
-
-
- 7.0.10
-
-
- 7.0.10
-
-
- 7.0.0
-
-
- 17.2.0
-
-
- 4.3.0
-
-
- 4.1.0
-
-
- 2.4.1
-
-
- 2.4.1
-
-
- 2.4.5
-
-
- 3.1.3
-
-
- 4.2.0
-
-
- 1.20.0
-
-
- 7.2.3
-
true
-
-
- 4.8.0
-
-
+ allruntime; build; native; contentfiles; analyzers
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 0000000000..2e28ebc0ea
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,171 @@
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000000..43e9cba5de
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| 7.x.x | :white_check_mark: |
+| < 7.0.0 | :x: |
+
+## Reporting a Vulnerability
+
+Please don not share vulnerabilities publicly in GitHub or other platforms.
+You can report security issues by sending a email to `security@abp.io`
+Your report is immediately evaluated. We publish patch versions for critical vulnerabilities in a week at most.
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/AbpIoLocalization.csproj b/abp_io/AbpIoLocalization/AbpIoLocalization/AbpIoLocalization.csproj
index 400c15ff77..267ace87f2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/AbpIoLocalization.csproj
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/AbpIoLocalization.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netstandard2.1;net7.0
+ netstandard2.0;netstandard2.1;net8.0
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
index e5df7c7915..f3c4c35a4d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
@@ -493,6 +493,73 @@
"QuotationTemplate.Tax/VAT:": "Tax / Vat (%{0}) :",
"QuotationTemplate.TotalDiscount:": "Total Discount :",
"QuotationTemplate.TOTALDUE:": "TOTAL DUE :",
- "QuotationTemplate.BankAccount": "Our bank account information can be found at {0}"
+ "QuotationTemplate.BankAccount": "Our bank account information can be found at {0}",
+ "Permission:Raffles": "Raffle",
+ "Permission:Draw": "Draw",
+ "Menu:Raffles": "Raffles",
+ "RaffleIsNotDrawable": "Raffle is not drawable",
+ "WinnerCountMustBeGreaterThanZero": "Winner count must be greater than zero",
+ "FullDescription": "Full Description",
+ "VisibilityStartDate": "Visibility Start Date",
+ "VisibilityEndDate": "Visibility End Date",
+ "RaffleDate": "Raffle Date",
+ "SubscriptionCode": "Subscription Code",
+ "GroupCode": "Group Code",
+ "MaxWinnerCount": "Max Winner Count",
+ "ReDraw": "Re-Draw",
+ "EditRaffle": "Edit Raffle",
+ "Raffles": "Raffles",
+ "CreateARaffle": "Create a raffle",
+ "Draw": "Draw",
+ "Enum:RaffleStatus:0": "Active",
+ "Enum:RaffleStatus:1": "Next",
+ "Enum:RaffleStatus:2": "Past",
+ "DrawDone": "Draw Done",
+ "HomePageShowType": "Home Page Show Type",
+ "None": "None",
+ "Card": "Card",
+ "Horizontal": "Horizontal",
+ "Winners": "Winners",
+ "StartDateMustBeLessThanEndDate": "Start date must be less than end date",
+ "VisibilityStartDateMustBeLessThanVisibilityEndDate": "Visibility start date must be less than visibility end date",
+ "StartDateMustBeGreaterThanVisibilityStartDate": "Start date must be greater than visibility start date",
+ "EndDateMustBeLessThanVisibilityEndDate": "End date must be less than visibility end date",
+ "DrawnDone": "Drawn Done",
+ "AddColor": "Add Color",
+ "Colors": "Colors",
+ "RemoveColor": "Remove Color",
+ "MaxColorCountWarning": "You can add up to {0} colors",
+ "MinColorCountWarning": "You must add at least {0} colors",
+ "RaffleDeletionConfirmationMessage": "Are you sure you want to delete this raffle?",
+ "CreateRaffle": "Create Raffle",
+ "RemoveImage": "Remove Image",
+ "SuccessfullySaved": "Successfully saved",
+ "Menu:CommunityTalks": "Community Talks",
+ "Menu:Conferences": "Conferences",
+ "Menu:OtherLiveEvents": "Other Live Events",
+ "Menu:SponsoredConferences": "Sponsored Conferences",
+ "Logo": "Logo",
+ "Slug": "Slug",
+ "CompanyUrl": "Company Url",
+ "TalkTitle": "Talk Title",
+ "AbstractTopic": "Abstract Topic",
+ "Bio": "Bio",
+ "LinkedIn": "LinkedIn",
+ "Github": "Github",
+ "Twitch": "Twitch",
+ "Youtube": "Youtube",
+ "Twitter": "Twitter",
+ "PersonalWebsite": "Personal Website",
+ "VideoId": "Video Id",
+ "Order": "Order",
+ "Image1x1": "Image 1x1",
+ "Image16x9": "Image 16x9",
+ "Banner": "Banner",
+ "Speaker": "Speaker",
+ "SessionDate": "Session Date",
+ "AddSession": "Add Session",
+ "AddSponsor": "Add Sponsor",
+ "SponsorLogo": "Sponsor Logo",
+ "RegistrationUrl": "Registration Url"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json
index 4a7e64125f..2bfbb7f885 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json
@@ -145,7 +145,7 @@
"Footer_GithubStarCount": "{0} نجمة على GitHub",
"Footer_NugetDownloadCount": "{0} تنزيلات على NuGet",
"AbpDescription": "ABP هو إطار تطبيق مفتوح المصدر يركز على تطوير تطبيقات الويب القائمة على AspNet Core. لا تكرر نفسك، ركز على كود عملك الخاص.",
- "Layout_AbpFramework_MetaTitle": "إطار عمل ABP - إطار عمل تطبيق ويب مفتوح المصدر",
+ "Layout_AbpFramework_MetaTitle": "إطار عمل ABP | إطار تطبيق ويب مفتوح المصدر لـ ASP.NET Core",
"CommunityTalks_CountdownDays": "أيام",
"CommunityTalks_CountdownHours": "ساعات",
"CommunityTalks_CountdownMinutes": "دقيقة",
@@ -167,7 +167,7 @@
"ABPDiscordServer": "ABP سيرفر الدسكورد",
"ABPCommunityTalks": "برامج منتدى ABP الحوارية",
"ABPCommunityPosts": "منشورات منتدى ABP",
- "BuyAndGetMonths": "شراء 12 شهر، احصل على 14 شهرا!",
+ "BuyAndGetMonths": "شراء 12 شهر، احصل على 14 شهرا!",
"GetYourDeal": "احصل على صفقتك",
"BuyOrRenewLicense": "اشترِ أو جدد الرخصة الآن واحصل على شهرين إضافيين!",
"BuyOrRenewLicenseToGetExtra2Months": "اشترِ أو جدد الرخصة الآن واحصل على شهرين إضافيين! اسرع! ⏰ آخر يوم: {0}",
@@ -185,4 +185,4 @@
"CampaignBetweenDates": "من {0} إلى {1}",
"SaveUpTo": "وفر ماقد يصل الى ${0}K"
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
index 9ef432a8bd..a261c69dca 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
@@ -149,7 +149,7 @@
"Footer_GithubStarCount": "{0} Stars on GitHub",
"Footer_NugetDownloadCount": "{0} Downloads on NuGet",
"AbpDescription": "ABP is an open source application framework focused on AspNet Core based web application development. Don't repeat yourself, focus on your own business code.",
- "Layout_AbpFramework_MetaTitle": "ABP Framework - Open Source Web Application Framework",
+ "Layout_AbpFramework_MetaTitle": "ABP Framework | Open source web application framework for ASP.NET Core",
"CommunityTalks_CountdownDays": "Days",
"CommunityTalks_CountdownHours": "Hrs",
"CommunityTalks_CountdownMinutes": "Min",
@@ -171,7 +171,7 @@
"ABPDiscordServer": "ABP Discord Server",
"ABPCommunityTalks": "ABP Community Talks",
"ABPCommunityPosts": "ABP Community Posts",
- "BuyAndGetMonths": "BUY 12 MONTHS, GET 14 MONTHS!",
+ "BuyAndGetMonths": "BUY 12 MONTHS, GET 14 MONTHS!",
"GetYourDeal": "Get Your Deal",
"BuyOrRenewLicense": "Buy or Renew License Now and Get 2 Extra Months!",
"BuyOrRenewLicenseToGetExtra2Months": "Buy or Renew License Now and Get 2 Extra Months! HURRY UP! ⏰ Last Day: {0}",
@@ -187,7 +187,7 @@
"GiveAwayForNewPurchases": "Application Development Classroom Training will be given away for the new purchases!",
"BlackFriday": "BLACKFRIDAY",
"ValidForExistingCustomers": "Also valid for the existing customers!",
- "CampaignBetweenDates": "From {0} to {1}",
+ "CampaignBetweenDates": "From {0} To {1}",
"SaveUpTo": "SAVE UP TO${0}K",
"ImplementingDDD": "Implementing Domain Driven Design",
"ExploreTheEBook": "Explore the E-Book",
@@ -220,6 +220,16 @@
"NoContent": "No content",
"More": "More",
"WhyABPIOPlatform": "Why ABP.IO Platform?",
- "AbpStudio": "ABP Studio"
+ "AbpStudio": "ABP Studio",
+ "ExtraMonths": "{0}EXTRA MONTHS",
+ "RSS": "RSS",
+ "RSSFeed": "RSS Feed",
+ "Articles": "Articles",
+ "Organizations": "Organizations",
+ "ManageAccount": "Manage Account",
+ "CommunityProfile": "Community Profile",
+ "BlogProfile": "Blog Profile",
+ "Tickets": "Tickets",
+ "Videos": "Videos"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json
index 16437480ef..c4c5217383 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json
@@ -148,7 +148,7 @@
"Footer_GithubStarCount": "{0} tähteä GitHubissa",
"Footer_NugetDownloadCount": "{0} Lataukset NuGetissä",
"AbpDescription": "ABP on avoimen lähdekoodin sovelluskehys, joka keskittyy AspNet Core -pohjaiseen verkkosovelluskehitykseen. Älä toista itseäsi, vaan keskity omaan yrityskoodiisi.",
- "Layout_AbpFramework_MetaTitle": "ABP Framework - avoimen lähdekoodin verkkosovelluskehys",
+ "Layout_AbpFramework_MetaTitle": "ABP Framework | Avoimen lähdekoodin verkkosovelluskehys ASP.NET Corelle",
"CommunityTalks_CountdownDays": "Pv",
"CommunityTalks_CountdownHours": "T",
"CommunityTalks_CountdownMinutes": "Min",
@@ -170,7 +170,7 @@
"ABPDiscordServer": "ABP Discord-palvelin",
"ABPCommunityTalks": "ABP Community Talks",
"ABPCommunityPosts": "ABP-yhteisön viestit",
- "BuyAndGetMonths": "OSTA 12 KUUKAUTA, SAAT 14 KUUKAUTA!",
+ "BuyAndGetMonths": "OSTA 12 KUUKAUTA, SAAT 14 KUUKAUTA!",
"GetYourDeal": "Hanki tarjouksesi",
"BuyOrRenewLicense": "Osta tai uusi lisenssi nyt ja saat 2 lisäkuukautta!",
"BuyOrRenewLicenseToGetExtra2Months": "Osta tai uusi lisenssi nyt ja saat 2 lisäkuukautta! KIIREHDI! ⏰ Viimeinen päivä: {0}",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json
index b9ccddecf4..91b61dd996 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json
@@ -146,7 +146,7 @@
"Footer_GithubStarCount": "{0} csillagok a GitHubon",
"Footer_NugetDownloadCount": "{0} Letöltések a NuGeten",
"AbpDescription": "Az ABP egy nyílt forráskódú alkalmazás keretrendszer, amely az AspNet Core alapú webalkalmazások fejlesztésére összpontosít. Ne ismételje magát, összpontosítson saját üzleti kódjára.",
- "Layout_AbpFramework_MetaTitle": "ABP Framework – Nyílt forráskódú webalkalmazás-keretrendszer",
+ "Layout_AbpFramework_MetaTitle": "ABP Framework | Nyílt forráskódú webalkalmazás-keretrendszer az ASP.NET Core számára",
"CommunityTalks_CountdownDays": "Napok",
"CommunityTalks_CountdownHours": "óra",
"CommunityTalks_CountdownMinutes": "Perc",
@@ -168,7 +168,7 @@
"ABPDiscordServer": "ABP Discord szerver",
"ABPCommunityTalks": "ABP közösségi beszélgetések",
"ABPCommunityPosts": "ABP közösségi bejegyzések",
- "BuyAndGetMonths": "VÁSÁROLJON 12 HÓNAPOT, 14 HÓNAPOT KAP!",
+ "BuyAndGetMonths": "VÁSÁROLJON 12 HÓNAPOT, 14 HÓNAPOT KAP!",
"GetYourDeal": "Szerezze meg az ajánlatát",
"BuyOrRenewLicense": "Vásároljon vagy újítson meg licencet most, és 2 további hónapot kap!",
"BuyOrRenewLicenseToGetExtra2Months": "Vásároljon vagy újítson meg licencet most, és 2 további hónapot kap! SIESS! ⏰ Utolsó nap: {0}",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
index 827ebb724c..ee4f7ca6e9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
@@ -140,7 +140,7 @@
"Footer_GithubStarCount": "Github'da {0} Yıldız",
"Footer_NugetDownloadCount": "{0} NuGet indirme",
"AbpDescription": "ABP, AspNet Core tabanlı web uygulaması geliştirmeye odaklanan açık kaynaklı bir uygulama çerçevesidir. Kendinizi tekrar etmeyin, kendi iş kodunuza odaklanın.",
- "Layout_AbpFramework_MetaTitle": "ABP Framework - Açık Kaynak Web Uygulama Çerçevesi",
+ "Layout_AbpFramework_MetaTitle": "ABP Framework | ASP.NET Core için açık kaynaklı web uygulama çerçevesi",
"CommunityTalks_CountdownDays": "Gün",
"CommunityTalks_CountdownHours": "Saat",
"CommunityTalks_CountdownMinutes": "Dk",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
index d1a0db7176..faf8b64d1f 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
@@ -148,7 +148,7 @@
"Footer_GithubStarCount": "{0} GitHub 上的星星",
"Footer_NugetDownloadCount": "{0} NuGet 下载量",
"AbpDescription": "ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的 Web 应用程序开发。 Don't repeat yourself,专注于自己的业务代码。",
- "Layout_AbpFramework_MetaTitle": "ABP 框架 - 开源 Web 应用程序框架",
+ "Layout_AbpFramework_MetaTitle": "ABP 框架 | ASP.NET Core 的开源 Web 应用程序框架",
"CommunityTalks_CountdownDays": "天",
"CommunityTalks_CountdownHours": "小时",
"CommunityTalks_CountdownMinutes": "分钟",
@@ -170,7 +170,7 @@
"ABPDiscordServer": "ABP Discord 服务器",
"ABPCommunityTalks": "ABP社区讲话",
"ABPCommunityPosts": "ABP社区文章",
- "BuyAndGetMonths": "购买 12 个月,获得 14 个月!",
+ "BuyAndGetMonths": "购买 12 个月,获得 14 个月!",
"GetYourDeal": "得到你的交易",
"BuyOrRenewLicense": "立即购买或续订许可证并额外获得 2 个月!",
"BuyOrRenewLicenseToGetExtra2Months": "立即购买或续订 ABP 商业许可证(适用于所有版本)并额外获得 2 个月!",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
index 7226737b84..362a5f0f22 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " نظام أساسي كامل لتطوير الويب span> span> مدمج framework ",
"AbpCommercialShortDescription": "يوفر ABP Commercial وحدات تطبيق مسبقة الإنشاء وأدوات تطوير سريعة للتطبيقات وموضوعات واجهة مستخدم احترافية ودعمًا متميزًا والمزيد.",
"LiveDemo": "عرض حي",
+ "LiveDemoLead": "{1} باستخدام حساب ABP الخاص بك، {3}إلى abp.io. أو املأ النموذج أدناه لإنشاء عرض توضيحي مباشر الآن",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "هناك حساب بالفعل باستخدام عنوان البريد الإلكتروني المحدد: {0} يمكنك تسجيل الدخول باستخدام حسابك للمتابعة.",
"GetLicence": "احصل على ترخيص",
"Application": "تطبيق",
"StartupTemplates": "قوالب بدء تشغيل ABP",
@@ -129,12 +131,14 @@
"YourFullName": "اسمك الكامل",
"EmailField": "عنوان البريد الإلكتروني",
"YourEmailAddress": "عنوان بريدك الإلكتروني",
+ "ValidEmailAddressIsRequired": "مطلوب عنوان بريد إلكتروني صالح.",
"HowMayWeHelpYou": "كيف يمكن أن نساعدك؟",
"SendMessage": "أرسل رسالة",
"Success": "النجاح",
"WeWillReplyYou": "لقد تلقينا رسالتك وسنتواصل معك قريبًا.",
"GoHome": "اذهب للمنزل",
"CreateLiveDemo": "إنشاء عرض حي",
+ "CreateLiveDemoDescription": "بمجرد إرسال هذا النموذج ، ستتلقى رسالة بريد إلكتروني تحتوي على رابط العرض التوضيحي الخاص بك.",
"RegisterToTheNewsletter": "سجل في النشرة الإخبارية لتلقي معلومات بخصوص ABP.IO ، بما في ذلك الإصدارات الجديدة وما إلى ذلك.",
"EnterYourEmailOrLogin": "أدخل عنوان بريدك الإلكتروني لإنشاء العرض التوضيحي أو تسجيل الدخول باستخدام حسابك الحالي.",
"ApplicationTemplate": "نموذج التطبيق",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
index a1205f1809..ef5e3d17c6 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Kompletní platforma pro vývoj webuvestavěná na framework",
"AbpCommercialShortDescription": "ABP Commercial poskytuje předpřipravené aplikační moduly, nástroje pro rychlý vývoj aplikací, profesionální témata uživatelského rozhraní, prémiovou podporu a další.",
"LiveDemo": "Živá ukázka",
+ "LiveDemoLead": "{1} pomocí vašeho účtu ABP, {3} na abp.io. Nebo vyplňte níže uvedený formulář a vytvořte si nyní živou ukázku",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Zadaná e-mailová adresa {0} je již registrována. Můžete se přihlásit se svým účtem a pokračovat.",
"GetLicence": "Získejte licenci",
"Application": "aplikace",
"StartupTemplates": "Spouštěcí šablony",
@@ -129,12 +131,14 @@
"YourFullName": "Vaše celé jméno",
"EmailField": "Emailová adresa",
"YourEmailAddress": "Vaše emailová adresa",
+ "ValidEmailAddressIsRequired": "Je vyžadována platná e-mailová adresa.",
"HowMayWeHelpYou": "Jak vám můžeme pomoci?",
"SendMessage": "Poslat zprávu",
"Success": "Úspěch",
"WeWillReplyYou": "Obdrželi jsme vaši zprávu a brzy se vám ozveme.",
"GoHome": "Jdi domů",
"CreateLiveDemo": "Vytvořit živé demo",
+ "CreateLiveDemoDescription": "Po odeslání tohoto formuláře obdržíte e-mail obsahující odkaz na vaši ukázku.",
"RegisterToTheNewsletter": "Zaregistrujte se k odběru newsletteru a získejte informace o ABP.IO, včetně nových verzí atd.",
"EnterYourEmailOrLogin": "Chcete-li vytvořit ukázku, zadejte svou e-mailovou adresu nebo se přihlaste pomocí svého stávajícího účtu.",
"ApplicationTemplate": "Šablona aplikace",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
index ebc78f8b51..e2bd413dfe 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Eine komplette Webentwicklungsplattformaufgebaute Framework",
"AbpCommercialShortDescription": "ABP Commercial bietet vorgefertigte Anwendungsmodule, schnelle Anwendungsentwicklungstools, professionelle UI-Themen, Premium-Support und mehr.",
"LiveDemo": "Live-Demo",
+ "LiveDemoLead": "{1} mit Ihrem ABP-Konto, {3} zu abp.io. Oder füllen Sie das Formular unten aus, um jetzt eine Live-Demo zu erstellen",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Es gibt bereits ein Konto mit der angegebenen E-Mail-Adresse: {0} Sie können sich mit Ihrem Konto anmelden, um fortzufahren.",
"GetLicence": "Holen Sie sich eine Lizenz",
"Application": "Anwendung",
"StartupTemplates": "Startup-Vorlagen",
@@ -129,12 +131,14 @@
"YourFullName": "Ihren vollständigen Namen",
"EmailField": "E-Mail-Addresse",
"YourEmailAddress": "Ihre E-Mail-Adresse",
+ "ValidEmailAddressIsRequired": "Eine gültige E-Mail-Adresse ist erforderlich.",
"HowMayWeHelpYou": "Wie können wir Ihnen helfen?",
"SendMessage": "Nachricht senden",
"Success": "Erfolg",
"WeWillReplyYou": "Wir haben Ihre Nachricht erhalten und werden uns in Kürze bei Ihnen melden.",
"GoHome": "Nach Hause gehen",
"CreateLiveDemo": "Live-Demo erstellen",
+ "CreateLiveDemoDescription": "Sobald Sie dieses Formular absenden, erhalten Sie eine E-Mail mit Ihrem Demo-Link.",
"RegisterToTheNewsletter": "Melden Sie sich für den Newsletter an, um Informationen zu ABP.IO, einschließlich Neuerscheinungen etc. zu erhalten.",
"EnterYourEmailOrLogin": "Geben Sie Ihre E-Mail-Adresse ein, um Ihre Demo zu erstellen, oder Login mit Ihrem bestehenden Konto.",
"ApplicationTemplate": "Bewerbungsvorlage",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 1b8c972d5c..92d7450319 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -49,6 +49,8 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial provides pre-built application modules, rapid application development tooling, professional UI themes, premium support and more.",
"LiveDemo": "Live Demo",
+ "LiveDemoLead": "{1} using your ABP account, {3} to abp.io. Or fill the form below to create a live demo now",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "There is already an account with the given email address: {0} You can login with your account to proceed.",
"GetLicence": "Get a License",
"Application": "Application",
"StartupTemplates": "Startup Templates",
@@ -96,7 +98,7 @@
"See All Modules": "SeeAllModules",
"ABPSuite": "ABP Suite",
"AbpSuiteShortDescription": "ABP Suite is a complementary tool to ABP Commercial.",
- "AbpSuiteExplanation": "It allows you to build web pages in a matter of minutes. It's a .NET Core Global tool that can be installed from the command line. It can create a new ABP solution, and generate CRUD pages from the database to the front-end.",
+ "AbpSuiteExplanation": "It allows you to build web pages in a matter of minutes. It's a .NET Core Global tool that can be installed from the command line. It can create a new ABP solution and generate CRUD pages from the database to the front-end.",
"Details": "Details",
"LeptonTheme": "Lepton Theme",
"ProfessionalModernUIThemes": "Professional, modern UI themes",
@@ -132,12 +134,14 @@
"LastNameField": "Last Name",
"EmailField": "E-mail Address",
"YourEmailAddress": "Your e-mail address",
+ "ValidEmailAddressIsRequired": "A valid e-mail address is required.",
"HowMayWeHelpYou": "How may we help you?",
"SendMessage": "Send Message",
"Success": "Success",
"WeWillReplyYou": "We received your message and will be in touch shortly.",
"GoHome": "Go Home",
"CreateLiveDemo": "Create Live Demo",
+ "CreateLiveDemoDescription": "Once you submit this form, you will receive an email containing your demo link.",
"RegisterToTheNewsletter": "Register for the newsletter to receive information regarding ABP.IO, including new releases etc.",
"EnterYourEmailOrLogin": "Enter your e-mail address to create your demo or Login using your existing account.",
"ApplicationTemplate": "Application Template",
@@ -177,17 +181,17 @@
"StartDevelopWithTutorials": "The downloaded solution is well architected and documented. You can start developing your own business code based on it following the tutorials.",
"TryTheCommercialDemo": "You can try the Live Demo to see a sample application created using the ABP Commercial startup template.",
"HowManyProducts": "How many different products/solutions can I build using the ABP Commercial?",
- "HowManyProductsExplanation": "You can create as many projects as you want during your active license period, there is no limit! After your license expires, you cannot create new projects, but you can continue to develop the projects you have downloaded and deploy them to an unlimited count of servers.",
+ "HowManyProductsExplanation": "You can create as many projects as you want during your active license period; there is no limit! After your license expires, you cannot create new projects, but you can continue to develop the projects you have downloaded and deploy them to an unlimited count of servers.",
"HowManyDevelopers": "How many developers can work on the ABP Commercial?",
"HowManyDevelopersExplanation": "ABP Commercial licenses are per developer. Different license types have different developer limits. However, you can add more developers to any license type whenever you need. Check out the Plans & Pricing page for license types, developer limits and additional developer costs.",
"ChangingLicenseType": "Can I upgrade my license type later?",
"ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, check out the \"How many developers can work on the ABP Commercial?\" FAQ.",
"LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?",
- "LicenseExtendUpgradeDiffExplanation": "Extending: By extending/renewing your license, you will continue to get premium support and get major or minor updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development. When you extend your license, 1 year is added to your license expiry date. Upgrading: By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. Check out the license comparison table to see the differences between the license plans. On the other hand, when you upgrade, your license expiry date will not change! To extend your license end date, you need to extend your license.",
+ "LicenseExtendUpgradeDiffExplanation": "Extending: By extending/renewing your license, you will continue to get premium support and get major or minor updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite, which speeds up your development. When you extend your license, 1 year is added to your license expiry date. Upgrading: By upgrading your license, you will be promoted to a higher license plan, which will allow you to get additional benefits. Check out the license comparison table to see the differences between the license plans. On the other hand, when you upgrade, your license expiry date will not change! To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "What is the license renewal cost after 1 year?",
"LicenseRenewalCostExplanation": "The renewal (extend) price of the standard Team License is ${0}, standard Business License is ${1} and standard Enterprise License is ${2}. If you are already a customer, log into your account to review the current renewal pricing.",
"HowDoIRenewMyLicense": "How do I renew my license?",
- "HowDoIRenewMyLicenseExplanation": "You can renew your license by navigating to the organization management page. In order to take advantage of our discounted Early Renewal rates, ensure you renew before your license expires. Don't worry about not knowing when your Early Renewal opportunity closes, you'll however receive 3 reminder e-mails before your subscription expires. We'll send them 30 days, 7 days and 1 day before expiration.",
+ "HowDoIRenewMyLicenseExplanation": "You can renew your license by navigating to the organization management page. In order to take advantage of our discounted Early Renewal rates, ensure you renew before your license expires. Don't worry about not knowing when your Early Renewal opportunity closes; you'll receive 3 reminder e-mails before your subscription expires. We'll send them 30 days, 7 days and 1 day before expiration.",
"IsSourceCodeIncluded": "Does my license include the source code of the commercial modules and themes?",
"IsSourceCodeIncludedExplanation1": "Depends on the license type you've purchased:",
"IsSourceCodeIncludedExplanation2": "Team: Your solution uses the modules and themes as NuGet and NPM packages. It doesn't include their source code. This way, you can easily upgrade these modules and themes whenever a new version is available. However, you can not get the source code of these modules and themes.",
@@ -198,7 +202,7 @@
"WhatHappensWhenLicenseEnds": "What happens when my license period ends?",
"WhatHappensWhenLicenseEndsExplanation1": "The ABP Commercial license is a perpetual license. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year update and support plan out of the box. In order to continue to get new features, performance enhancements, bug fixes, support and continue using ABP Suite, you need to renew your license. When your license expires;",
"WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue developing your existing applications forever.",
- "WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MINOR version (except RC or Preview versions). For example: if you are using v3.2.0 of a module, you can still get updates for v3.2.x (v3.2.1, v3.2.5... etc.) of that module. But you cannot get updates for the next major or minor version (like v3.3.0, v3.3.3, 4.x.x.. etc.). For example, when your license expired, the latest release was v4.4.3, and later, it published both 4.4.4 version and 4.5.0 version, you would be able to access the v4.4.X but you wouldn't be access the v4.5.X.",
+ "WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MINOR version (except RC or Preview versions). For example, if you are using v3.2.0 of a module, you can still get updates for v3.2.x (v3.2.1, v3.2.5... etc.) of that module. But you cannot get updates for the next major or minor version (like v3.3.0, v3.3.3, 4.x.x.. etc.). For example, when your license expired, the latest release was v4.4.3, and later, it published both 4.4.4 version and 4.5.0 version, you would be able to access the v4.4.X but you wouldn't be access the v4.5.X.",
"WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.",
"WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "You can not get the premium support anymore.",
@@ -206,9 +210,9 @@
"discountForYears": "{0}% discount for {1} year(s)",
"WhatHappensWhenLicenseEndsExplanation8": "The ABP projects you generated are not stored on our servers. Therefore, it is your responsibility to keep the source code you download. When your license expires, there's no way to get your generated ABP project source code.",
"WhenShouldIRenewMyLicense": "When should I renew my license?",
- "WhenShouldIRenewMyLicenseExplanation": "If you renew your license within {3} days after your license expires, the following discounts will be applied: Team License {0}; Business License {1}; Enterprise License {2}. However, if you renew your license after {3} days since the expiry date of your license, the renewal price will be the same as the license purchase price and there will be no discount on your renewal.",
+ "WhenShouldIRenewMyLicenseExplanation": "If you renew your license within {3} days after your license expires, the following discounts will be applied: Team License {0}; Business License {1}; Enterprise License {2}. However, if you renew your license after {3} days since the expiry date of your license, the renewal price will be the same as the license purchase price, and there will be no discount on your renewal.",
"TrialPlan": "Do you have a trial plan?",
- "TrialPlanExplanation": "Yes, to start your free trial contact marketing@volosoft.com. We also offer a 30-day money-back guarantee for the Team license, no questions asked! You can request a full refund within the first 30 days of the license purchase. We provide a 60% refund within 30 days for Business and Enterprise licenses. This is because the Business and Enterprise licenses contain the full source-code of all the modules and themes.",
+ "TrialPlanExplanation": "Yes, to start your free trial, contact marketing@volosoft.com. We also offer a 30-day money-back guarantee for the Team license, no questions asked! You can request a full refund within the first 30 days of the license purchase. We provide a 60% refund within 30 days for Business and Enterprise licenses. This is because the Business and Enterprise licenses contain the full source-code of all the modules and themes.",
"DoYouAcceptBankWireTransfer": "Do you accept bank wire transfers?",
"DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfers. After sending the license fee via bank transfer, send your receipt and requested license type to accounting@volosoft.com. Our international bank account information:",
"HowToUpgrade": "How to upgrade existing applications when a new version is available?",
@@ -224,20 +228,20 @@
"MicroserviceSupportExplanation2": "All the ABP Commercial modules are designed to support microservice deployment scenarios (with its own API and database) by following the Module Development Best Practices document.",
"MicroserviceSupportExplanation3": "We provide a sample Microservice Demo Solution that demonstrates a microservice architecture implementation to help you create your own solution.",
"MicroserviceSupportExplanation4": "So, the short answer is: \"Yes, it supports microservice architecture\".",
- "MicroserviceSupportExplanation5": "However, a microservice system is a solution and every solution will have different requirements, network topology, communication scenarios, authentication possibilities, database sharding/partitioning decisions, runtime configurations, 3rd party system integrations and many more.",
+ "MicroserviceSupportExplanation5": "However, a microservice system is a solution, and every solution will have different requirements, network topology, communication scenarios, authentication possibilities, database sharding/partitioning decisions, runtime configurations, 3rd party system integrations and many more.",
"MicroserviceSupportExplanation6": "The ABP Framework and ABP Commercial provide infrastructure for microservice scenarios, microservice compatible modules, samples and documentation to help you build your own solution. But don't expect to directly download your dream solution pre-built for you. You will need to understand it and bring specific parts together based on your requirements.",
"WhereCanIDownloadSourceCode": "Where can I download the source-code?",
"WhereCanIDownloadSourceCodeExplanation": "You can download the source code of all the ABP modules, Angular packages and themes via ABP Suite or ABP CLI. Check out How to download the source-code?",
"ComputerLimitation": "How many computers can a developer login when developing ABP?",
- "ComputerLimitationExplanation": "We specifically permit {0} computers per individual/licensed developer. Whenever there is a need for a developer to develop ABP Commercial products on a third machine, an e-mail should be sent to license@abp.io explaining the situation and we will then make the appropriate allocation in our system.",
+ "ComputerLimitationExplanation": "We specifically permit {0} computers per individual/licensed developer. Whenever there is a need for a developer to develop ABP Commercial products on a third machine, an e-mail should be sent to license@abp.io explaining the situation, and we will then make the appropriate allocation in our system.",
"RefundPolicy": "Do you have a refund policy?",
- "RefundPolicyExplanation": "You can request a refund within 30 days of your license purchase. The Business and Enterprise license types have source-code download option, therefore we provide a 60% refund within 30 days for Business and Enterprise licenses. In addition, no refunds are made for renewals and second license purchases.",
+ "RefundPolicyExplanation": "You can request a refund within 30 days of your license purchase. The Business and Enterprise license types have source-code download options; therefore, we provide a 60% refund within 30 days for Business and Enterprise licenses. In addition, no refunds are made for renewals and second license purchases.",
"HowCanIRefundVat": "How can I refund VAT?",
"HowCanIRefundVatExplanation1": "If you made the payment using 2Checkout, you can refund VAT via your 2Checkout account:",
"HowCanIRefundVatExplanation2": "Log in to your 2Checkout account",
"HowCanIRefundVatExplanation3": "Find the appropriate order and press \"Refund Belated VAT\" (enter your VAT ID)",
"HowCanIGetMyInvoice": "How can I get my invoice?",
- "HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: Iyzico and 2Checkout. If you purchase your license through the 2Checkout gateway, it sends the PDF invoice to your email address, check out 2Checkout invoicing. If you purchase through the Iyzico gateway, with a custom purchase link or via a bank wire transfer, we will prepare and send your invoice. You can request or download your invoice from the organization management page. Before contacting us for the invoice, check your organization management page!",
+ "HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: Iyzico and 2Checkout. If you purchase your license through the 2Checkout gateway, it sends the PDF invoice to your email address; check out 2Checkout invoicing. If you purchase through the Iyzico gateway, with a custom purchase link or via a bank wire transfer, we will prepare and send your invoice. You can request or download your invoice from the organization management page. Before contacting us for the invoice, check your organization management page!",
"Forum": "Forum",
"SupportExplanation": "ABP Commercial license provides a premium forum support by a team consisting of the ABP Framework experts.",
"PrivateTicket": "Private Ticket",
@@ -245,15 +249,15 @@
"AbpSuiteExplanation1": "ABP Suite allows you to build web pages in a matter of minutes. It's a .NET Core Global tool that can be installed from the command line.",
"AbpSuiteExplanation2": "It can create a new ABP solution and generate CRUD pages from the database to the front-end. For technical overview see the document",
"FastEasy": "Fast & Easy",
- "AbpSuiteExplanation3": "ABP Suite allows you to easily create CRUD pages. You just need to define your entity and its properties, and let the rest to ABP Suite for you! ABP Suite generates all the necessary code for your CRUD page in a few seconds. It supports Angular, MVC and Blazor user interfaces.",
+ "AbpSuiteExplanation3": "ABP Suite allows you to easily create CRUD pages. You just need to define your entity and its properties and let the rest go to ABP Suite for you! ABP Suite generates all the necessary code for your CRUD page in a few seconds. It supports Angular, MVC and Blazor user interfaces.",
"RichOptions": "Rich Options",
"AbpSuiteExplanation4": "ABP Suite supports multiple UI options like Razor Pages and Angular.It also supports multiple databases like MongoDB and all databases supported by EntityFramework Core (MS SQL Server, Oracle, MySql, PostgreSQL, and other providers...).",
- "AbpSuiteExplanation5": "Good thing is that, you don't have to worry about those options. ABP Suite understands your project type and generates the code for your project and places the generated code in the correct place in your project.",
+ "AbpSuiteExplanation5": "The good thing is that you don't have to worry about those options. ABP Suite understands your project type and generates the code for your project and places the generated code in the correct place in your project.",
"SourceCode": "Source Code",
"AbpSuiteExplanation6": "ABP Suite generates the source code for you! It doesn't generate magic files to generate the web page. ABP Suite generates the source code for Entity, Repository, Application Service, Code First Migration, JavaScript/TypeScript and CSHTML/HTML and necessary Interfaces as well. ABP Suite also generates the code according to the Best Practices of software development, so you don't have to worry about the generated code's quality.",
"AbpSuiteExplanation7": "Since you have the source code of the building blocks of the generated CRUD page in the correct application layers, you can easily modify the source code and inject your custom/business logic to the generated code.",
"CrossPlatform": "Cross Platform",
- "AbpSuiteExplanation8": "ABP Suite is built with .NET Core and it is cross platform. It runs as a web application on your local computer. You can run it on Windows, Mac and Linux",
+ "AbpSuiteExplanation8": "ABP Suite is built with .NET Core, and it is cross-platform. It runs as a web application on your local computer. You can run it on Windows, Mac and Linux",
"OtherFeatures": "Other Features",
"OtherFeatures1": "Updates NuGet and NPM packages on your solution easily.",
"OtherFeatures2": "Regenerates already generated pages from scratch.",
@@ -291,7 +295,7 @@
"PerpetualLicense": "Perpetual license",
"UnlimitedServerDeployment": "Unlimited server deployment",
"YearUpgrade": "1 year upgrade",
- "YearPremiumForumSupport": "1 year premium forum support",
+ "YearPremiumForumSupport": "1-year premium forum support",
"ForumSupportIncidentCountYear": "Forum support incident count/year",
"PrivateTicketEmailSupport": "Private ticket & email support",
"BuyNow": "Buy Now",
@@ -395,7 +399,7 @@
"DowngradeLicensePlan": "Can I downgrade to a lower license plan in the future?",
"DowngradeLicensePlanExplanation": "You cannot downgrade your existing license plan. But you can purchase a new lower license plan and continue your development on the new license. After you purchase a lower license, you just need to login to your new license plan via ABP CLI command: ` abp login -o `.",
"LicenseTransfer": "Can a license be transferred from one developer to another?",
- "LicenseTransferExplanation": "Yes! When you purchase a license, you become the license holder, hence you will have access to the organization management page. An organization has owner and developer roles. Owners can manage the developer seats and assign developers. Each assigned developer will login via ABP CLI command into the system and will have development and support permissions.",
+ "LicenseTransferExplanation": "Yes! When you purchase a license, you become the license holder, hence you will have access to the organization management page. An organization has owner and developer roles. Owners can manage the developer seats and assign developers. Each assigned developer will log in via ABP CLI command into the system and will have development and support permissions.",
"UserOwnerDescription": "The 'Owner' of the organization is the admin of this account. He/she manages the organization by purchasing licenses and allocating developers. An 'Owner' cannot write code in the ABP Commercial projects, cannot download the ABP sample projects, and cannot ask questions on the support website. If you want to do all these, you have to add yourself as a developer too.",
"UserDeveloperDescription": "The 'Developers' can write code in the ABP Commercial projects, download the ABP sample projects, and ask questions on the support website. On the other hand, the 'Developers' cannot manage this organization.",
"RemoveCurrentUserFromOrganizationWarningMessage": "You are removing yourself from your own organization. You will no longer be able to manage this organization, do you confirm?",
@@ -417,7 +421,7 @@
"UIFrameworks": "UI Frameworks",
"UsefulLinks": "Useful Links",
"Platform": "Platform",
- "CoolestCompaniesUseABPCommercial": "The coolest companies already use ABP Commercial.",
+ "CoolestCompaniesUseABPCommercial": "The coolest companies already use ABP Commercial.",
"UserInterface": "User Interface",
"APIGateway": "API Gateway",
"Microservice": "Microservice",
@@ -475,14 +479,14 @@
"MultipleUIOptions": "Multiple UI Options",
"MultipleUIOptionsExplanation": "We love different ways to create the User Interface. This startup solution provides three different UI framework options for your business application.",
"MultipleDatabaseOptions": "Multiple Database Options",
- "MultipleDatabaseOptionsExplanation": "You have two database provider options (in addition to using both in a single application). Use Entity Framework Core to work with any relational database and optionally use Dapper when you need to write low-level queries for a better performance. MongoDB is another option if you need to use a document based NoSQL database. While these providers are well-integrated, abstracted and pre-configured, you can actually interact to any database system that you can use with .NET.",
+ "MultipleDatabaseOptionsExplanation": "You have two database provider options (in addition to using both in a single application). Use Entity Framework Core to work with any relational database and optionally use Dapper when you need to write low-level queries for better performance. MongoDB is another option if you need to use a document-based NoSQL database. While these providers are well-integrated, abstracted and pre-configured, you can actually interact with any database system that you can use with .NET.",
"ModularArchitectureExplanation2": "Modularity is a first-class citizen in the ABP.IO platform. All the application functionalities are split into well-isolated optional modules. The startup solution already comes with the fundamental ABP Commercial modules pre-installed. You can also create your own modules to build a modular system for your own application.",
"MultiTenancyForSaasBusiness": "Multi-Tenancy for your SaaS Business",
"MultiTenancyForSaasBusinessExplanation": "ABP Commercial provides a complete, end-to-end multi-tenancy system to create your SaaS (Software-as-a-Service) systems. It allows the tenants to share or have their own databases with on-the-fly database creation and migration system.",
"MicroserviceStartupSolution": "Microservice Startup Solution",
"MicroserviceArchitectureExplanation2": "You can get it for your next microservice system to take advantage of the pre-built base solution and distilled experience.",
"PreIntegratedTools": "Pre-Integrated to popular tools",
- "PreIntegratedToolsExplanation": "The solution is already integrated to the industry-standard tools and technologies, while you can always change them and integrate to your favorite tools.",
+ "PreIntegratedToolsExplanation": "The solution is already integrated into the industry-standard tools and technologies, while you can always change them and integrate to your favorite tools.",
"SingleSignOnAuthenticationServer": "Single Sign-on Authentication Server",
"SingleSignOnAuthenticationServerExplanation": "The solution has an authentication server application that is used by the other applications as a single sign-on server with the API access management features. It is based on the IdentityServer.",
"WebAppsWithGateways": "2 Web App with 2 API Gateways",
@@ -508,7 +512,7 @@
"Note": "Note",
"AdditionalNote": "Additional Note",
"OnboardingTrainingFaqTitle": "Do you have ABP onboarding training?",
- "OnboardingTrainingFaqExplanation": "Yes, we have ABP Training Services to help you get your ABP project started fast. You will learn about ABP from an ABP core team member, and you will get the skills to begin your ABP project. In the onboarding training, we will explain how to set up your development environment, install the required tools, create a fully functional CRUD page. The training will be live and the Zoom application will be used, and we are open to using other online meeting platforms. The language of the training will be English. You can also ask your questions about ABP during the sessions. A convenient time and date will be planned for both parties. To get more information, contact us at info@abp.io.",
+ "OnboardingTrainingFaqExplanation": "Yes, we have ABP Training Services to help you get your ABP project started fast. You will learn about ABP from an ABP core team member, and you will get the skills to begin your ABP project. In the onboarding training, we will explain how to set up your development environment, install the required tools, and create a fully functional CRUD page. The training will be live, and the Zoom application will be used, we are open to using other online meeting platforms. The language of the training will be English. You can also ask your questions about ABP during the sessions. A convenient time and date will be planned for both parties. To get more information, contact us at info@abp.io.",
"AddBasket": "Add to Basket",
"SendTrainingRequest": "Send Training Request",
"OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* The English version of this document is the most up-to-date, and the English version will prevail in any dispute.",
@@ -523,25 +527,25 @@
"Pricing_Page_Hint4": "ABP Suite is a tool to assist your development to improve your productivity. It supports generating CRUD pages and creating new projects.",
"Pricing_Page_Hint5": "You can use all the pre-built modules in your applications.",
"Pricing_Page_Hint6": "You can use all the pre-built themes in your applications.",
- "Pricing_Page_Hint7": "A startup template is a Visual Studio solution to make you jump-start to your project. All fundamental modules are added and pre-configured for you.",
- "Pricing_Page_Hint8": "Mastering ABP Framework e-book explains how to implement .NET solutions with best practices. It is sold on Amazon.com and you can download the book for free with your license.",
+ "Pricing_Page_Hint7": "A startup template is a Visual Studio solution to make you jump-start your project. All fundamental modules are added and pre-configured for you.",
+ "Pricing_Page_Hint8": "Mastering ABP Framework e-book explains how to implement .NET solutions with best practices. It is sold on Amazon.com, and you can download the book for free with your license.",
"Pricing_Page_Hint9": "You can download the source-code of any module. You may want to add the source code to your solution to make radical changes or just keep it for yourself for security reasons.",
"Pricing_Page_Hint10": "Licenses are for a lifetime. That means you can continue to develop your application forever. Accessing to the latest version and getting support are granted within the license period (1 year unless you renew it).",
"Pricing_Page_Hint11": "No restrictions on deployment! You can deploy to as many servers as you want, including the cloud services or on-premises.",
- "Pricing_Page_Hint12": "You can update the modules, themes and tools to the latest version within your active license period. After your license expires, you need to renew it, to continue to get updates for bug fixes, new features and enhancements.",
+ "Pricing_Page_Hint12": "You can update the modules, themes and tools to the latest version within your active license period. After your license expires, you need to renew it to continue to get updates for bug fixes, new features and enhancements.",
"Pricing_Page_Hint13": "You can get the premium support for one year (you can renew your license to extend it).",
"Pricing_Page_Hint14": "Team and Business licenses have incident/question count limit. If you buy additional developer licenses, your incident limit increases by {0} (for the Team License) or {1} (for the Business License) per developer.",
- "Pricing_Page_Hint15": "Only Enterprise License includes private support. You can send e-mail directly to the ABP Team or ask questions on support.abp.io with a private ticket option. The private tickets are not visible to the public.",
+ "Pricing_Page_Hint15": "Only Enterprise License includes private support. You can send an e-mail directly to the ABP Team or ask questions on support.abp.io with a private ticket option. The private tickets are not visible to the public.",
"Pricing_Page_Hint16": "You can download the source-code of all ABP themes. You may want to add the source code to your solution to make radical changes or just keep it for yourself for security reasons.",
"Pricing_Page_Testimonial_1": "ABP Commercial allowed SC Ventures to deliver a bank-grade multi-tenant silo-database SaaS platform in 9 months to support the accounts receivable / accounts payable supply chain financing of significant value invoices from multiple integrated anchors. The modularity of ABP made it possible for the team to deliver in record time, pass all VAPT, and deploy the containerized microservices stack via full CI/CD and pipelines into production.",
- "Pricing_Page_Testimonial_2": "We see the value of using ABP Commercial to reduce the overhead of custom development projects. And the team is able to unify the code pattern in different project streams. We see more potential in the framework for us to build new features faster than before. We trust we will be constantly seeing the value of leveraging ABP Commercial.",
- "Pricing_Page_Testimonial_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we would have to write everything we needed on our own, we might have to spend years. Once more things we like is that the new version, or issue fixing, or improvement come out very soon every other week. We don't wait too long.",
+ "Pricing_Page_Testimonial_2": "We see the value of using ABP Commercial to reduce the overhead of custom development projects. The team is able to unify the code pattern in different project streams. We see more potential in the framework for us to build new features faster than before. We trust we will be constantly seeing the value of leveraging ABP Commercial.",
+ "Pricing_Page_Testimonial_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we had to write everything we needed on our own, we might have to spend years. One more thing we like is that the new version, issue fixing, or improvement comes out very soon every other week. We don't wait too long.",
"Pricing_Page_Testimonial_4": "ABP Commercial is a fantastic product would recommend. Commercial products to market for our customers in a single configurable platform. The jump starts that the framework and tooling provide any team is worth every cent. ABP Commercial was the best fit for our needs.",
"Pricing_Page_Testimonial_5": "ABP Framework is not only a framework, but it is also a guide for project development/management, because it provides DDD, GenericRepository, DI, Microservice, and Modularity training. Even if you are not going to use the framework itself, you can develop yourself with docs.abp.io which is well and professionally prepared (OpenIddict, Redis, Quartz etc.). Because many things are pre-built, it shortens project development time significantly (Such as login page, exception handling, data filtering, seeding, audit logging, localization, auto API controller etc.). As an example from our application, I have used Local Event Bus for stock control. So, I am able to manage order movements by writing stock handler. It is wonderful not to lose time for CreationTime, CreatorId. They are being filled automatically.",
- "Pricing_Page_Testimonial_6": "ABP Framework is a good framework but it needs time to understand the different layers, classes, and libraries it uses (specially ABP). I spent a lot of time reading the code base, but ABP Commercial saved us time to create the project specialty entities (AR) and the repository linked to each of them. I liked also the approach used in ABP is very mature, we know is based on DDD and monolith.",
- "Pricing_Page_Testimonial_7": "As a startup, we need to iterate quickly and spend minimal time on boilerplate and non-core features.\nOur engineers range from highly experienced to junior engineers, we needed a common understanding and a way to share technical and domain knowledge, ABP allowed us to do this due to their great guides and documentation. \nThere are things we haven't had to worry about since they work out of the box with ABP. \nABP helped us streamline rapid prototyping and development, less than 4 weeks from feature inception to production. With all its premium features included in the license, ABP has given us, \"Startup in a Box\" on the Software Engineering Side.",
+ "Pricing_Page_Testimonial_6": "ABP Framework is a good framework but it needs time to understand the different layers, classes, and libraries it uses (especially ABP). I spent a lot of time reading the code base, but ABP Commercial saved us time in creating the project specialty entities (AR) and the repository linked to each of them. I liked also the approach used in ABP is very mature; we know is based on DDD and monolith.",
+ "Pricing_Page_Testimonial_7": "As a startup, we need to iterate quickly and spend minimal time on boilerplate and non-core features.\nOur engineers range from highly experienced to junior engineers, and we needed a common understanding and a way to share technical and domain knowledge, ABP allowed us to do this due to their great guides and documentation. \nThere are things we haven't had to worry about since they work out of the box with ABP. \nABP helped us streamline rapid prototyping and development, less than 4 weeks from feature inception to production. With all its premium features included in the license, ABP has given us, \"Startup in a Box\" on the Software Engineering Side.",
"Pricing_Page_Testimonial_8": "I would recommend ABP commercial to all those who want to expand the range of products available to their customers. It's fantastic when need to use a distributed enterprise environment (Angular, WPF, Win&Linux). In addition to their products, we love their support, which makes our job faster and easier. We already know that we have found a great partner for the future who will support us in expanding our business.",
- "Pricing_Page_Testimonial_9": "We are a company of 2 employees that's been in business for over 20 years.\nIn terms of our experience with ABP Commercial, we were approached by a client who requested that we develop a new human resources application in a modern environment to replace their 25-year-old Access application. We decided to transition from a desktop solution to a web-based one.\n\nAt the time, we had very little knowledge of web applications and .NET but we stumbled upon ABP Commercial, and with the help of ABP Framework, technical documentation, and ABP Suite, we were able to not only develop the application to the client's specifications but also successfully work within a .NET environment within a year.",
+ "Pricing_Page_Testimonial_9": "We are a company of 2 employees that's been in business for over 20 years.\nIn terms of our experience with ABP Commercial, we were approached by a client who requested that we develop a new human resources application in a modern environment to replace their 25-year-old Access application. We decided to transition from a desktop solution to a web-based one.\n\nAt the time, we had very little knowledge of web applications and .NET, but we stumbled upon ABP Commercial, and with the help of ABP Framework, technical documentation, and ABP Suite, we were able to not only develop the application to the client's specifications but also successfully work within a .NET environment within a year.",
"AbpBookDownloadArea_ClaimYourEBook": "Claim your Mastering ABP Framework E-Book",
"AddMemberModal_Warning_1": "If the username you are trying to add doesn't exist in the system, please ask your team member to register on {0} and share the username of his/her account with you.",
"MyOrganizations_Detail_WelcomeMessage": "Welcome to your organization, {0}",
@@ -567,7 +571,7 @@
"TotalPrice": "Total Price",
"ThereIsNoInvoice": "There is no invoice",
"MyOrganizations_Detail_PaymentProviderInfo": "If you have purchased your license through {0} gateway, it sends the PDF invoice to your email address, see {0} invoicing.",
- "MyOrganizations_Detail_PayUInfo": "If you have purchased through the PayU gateway, click the \"Request Invoice\" button and fill in the billing information.",
+ "MyOrganizations_Detail_PayUInfo": "If you have purchased through the Iyzico gateway, click the \"Request Invoice\" button and fill in the billing information.",
"MyOrganizations_Detail_ConclusionInfo": "Your invoice request will be concluded within {0} business days.",
"ExtendYourLicense": "Extend your {0} license",
"Continue": "Continue",
@@ -597,7 +601,7 @@
"PaymentSucceed_ViewOrganization": "Click here to view organization",
"Purchase_TotalAnnualPrice": "TOTAL (annual fee)",
"Purchase_TrainingPrice": "Training Price",
- "Purchase_OnboardingTraining": "ABP Onboarding & Web Application Development Live Training",
+ "Purchase_OnboardingTraining": "Onboarding & Web Application Development Live Training",
"TotalDeveloperPrice": "Total Developer Price",
"Purchase_PricePerDeveloper": "{0} {1} per developer",
"Purchase_IncludedDeveloperInfo": "{0} {1} included.",
@@ -646,7 +650,7 @@
"UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.",
"UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?",
"UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "Upgrading will not extend your license expiration date!",
- "UpgradePaymentInfoSection_LicenseUpgradeDescription": "By upgrading your license, you will promote to a higher license type which will allow you to get additional benefits. See the license comparison table to check the differences between the license types.",
+ "UpgradePaymentInfoSection_LicenseUpgradeDescription": "By upgrading your license, you will be promoted to a higher license type, which will allow you to get additional benefits. See the license comparison table to check the differences between the license types.",
"Landing_Page_CustomerStories": "Customer Stories",
"Landing_Page_OurGreatCustomers": "Our Great Customers",
"Landing_Page_WebApplicationFramework": "Web Application Framework",
@@ -666,8 +670,8 @@
"Landing_Page_DocsModule": "Docs",
"Landing_Page_FileManagementModule": "File Management",
"Landing_Page_CustomerStory_1": "ABP Commercial allowed SC Ventures to deliver a bank-grade multi-tenant silo-database SaaS platform in 9 months to support the accounts receivable / accounts payable supply chain financing of significant value invoices from multiple integrated anchors. The modularity of ABP made it possible for the team to deliver in record time, pass all VAPT, and deploy the containerized microservices stack via full CI/CD and pipelines into production.",
- "Landing_Page_CustomerStory_2": "We see the value of using ABP Commercial to reduce the overhead of custom development projects. And the team can unify the code pattern in different project streams. We see more potential in the framework for us to build new features faster than before. We trust we will be constantly seeing the value of leveraging ABP Commercial.",
- "Landing_Page_CustomerStory_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we would have to write everything we needed on our own, we might have to spend years. Once more thing we like is that the new version, or issue fixing, or improvement comes out very soon\n every other week. We don't wait too long.",
+ "Landing_Page_CustomerStory_2": "We see the value of using ABP Commercial to reduce the overhead of custom development projects. The team can unify the code pattern in different project streams. We see more potential in the framework for us to build new features faster than before. We trust we will be constantly seeing the value of leveraging ABP Commercial.",
+ "Landing_Page_CustomerStory_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we had to write everything we needed on our own, we might have to spend years. One more thing we like is that the new version, or issue fixing, or improvement comes out very soon\n every other week. We don't wait too long.",
"Landing_Page_CustomerStory_4": "ABP Commercial is a fantastic product would recommend. Commercial products to market for our customers in a single configurable platform. The jump starts that the framework and tooling provide any team is worth every cent. ABP Commercial was the best fit for our needs.",
"Landing_Page_AdditionalServices": "Custom or volume license, onboarding, live training & support, custom project development, porting existing projects and more...",
"Landing_Page_IncludedDeveloperLicenses": "Included {0} developer licenses",
@@ -715,7 +719,7 @@
"Landing_Page_DocsModuleDescription_8": "Links to the file on GitHub, so anyone can easily contribute by clicking to the Edit link.",
"Landing_Page_DocsModuleDescription_9": "In addition to the GitHub source, allows to simply use a folder as the documentation source.",
"Landing_Page_FileManagementModuleDescription_1": "Upload, download and organize files in a hierarchical folder structure.",
- "Landing_Page_FileManagementModuleDescription_2": "This module is used to upload, download and organize files in a hierarchical folder structure. It is also compatible to multi-tenancy and you can determine total size limit for your tenants.",
+ "Landing_Page_FileManagementModuleDescription_2": "This module is used to upload, download and organize files in a hierarchical folder structure. It is also compatible with multi-tenancy and you can determine the total size limit for your tenants.",
"Landing_Page_FileManagementModuleDescription_3": "This module is based on the BLOB Storing system, so it can use different storage providers to store the file contents.",
"Landing_Page_IdentityModuleDescription_1": "This module implements the User and Role system of an application;",
"Landing_Page_IdentityModuleDescription_2": "Built on the Microsoft's ASP.NET Core Identity library.",
@@ -770,7 +774,7 @@
"YourFavoritePages": "Your favorite pages at your reach",
"YourFavoritePagesDescription": "Easily add or remove the page from favorites by clicking the star icon in the upper right corner of the page.",
"BreadCrumbs": "Breadcrumb for seamless switching",
- "BreadCrumbsDescription": "Using Breadcrumb, you can switch to the pages at the same level with one-click, even when the left menu is closed, and it works on tablet and mobile responsive!",
+ "BreadCrumbsDescription": "Using Breadcrumb, you can switch to the pages at the same level with one click, even when the left menu is closed, and it works on tablet and mobile responsive!",
"YourMenu": "Your menu as you wish",
"YourMenuDescription": "Customize the directly clickable icons and dropdown boxes on the user menu as you wish. The user menu is completely customizable for your needs",
"RtlSupport": "RTL support for your language",
@@ -793,10 +797,10 @@
"IndependentLayoutDescription1": "LeptonX's layout infrastructure was designed completely separate from the content.",
"IndependentLayoutDescription2": "This means that you can freely design your project with a content structure other than Bootstrap if you want.",
"MostUsedLibraries": "Most used libraries integrated with LeptonX",
- "MostUsedLibrariesDescription1": "LeptonX contains your most used libraries. It allows you to use libraries such as ApexCharts, DataTables, DropZone, FullCalender, JSTree, Select2, Toastr effortlessly.",
+ "MostUsedLibrariesDescription1": "LeptonX contains your most used libraries. It allows you to use libraries such as ApexCharts, DataTables, DropZone, FullCalender, JSTree, Select2, and Toastr effortlessly.",
"MostUsedLibrariesDescription2": "LeptonX also supports MVC Angular and Blazor-specific libraries.",
"CreateAndCustomize": "Create and customize the pages you need in seconds with LeptonX custom pages",
- "CreateAndCustomizeDescription": "By using LeptonX Theme you also have access to many pre-made html pages. These include many pages such as login page, blog, FAQ, subscription list, invoice, pricing, and file management.",
+ "CreateAndCustomizeDescription": "By using LeptonX Theme you also have access to many pre-made HTML pages. These include many pages such as login page, blog, FAQ, subscription list, invoice, pricing, and file management.",
"LeptonThemeForAdmin": "Lepton Theme for your admin dashboard by",
"LeptonThemeForAdminDescription": "Lepton Theme is still available and will be maintained. If you want to switch to LeptonX Theme as a Lepton Theme user, you can see the documentation to learn how-to.",
"LeptonCompatibleWith": "Lepton Theme is compatible with",
@@ -886,7 +890,7 @@
"DevelopYourSolution_Description5": "ABP completely automates \n unit of work (for database connection and transaction management), \n exception handling, \n validation\n and audit logging. It provides many more building blocks to simplify your daily development tasks and focus on your own code while creating production-ready \n applications.",
"DevelopYourSolution_Description6": "You can imagine how much that code block can be long and complicated if you would do it all manually.",
"SuiteCrudGenerationInFewSeconds": "In addition to hand coding your solution, you can create fully working advanced CRUD pages in a few minutes using the ABP Suite tooling. It generates the code into your solution, so you can fine-tune it based on your custom requirements.",
- "DeployAnywhere_Description1": "At the end of the day, you have a pure .NET solution. You can deploy your solution to your own server, to a cloud platform, Kubernetes or anywhere you want. You can deploy to as many servers as you want. ABP is a deployment environment agnostic tool.",
+ "DeployAnywhere_Description1": "At the end of the day, you have a pure .NET solution. You can deploy your solution to your own server, to a cloud platform, to Kubernetes or anywhere you want. You can deploy to as many servers as you want. ABP is a deployment environment agnostic tool.",
"ExpertiseAbpFramework": "Expertise the ABP Framework",
"ExpertiseAbpFramework_Description1": "Want to go beyond basics and get expertise with the ABP.IO Platform?",
"FreeDownload": "Free Download",
@@ -897,7 +901,7 @@
"OtherModules": "Other Modules",
"OtherModules_Description1": "Account, Audit Logging, Chat, CMS Kit, File Management, Forms, GDPR, Identity, Language Management, Payment, Saas and more...",
"HowItWorks_DatabaseProviderOptions": "Database provider options",
- "SeeFAQ" : "See FAQ",
+ "SeeFAQ": "See FAQ",
"ReleaseLogs": "Release Logs",
"ReleaseLogs_Tag": "{0} Release Logs",
"ReleaseLogs_Pr": "Pull Request #{0} - {1}",
@@ -937,18 +941,18 @@
"ThankYou!": "Thank you!",
"SendBetaRequest": "Send Beta Request",
"YouJoinedTheBetaTesterProgram": "You joined the ABP Studio beta tester program.",
- "PricingExplanation2": "30 days money back guarantee *. Learn more",
+ "PricingExplanation2": "30 days money back guarantee — Learn more",
"MoneyBackGuaranteeText": "* 30-day money-back guarantee on all licenses! 100% refund on Team, 60% refund on Business and Enterprise licenses within 30 days.",
"MobileApplicationStartupTemplates": "Mobile Application Startup Templates",
"MobileApplicationStartupTemplates_Description1": "Integrated mobile application startup templates for your ABP Commercial solutions.",
"CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates": "Create Powerful line-of-business Applications using ABP Mobile Startup Templates",
- "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description1": "ABP Commercial provides two mobile application startup templates implemented with React Native and .NET MAUI. When you create your new ABP based solution, you will also have basic startup applications connected to your backend APIs.",
+ "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description1": "ABP Commercial provides two mobile application startup templates implemented with React Native and .NET MAUI. When you create your new ABP-based solution, you will also have basic startup applications connected to your backend APIs.",
"CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description2": "The application has a pre-built authentication token cycle, multi-language support, multi-tenancy support, login, forgot password, profile management and a user management page. You can add your own business logic and customize it based on your requirements.",
"TwoFrameworkOptions": "Two Framework Options",
- "TwoFrameworkOptions_Description": "ABP provides both React Native and .NET MAUI mobile startup templates. This way you can choose the one that best suits your needs. Both apps reuse code at the highest rate between iOS and Android platforms.",
+ "TwoFrameworkOptions_Description": "ABP provides both React Native and .NET MAUI mobile startup templates. This way, you can choose the one that best suits your needs. Both apps reuse code at the highest rate between iOS and Android platforms.",
"PreIntegratedToYourBackend": "Pre-integrated to Your Backend",
"PreIntegratedToYourBackend_Description": "ABP Mobile applications are pre-integrated to your backend APIs. It gets a valid authentication token from the server and makes authenticated requests.",
- "MultiLanguage": "Multi - Language",
+ "MultiLanguage": "Multi-Language",
"MultiLanguage_Description": "It already supports more than 10 languages out of the box. You can also add next languages.",
"Arabic": "Arabic",
"Czech": "Czech",
@@ -966,7 +970,7 @@
"EngageAndRetainYourCustomersWithABPMobileApps_Description1": "Your customers want to manage their products and subscriptions from anywhere, anytime. That requires organizations to create mobile apps that enable customers to fulfill their requests quickly and seamlessly.",
"EngageAndRetainYourCustomersWithABPMobileApps_Description2": "With ABP Mobile apps, you can create high-quality native mobile apps for Android and iOS… Using a single codebase and without compromising on security, quality, or scalability.",
"OneCodeBaseMultipleDevices": "One Code-Base Multiple Devices",
- "OneCodeBaseMultipleDevices_Description": "ABP Mobile applications are cross-platform. They are ready to be installed and run on iOS and Android devices, and they adapt to different form-factors using a single code base. Developers only need to create the UI and front-end code once, there is no need to adapt the code for each device you want to support.",
+ "OneCodeBaseMultipleDevices_Description": "ABP Mobile applications are cross-platform. They are ready to be installed and run on iOS and Android devices, and they adapt to different form factors using a single code base. Developers only need to create the UI and front-end code once, there is no need to adapt the code for each device you want to support.",
"ComesWithTheSourceCode": "Comes with the Source-Code",
"ComesWithTheSourceCode_Description": "The mobile apps are provided with the source-code. Easily customize the UX/UI of your apps to meet branding guidelines.",
"Purchase_OneYearPrice": "1 Year Price",
@@ -974,15 +978,15 @@
"Purchase_DevelopersAlreadyIncluded": "{0} developers already included",
"1Year": "1 year",
"{0}Years": "{0} years",
- "1YearLicense": "1 year license",
- "{0}YearsLicense": "{0} years license",
- "1AdditionalDeveloper": "1 additional developer",
- "{0}AdditionalDevelopers": "{0} additional developers",
+ "1YearLicense": "1 Year License",
+ "{0}YearsLicense": "{0} Years License",
+ "1AdditionalDeveloper": "1 Additional Developer",
+ "{0}AdditionalDevelopers": "{0} Additional Developers",
"Discount": "Discount ({0}%)",
"Summary": "Summary",
"TrainingPack": "Training pack",
"TrainingPackDiscount": "Training pack discount",
- "Purchase_OnboardingTraining_Description": "This live training package is discounted when purchase with the new license. This discounted price is valid only for new license purchases. Learn more ",
+ "Purchase_OnboardingTraining_Description": "This live training package is valid for a class of 8 students and this discount is only valid when purchased with the new license. Learn more ",
"Purchase_Save": "{0}% Save {1} {2}",
"RemoveBasket": "Remove from basket",
"WhyABPIOPlatform?": "Why ABP.IO Platform?",
@@ -1001,35 +1005,35 @@
"ABPSOLUTION": "ABP SOLUTION",
"CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP provides a well-architected, layered and production-ready startup solution based on the Domain Driven Design principles. The solution also includes a pre-configured unit and integration test projects for each layer.",
"CommonLibraries": "Common Libraries",
- "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.",
- "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates the popular, mature and up-to-date libraries into the solution. You don't spend time integrating them and talking to each other. They properly work out of the box.",
+ "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic, making it challenging to keep up with the latest tools, libraries, trends, and approaches.",
+ "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates popular, mature, and up-to-date libraries into the solution. You don't need to spend time integrating them or making them communicate with each other. They work properly out of the box.",
"UITheme&Layout": "UI Theme & Layout",
- "UITheme&Layout_THEPROBLEM_Description": "When it comes to the UI, there are a lot of challenges, including preparing a foundation to create a responsive, modern and flexible UI kit with a consistent look & feel and tons of features (like left/top navigation menu, header, toolbar, footer, widgets and so.).",
- "UITheme&Layout_THEPROBLEM_Description2": "Even if you buy a pre-built theme, integrating it into your solution may take days of development. Upgrading such a theme is another problem. Most of the time, the theme's HTML/CSS structure is mixed with your UI code, and it is not easy to upgrade or change the theme later.",
- "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework provides a theming system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern themes.",
- "UITheme&Layout_ABPSOLUTION_Description2": "There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.",
+ "UITheme&Layout_THEPROBLEM_Description": "When addressing UI concerns, a range of challenges surfaces. These include establishing the groundwork for a responsive, contemporary, and adaptable UI kit with a consistent appearance and a host of features like navigation menus, headers, toolbars, footers, widgets, and more.",
+ "UITheme&Layout_THEPROBLEM_Description2": "Even if you opt for a pre-designed theme, seamlessly integrating it into your project could demand days of development. An additional hurdle lies in upgrading such themes. Frequently, the theme's HTML/CSS structure becomes intertwined with your UI code, rendering future theme changes or upgrades intricate tasks. This interweaving of code and design complicates the flexibility of making adjustments down the line.",
+ "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework offers a distinctive theming system that liberates your UI code from theme constraints. Themes exist in isolation, packaged as NuGet or NPM packages, making theme installation or upgrades a matter of minutes. While you retain the option to develop your custom theme or integrate an existing one, ABP Commercial presents a collection of polished and contemporary themes.",
+ "UITheme&Layout_ABPSOLUTION_Description2": "Additionally, there are UI component providers like Telerik and DevExpress. However, these providers primarily furnish individual components, placing the onus on you to establish your layout system. When working within ABP-based projects, you can seamlessly incorporate these libraries, similar to how you would in any other project.",
"TestInfrastructure": "Test Infrastructure",
- "TestInfrastructure_THEPROBLEM_Description": "Preparing a robust test environment takes time. You need to setup test projects in your solution, select the tools, mock the services and database, create the required base classes and utility services to reduce repeating code in the tests and so on.",
- "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1.",
+ "TestInfrastructure_THEPROBLEM_Description": "Establishing a robust testing environment is a time-consuming endeavor. It involves setting up dedicated test projects within your solution, carefully selecting the necessary tools, creating service and database mocks, crafting essential base classes and utility services to minimize redundant code across tests, and addressing various related tasks.",
+ "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates arrive pre-equipped with configured test projects, streamlining the process for you. This means that from day one, you can readily commence writing your initial unit or integration test code without delay.",
"CodingStandards&Training": "Coding Standards & Training",
- "CodingStandards&Training_THEPROBLEM_Description": "Once you create the development-ready solution, you typically need to train the developers to explain the system and develop it with the same conventions in a standard and consistent way. Even if you train the developers, it is hard to prepare and maintain your documentation. Over time, every developer will write the code differently, and coding standards will begin to diverge.",
- "CodingStandards&Training_ABPSOLUTION_Description": "ABP solution is already well-defined and well-documented. Tutorials and best practice guides clearly explain how to make development on an ABP project.",
+ "CodingStandards&Training_THEPROBLEM_Description": "After you've set up the solution for development, you usually have to teach the developers how the system works and how to build it using the same agreed-upon methods. Even if you give them training, keeping the documentation up-to-date can be difficult. As time goes on, each developer might write code in their own way, causing the rules for writing code to become different from each other.",
+ "CodingStandards&Training_ABPSOLUTION_Description": "The ABP solution is already neatly organized and has clear explanations. Step-by-step tutorials and guides show you exactly how to work on an ABP project.",
"KeepingYourSolutionUpToDate": "Keeping Your Solution Up to Date",
"KeepingYourSolutionUpToDate_THEPROBLEM_Description": "After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches.",
"KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.",
"KeepingYourSolutionUpToDate_ABPSOLUTION_Description2": "Abp updateCLI command automatically discovers and upgrades all ABP-dependant NuGet and NPM packages in a solution. With ABP, it is easier to stay with the latest versions.",
"DRY": "Don't Repeat Yourself!",
- "DRY_Description": "Creating a base solution takes significant time and requires well architectural experience. However, this is just the beginning! As you start developing, you will likely have to write lots of repetitive code; that would be great if all this could be handled automatically.",
+ "DRY_Description": "Creating a base solution takes significant time and requires good architectural experience. However, this is just the beginning! As you start developing, you will likely have to write lots of repetitive code; that would be great if all this could be handled automatically.",
"DRY_Description2": "ABP automates and simplifies repeating code as much as possible by following the convention over configuration principle. However, it doesn't restrict you when you need to switch to manual gear. The control is always in your hands.",
"Authentication": "Authentication",
- "Authentication_THEPROBLEM_Description": "Single Sign On, Active Directory / LDAP Integration, OpenIddict integration, social logins, two-factor authentication, forgot/reset password, email activation, new user registration, password complexity control, locking account on failed attempts, showing failed login attemps ... etc. We know that all these generic requirements are familiar to you. You are not alone!",
+ "Authentication_THEPROBLEM_Description": "Single Sign On, Active Directory / LDAP Integration, OpenIddict integration, social logins, two-factor authentication, forgot/reset password, email activation, new user registration, password complexity control, locking account on failed attempts, showing failed login attempts... etc. We know that all these generic requirements are familiar to you. You are not alone!",
"Authentication_ABPSOLUTION_Description": "ABP Framework and the commercial version provide all these standard stuff pre-implemented for you as a re-usable account module. You just enable and configure what you need.",
"CrossCuttingConcerns": "Cross-Cutting Concerns",
- "CrossCuttingConcerns_THEPROBLEM_Description": "Cross-Cutting Concerns are the fundamental repeating logic that should be implementedfor each use case. Some examples;",
+ "CrossCuttingConcerns_THEPROBLEM_Description": "Cross-Cutting Concerns are the fundamental repeating logic that should be implemented for each use case. Some examples;",
"CrossCuttingConcerns_THEPROBLEM_Description2": "Starting transactions, committing on success and rollback on errors.",
- "CrossCuttingConcerns_THEPROBLEM_Description3": "Handling and reporting exceptions, returning a proper error response to the clients and handling error cases on the client-side.",
- "CrossCuttingConcerns_THEPROBLEM_Description4": "Implementing authorization and validation, returning proper responses and handling these on the client-side.",
- "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP Framework automates or simplifies all the common cross-cutting concerns. You only write code that matters for your business and ABP handles the rest by conventions.",
+ "CrossCuttingConcerns_THEPROBLEM_Description3": "Handling and reporting exceptions, returning a proper error response to the clients and handling error cases on the client side.",
+ "CrossCuttingConcerns_THEPROBLEM_Description4": "Implementing authorization and validation, returning proper responses and handling these on the client side.",
+ "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP Framework automates or simplifies all the common cross-cutting concerns. You only write code that matters for your business, and ABP handles the rest by conventions.",
"ArchitecturalInfrastructure": "Architectural Infrastructure",
"ArchitecturalInfrastructure_THEPROBLEM_Description": "You typically need to build infrastructure to implement your architecture properly. For example, you generally implement the Repository pattern. You define some base classes to simplify and standardize to create entities, services, controllers and other objects.",
"ArchitecturalInfrastructure_ABPSOLUTION_Description": "ABP Framework provides all these and more out of the box. It is mature and well-documented.",
@@ -1042,37 +1046,45 @@
"EnterpriseApplicationRequirements_THEPROBLEM_Description6": "Enqueuing and executing background jobs.",
"EnterpriseApplicationRequirements_THEPROBLEM_Description7": "Handling multiple time zones in a global system.",
"EnterpriseApplicationRequirements_THEPROBLEM_Description8": "Sharing validation, localization, authorization logic between server and client.",
- "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "ABP provides infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.",
+ "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "ABP provides an infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.",
"GeneratingInitialCode&Tooling": "Generating Initial Code & Tooling",
- "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "You will build many similar pages in a typical web application. Most of them will perform similar CRUD operations. It is very tedious and also error prone to repeatedly create such pages.",
+ "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "You will build many similar pages in a typical web application. Most of them will perform similar CRUD operations. It is very tedious and also error-prone to repeatedly create such pages.",
"GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Suite can generate a full-stack CRUD page for your entities in seconds. The generated code is layered and clean. All the standard validation and authorization requirements are implemented. Plus, unit test classes are generated. Once you get a fully running page, you can modify it according to your business requirements.",
"IntegratingTo3rdPartyLibrariesAndSystems": "Integrating to 3rd-Party Libraries and Systems",
- "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "Most libraries are designed as low level, and you typically do some work to integrate them properly without repeating the same integration and configuration code everywhere in your solution. For example, assume you must use RabbitMQ to implement your distributed event bus. All you want to do is; send a message to a queue and handle the incoming messages. But you need to understand messaging patterns, queue and exchange details. To write an efficient code, you must create a pool to manage connections, clients and channels. You also must deal with exceptions, ACK messages, re-connecting to RabbitMQ on failures and more.",
+ "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "Most libraries are designed as low level, and you typically do some work to integrate them properly without repeating the same integration and configuration code everywhere in your solution. For example, assume you must use RabbitMQ to implement your distributed event bus. All you want to do is; send a message to a queue and handle the incoming messages. But you need to understand messaging patterns, queues and exchange details. To write efficient code, you must create a pool to manage connections, clients and channels. You also must deal with exceptions, ACK messages, re-connecting to RabbitMQ on failures and more.",
"IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "For example, ABP's RabbitMQ Distributed Event Bus integration abstracts all these details. You send and receive messages without the hustle and bustle. Do you need to write low-level code? No problem, you can always do that. ABP doesn't restrict you when you need to use low-level features of the library you are using.",
"WhyNotBuildYourOwnFramework?": "Why Not Build Your Own Framework?",
- "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "All the infrastructure, even in the most simple way, takes a lot of time to build, maintain and document. It gets bigger over time, and it becomes hard to maintain it in your solution. Separating these into a re-usable project is the starting point for building your own internal framework.",
+ "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "All the infrastructure, even in the simplest way, takes a lot of time to build, maintain and document. It gets bigger over time, and it becomes hard to maintain it in your solution. Separating these into a re-usable project is the starting point for building your own internal framework.",
"WhyNotBuildYourOwnFramework_THEPROBLEM_Description2": "Building, documenting, training and maintaining an internal framework is really hard. If you don't have an experienced, dedicated framework team, your internal framework rapidly becomes an undocumented legacy code that no one can understand and maintain anymore. On the other hand, these frameworks are generally developed by one or two developers in the team. And these fellows are becoming a knowledge silo. It is good for them but bad for the company because they are the project's single point of failure -SPOF-. Once they leave the company, the project dramatically goes down.",
"WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "ABP Framework is a community-driven, well-documented, mature and generic application framework. A team of highly experienced developers are working hard to keep it up-to-date, easy to understand and comfortable to use. Using such a stable framework makes you focus on your own business code and get help with the framework from experts whenever you need it.",
- "ArchitecturalInfrastructure_Description": "SaaS applications, modular or microservice systems are most used enterprise software models. Building such systems not only requires a good understanding and experience, but also requires a strong software infrastructure. Otherwise, you will find yourself spending a great effort to support these architectural details in your codebase.",
+ "ArchitecturalInfrastructure_Description": "SaaS applications, modular or microservice systems are most used enterprise software models. Building such systems not only requires a good understanding and experience but also requires a strong software infrastructure. Otherwise, you will find yourself spending a great effort to support these architectural details in your codebase.",
"Modularity": "Modularity",
"Modularity_THEPROBLEM_Description": "Building a truly modular system is not easy! All the aspects of the system (database, entities, APIs, UI pages/components) can be split into modules, and each module can be re-usable without others. The plain ASP.NET Core doesn't provide such a modular architecture. If you need it, you should think about it from scratch.",
"Modularity_ABPSOLUTION_Description": "The ABP Framework is born to be a modular application development structure. Every feature in the framework is developed to be compatible with modularity. Documentation and guides explain how to develop re-usable modules in a standard way.",
"SaaSMultiTenancy": "SaaS / Multi-Tenancy",
"SaaSMultiTenancy_THEPROBLEM_Description": "Multi-Tenancy is a common way to implement SaaS systems. However, implementing a consistent multi-tenant infrastructure may become complicated.",
- "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP Framework provides a complete multi-tenant infrastructure and abstract complexity from your business code. Your application code will be mostly multi-tenancy aware while the ABP Framework automatically isolates the database, cache and other details of the tenants from each other. It supports single database, per tenant database and hybrid approaches. It properly configures the libraries like Microsoft Identity and OpenIddict, which are not normally multi-tenancy compatible.",
+ "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP Framework provides a complete multi-tenant infrastructure and abstract complexity from your business code. Your application code will be mostly multi-tenancy aware, while the ABP Framework automatically isolates the database, cache and other details of the tenants from each other. It supports single database, per tenant database and hybrid approaches. It properly configures the libraries like Microsoft Identity and OpenIddict, which are not normally multi-tenancy compatible.",
"Microservices": "Microservices",
"Microservices_THEPROBLEM_Description": "Building a microservice system requires many infrastructure details: Authenticating and authorizing applications and microservices and implementing asynchronous messaging and synchronous (Rest/GRPC) communication patterns between microservices are the most fundamental issues.",
"Microservices_ABPSOLUTION_Description": "The ABP Framework provides services, guides, and samples to help you implement your microservice solution using the industry standard tools.",
"Microservices_ABPSOLUTION_Description2": "ABP Commercial even goes one step further and provides a complete startup template to kick-start your microservice solution.",
"PreBuiltModules": "Pre-Built Modules",
"PreBuiltModules_THEPROBLEM_Description": "All of us have similar but slightly different business requirements. However, we all should re-invent the wheel since no one's code can directly work in our solution. They are all embedded parts of a larger solution.",
- "PreBuiltModules_ABPSOLUTION_Description":"ABP Commercial modules provides a lot of re-usable application modules like payment, chat, file management, audit log reporting... etc. All of these modules are easily installed into your solution and directly work. We are constantly adding more modules.",
+ "PreBuiltModules_ABPSOLUTION_Description": "ABP Commercial modules provides a lot of re-usable application modules like payment, chat, file management, audit log reporting... etc. All of these modules are easily installed into your solution and directly work. We are constantly adding more modules.",
"PreBuiltModules_ABPSOLUTION_Description2": "All modules are designed as customizable for your business requirements. If you need complete control, you can download the full source code of any module and completely customize based on your specific business requirements.",
"ABPCommunity": "ABP Community",
- "ABPCommunity_Description": "Finally, Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with more then 10K stars on GitHub.",
+ "ABPCommunity_Description": "Finally, Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with more than 10K stars on GitHub.",
"ABPCommunity_Description2": "It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.",
"ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time.",
"WhyAbpIo_Page_Title": "Why ABP.IO Platform?",
- "AbpStudio_Page_Title": "ABP Studio"
+ "AbpStudio_Page_Title": "ABP Studio",
+ "CampaignInfo": "Buy a new license or renew your existing license and get an additional 2 months at no additional cost! This offer is valid for all license plans. Ensure you take advantage of this limited-time promotion to expand your access to premium features and upgrades.",
+ "HurryUpLastDay": "Hurry Up! Last Day: {0}",
+ "CreatingCRUDPagesWithABPSuite": "Creating CRUD pages with ABP Suite",
+ "Testimonials": "Testimonials",
+ "MultipleYearDiscount": "Multiple Year Discount",
+ "CampaignDiscountText": "Black Friday Discount",
+ "CampaignDiscountName": "Black Friday",
+ "CampaignName:BlackFriday": "Black Friday"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
index 88ce642703..0d211064d7 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " Una plataforma de desarrollo web completa integrada marco ",
"AbpCommercialShortDescription": "ABP Commercial proporciona módulos de aplicaciones prediseñados, herramientas de desarrollo rápido de aplicaciones, temas de interfaz de usuario profesionales, soporte premium y más.",
"LiveDemo": "Demo en vivo",
+ "LiveDemoLead": "{1} usando su cuenta ABP, {3} a abp.io. O complete el siguiente formulario para crear una demostración en vivo ahora",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Ya existe una cuenta con la dirección de correo electrónico especificada: {0} Puede iniciar sesión con su cuenta para continuar.",
"GetLicence": "Obtener una licencia",
"Application": "Solicitud",
"StartupTemplates": "Plantillas de inicio",
@@ -129,12 +131,14 @@
"YourFullName": "Tu nombre completo",
"EmailField": "Dirección de correo electrónico",
"YourEmailAddress": "Tu correo electrónico",
+ "ValidEmailAddressIsRequired": "Se requiere una dirección de correo electrónico válida.",
"HowMayWeHelpYou": "¿Cómo podemos ayudarle?",
"SendMessage": "Enviar mensaje",
"Success": "Éxito",
"WeWillReplyYou": "Recibimos su mensaje y nos pondremos en contacto a la brevedad.",
"GoHome": "Vete a casa",
"CreateLiveDemo": "Crear demostración en vivo",
+ "CreateLiveDemoDescription": "Una vez que envíe este formulario, recibirá un correo electrónico con el enlace de su demostración.",
"RegisterToTheNewsletter": "Regístrese para recibir el boletín informativo para recibir información sobre ABP.IO, incluidos nuevos lanzamientos, etc.",
"EnterYourEmailOrLogin": "Ingrese su dirección de correo electrónico para crear su demostración o Iniciar sesión con su cuenta existente.",
"ApplicationTemplate": "Plantilla de aplicación",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
index 3e1b92ff90..cb94010c0e 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
@@ -49,6 +49,8 @@
"IndexPageHeroSection": " Täydellinen verkkokehitysympäristö sisäänrakennettu kehys ",
"AbpCommercialShortDescription": "ABP Commercial tarjoaa valmiita sovellusmoduuleja, nopean sovelluskehitystyökalun, ammattimaiset käyttöliittymäteemat, ensiluokkaisen tuen ja paljon muuta.",
"LiveDemo": "Live-esittely",
+ "LiveDemoLead": "{1} käyttämällä ABP-tiliäsi, {3} abp.io: lle. Tai täytä alla oleva lomake luodaksesi live-esittelyn nyt",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Sähköpostiosoitteella {0} on jo tili. Voit kirjautua sisään tilillesi jatkaaksesi.",
"GetLicence": "Hanki lisenssi",
"Application": "Sovellus",
"StartupTemplates": "Käynnistysmallit",
@@ -132,12 +134,14 @@
"LastNameField": "Sukunimi",
"EmailField": "Sähköpostiosoite",
"YourEmailAddress": "Sähköpostiosoitteesi",
+ "ValidEmailAddressIsRequired": "Kelvollinen sähköpostiosoite vaaditaan",
"HowMayWeHelpYou": "Kuinka voimme auttaa sinua?",
"SendMessage": "Lähetä viesti",
"Success": "Menestys",
"WeWillReplyYou": "Saimme viestisi ja otamme sinuun pian yhteyttä.",
"GoHome": "Mene kotiin",
"CreateLiveDemo": "Luo live-esittely",
+ "CreateLiveDemoDescription": "Kun lähetät tämän lomakkeen, saat sähköpostin, jossa on linkki demoosi.",
"RegisterToTheNewsletter": "Rekisteröidy uutiskirjeeseen saadaksesi tietoa ABP.IO: sta, mukaan lukien uudet julkaisut jne.",
"EnterYourEmailOrLogin": "Kirjoita sähköpostiosoitteesi luodaksesi esittely tai kirjaudu sisään nykyisellä tililläsi.",
"ApplicationTemplate": "Sovelluksen malli",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
index 0588062ad8..3f3be7d3be 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Une plate-forme de développement Web complète intégrée cadre ",
"AbpCommercialShortDescription": "ABP Commercial fournit des modules d'application prédéfinis, des outils de développement rapide d'applications, des thèmes d'interface utilisateur professionnels, un support premium et plus encore.",
"LiveDemo": "Démo en direct",
+ "LiveDemoLead": "{1} en utilisant votre compte ABP, {3} à abp.io. Ou remplissez le formulaire ci-dessous pour créer une démo en direct maintenant",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Il existe déjà un compte avec l'adresse e-mail fournie: {0} Vous pouvez vous connecter avec votre compte pour continuer.",
"GetLicence": "Obtenez une licence",
"Application": "Application",
"StartupTemplates": "Modèles de démarrage",
@@ -129,12 +131,14 @@
"YourFullName": "Votre nom complet",
"EmailField": "Adresse e-mail",
"YourEmailAddress": "Votre adresse email",
+ "ValidEmailAddressIsRequired": "Une adresse e-mail valide est requise.",
"HowMayWeHelpYou": "Comment pouvons nous vous aider?",
"SendMessage": "Envoyer le message",
"Success": "Succès",
"WeWillReplyYou": "Nous avons reçu votre message et vous contacterons sous peu.",
"GoHome": "Retour à l'acceuil",
"CreateLiveDemo": "Créer une démo en direct",
+ "CreateLiveDemoDescription": "Une fois que vous avez soumis ce formulaire, vous recevrez un e-mail contenant le lien de votre démo.",
"RegisterToTheNewsletter": "Inscrivez-vous à la newsletter pour recevoir des informations concernant ABP.IO, y compris les nouvelles versions, etc.",
"EnterYourEmailOrLogin": "Saisissez votre adresse e-mail pour créer votre démo ou Connectez-vous à l'aide de votre compte existant.",
"ApplicationTemplate": "Modèle d'application",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
index 2d16ac121d..935c1b12d0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "एक पूर्ण वेब डेवलपमेंट प्लेटफॉर्मबिल्ट-ऑन Framework",
"AbpCommercialShortDescription": "एबीपी कमर्शियल प्री-बिल्ट एप्लिकेशन मॉड्यूल, रैपिड एप्लिकेशन डेवलपमेंट टूलिंग, पेशेवर यूआई थीम, प्रीमियम सपोर्ट आदि प्रदान करता है।",
"LiveDemo": "लाइव डेमो",
+ "LiveDemoLead": "{1} अपने एबीपी खाते का उपयोग करते हुए, {3} abp.io पर आपका स्वागत है। या अब एक लाइव डेमो बनाने के लिए नीचे दिए गए फॉर्म को भरें",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "दिए गए ईमेल पते {0} के साथ पहले से ही एक खाता है। आप अपने खाते से लॉगिन करके आगे बढ़ सकते हैं।",
"GetLicence": "एक लाइसेंस प्राप्त करें",
"Application": "आवेदन",
"StartupTemplates": "स्टार्टअप टेम्पलेट",
@@ -129,12 +131,14 @@
"YourFullName": "आपका पूरा नाम",
"EmailField": "ईमेल पता",
"YourEmailAddress": "आपका ईमेल पता",
+ "ValidEmailAddressIsRequired": "एक वैध ईमेल पता आवश्यक है।",
"HowMayWeHelpYou": "हम कैसे आपकी सहायता कर सकते हैं?",
"SendMessage": "मेसेज भेजें",
"Success": "सफलता",
"WeWillReplyYou": "हमें आपका संदेश प्राप्त हुआ और शीघ्र ही संपर्क में आएगा।",
"GoHome": "घर जाओ",
"CreateLiveDemo": "लाइव डेमो बनाएँ",
+ "CreateLiveDemoDescription": "एक बार जब आप इस फॉर्म को जमा करते हैं, तो आपको अपने डेमो लिंक को समेत एक ईमेल प्राप्त होगा।",
"RegisterToTheNewsletter": "ABP.IO के बारे में जानकारी प्राप्त करने के लिए न्यूज़लेटर के लिए रजिस्टर करें, जिसमें नई रिलीज़ आदि शामिल हैं।",
"EnterYourEmailOrLogin": "अपना डेमो बनाने के लिए अपना ई-मेल पता दर्ज करें या अपने मौजूदा खाते का उपयोग करके लॉगिन करें।",
"ApplicationTemplate": "एप्लिकेशन टेम्पलेट",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
index 351a468fe4..03cd52cbca 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
@@ -49,6 +49,8 @@
"IndexPageHeroSection": "Teljes webfejlesztői platformbeépített keretrendszer",
"AbpCommercialShortDescription": "Az ABP Commercial előre beépített alkalmazásmodulokat, gyors alkalmazásfejlesztési eszközöket, professzionális felhasználói felületi témákat, prémium támogatást és még sok mást kínál.",
"LiveDemo": "Élő Demo",
+ "LiveDemoLead": "{1} az ABP-fiókjával, {3} az abp.io-ra. Vagy töltse ki az alábbi űrlapot, hogy most létrehozzon egy élő bemutatót",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Már van fiók a megadott e-mail címmel: {0} Bejelentkezhet a fiókjával a folytatáshoz.",
"GetLicence": "Szerezzen engedélyt",
"Application": "Alkalmazás",
"StartupTemplates": "Indítási sablonok",
@@ -132,12 +134,14 @@
"LastNameField": "Vezetéknév",
"EmailField": "Email cím",
"YourEmailAddress": "Az email címed",
+ "ValidEmailAddressIsRequired": "Érvényes e-mail cím szükséges",
"HowMayWeHelpYou": "Hogyan segíthetünk?",
"SendMessage": "Üzenet küldése",
"Success": "Siker",
"WeWillReplyYou": "Megkaptuk üzenetét, és hamarosan felvesszük Önnel a kapcsolatot.",
"GoHome": "Hazamenni",
"CreateLiveDemo": "Élő bemutató létrehozása",
+ "CreateLiveDemoDescription": "Miután elküldte ezt a űrlapot, e-mailt kap, amely tartalmazza a bemutató linkjét.",
"RegisterToTheNewsletter": "Regisztráljon a hírlevélre, hogy információkat kapjon az ABP.IO-ról, beleértve az új kiadásokat stb.",
"EnterYourEmailOrLogin": "Adja meg e-mail címét a bemutató létrehozásához, vagy jelentkezzen be meglévő fiókjával.",
"ApplicationTemplate": "Alkalmazássablon",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
index ff0c6cc417..c125ce7d3e 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Heilstætt vefþróunar umhverfi byggt á ABP",
"AbpCommercialShortDescription": "ABP Commercial býður upp á forsmíðaðar forritareiningar, tól sem hraða þróun, fagmanlega hannaðar UI þemur, úrvals stuðning og fleira.",
"LiveDemo": "Virkt sýnidæmi",
+ "LiveDemoLead": "{1} með þínum ABP reikningi, {3} til abp.io. Eða fylltu út formið hér að neðan til að búa til virkt sýnidæmi núna",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Það er nú þegar reikningur með þessu netfangi: {0} Þú getur skráð þig inn með þínum reikningi til að halda áfram.",
"GetLicence": "Sækja Leyfi",
"Application": "Umsókn",
"StartupTemplates": "Byrjunar Sniðmát",
@@ -129,12 +131,14 @@
"YourFullName": "Þitt fulla nafn",
"EmailField": "Netfang",
"YourEmailAddress": "Netfangið þitt",
+ "ValidEmailAddressIsRequired": "Netfangið þarf að vera gilt.",
"HowMayWeHelpYou": "Hvernig getum við aðstoðað þig?",
"SendMessage": "Senda skilaboð",
"Success": "Heppnaðist",
"WeWillReplyYou": "Við höfum móttekið skilaboðin þín og munum hafa samband innan tíðar.",
"GoHome": "Fara heim",
"CreateLiveDemo": "Búa til Live Demo",
+ "CreateLiveDemoDescription": "Þegar þú sendir þetta form, færðu tölvupóst sem inniheldur tengilinn þinn.",
"RegisterToTheNewsletter": "Skráning á póstlista fyrir fréttabréf með upplýsingum um ABP.IO, þ.á.m. nýjar útgáfur o.s.frv..",
"EnterYourEmailOrLogin": "Settu inn netfangið þitt til að búa til kynningu eða Login með þínum notandareikningi.",
"ApplicationTemplate": "Forritssniðmát",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
index ccd74fd005..a1e06f4a06 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " Una completa piattaforma di sviluppo web integrata framework ",
"AbpCommercialShortDescription": "ABP Commercial fornisce moduli applicativi predefiniti, strumenti per lo sviluppo rapido di applicazioni, temi dell'interfaccia utente professionale, supporto premium e altro ancora.",
"LiveDemo": "Dimostrazione dal vivo",
+ "LiveDemoLead": "{1} utilizzando il tuo account ABP, {3} a abp.io. O compilare il modulo sottostante per creare una demo live ora",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Esiste già un account con l'indirizzo email specificato: {0} Puoi accedere con il tuo account per procedere.",
"GetLicence": "Ottieni una licenza",
"Application": "Applicazione",
"StartupTemplates": "Modelli di avvio",
@@ -129,12 +131,14 @@
"YourFullName": "Il tuo nome completo",
"EmailField": "Indirizzo e-mail",
"YourEmailAddress": "Il tuo indirizzo di posta elettronica",
+ "ValidEmailAddressIsRequired": "È richiesto un indirizzo email valido.",
"HowMayWeHelpYou": "Come possiamo aiutarti?",
"SendMessage": "Invia messaggio",
"Success": "Successo",
"WeWillReplyYou": "Abbiamo ricevuto il tuo messaggio e ti contatteremo a breve.",
"GoHome": "Torna all'inizio",
"CreateLiveDemo": "Crea demo live",
+ "CreateLiveDemoDescription": "Una volta inviato questo modulo, riceverai un'e-mail contenente il link alla tua demo.",
"RegisterToTheNewsletter": "Registrati alla newsletter per ricevere informazioni su ABP.IO, comprese le nuove versioni ecc.",
"EnterYourEmailOrLogin": "Inserisci il tuo indirizzo e-mail per creare la tua demo o Accedi utilizzando il tuo account esistente.",
"ApplicationTemplate": "Modello di applicazione",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
index cc7a076848..a1b445a81c 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Een compleet webontwikkelingsplatformingebouwd raamwerk",
"AbpCommercialShortDescription": "ABP Commercial biedt kant-en-klare applicatiemodules, tooling voor snelle applicatieontwikkeling, professionele UI-thema's, premium ondersteuning en meer.",
"LiveDemo": "Live demonstratie",
+ "LiveDemoLead": "{1} met behulp van uw ABP-account, {3} naar abp.io. Of vul het onderstaande formulier in om nu een live demo te maken",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Er is al een account met het opgegeven e-mailadres: {0} U kunt inloggen met uw account om door te gaan.",
"GetLicence": "Verkrijg een licentie",
"Application": "Sollicitatie",
"StartupTemplates": "Opstartsjablonen",
@@ -129,12 +131,14 @@
"YourFullName": "Je volledige naam",
"EmailField": "E-mailadres",
"YourEmailAddress": "Jouw e-mailadres",
+ "ValidEmailAddressIsRequired": "Een geldig e-mailadres is vereist.",
"HowMayWeHelpYou": "Hoe kunnen we je helpen?",
"SendMessage": "Bericht versturen",
"Success": "Succes",
"WeWillReplyYou": "We hebben uw bericht ontvangen en nemen spoedig contact met u op.",
"GoHome": "Ga naar huis",
"CreateLiveDemo": "Live demo maken",
+ "CreateLiveDemoDescription": "Zodra u dit formulier indient, ontvangt u een e-mail met uw demolink.",
"RegisterToTheNewsletter": "Schrijf je in voor de nieuwsbrief om informatie over ABP.IO te ontvangen, inclusief nieuwe releases etc.",
"EnterYourEmailOrLogin": "Voer uw e-mailadres in om uw demo te maken of Log in met uw bestaande account.",
"ApplicationTemplate": "Toepassingssjabloon",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
index 4aa4f6616f..ed08bb1583 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial zapewnia gotowe moduły aplikacji, narzędzia do szybkiego tworzenia aplikacji, profesjonalne motywy interfejsu użytkownika, wsparcie premium i nie tylko.",
"LiveDemo": "Demo na żywo",
+ "LiveDemoLead": "{1} korzystając z konta ABP, {3} to abp.io. Lub wypełnij poniższy formularz, aby utworzyć teraz demo na żywo",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Istnieje już konto o podanym adresie e-mail: {0} Możesz się zalogować na swoje konto, aby kontynuować.",
"GetLicence": "Uzyskaj licencję",
"Application": "Podanie",
"StartupTemplates": "Szablony startowe",
@@ -129,12 +131,14 @@
"YourFullName": "Twoje pełne imię",
"EmailField": "Adres e-mail",
"YourEmailAddress": "Twój adres email",
+ "ValidEmailAddressIsRequired": "Wymagany jest prawidłowy adres e-mail.",
"HowMayWeHelpYou": "Jak możemy Ci pomóc?",
"SendMessage": "Wyślij wiadomość",
"Success": "Powodzenie",
"WeWillReplyYou": "Otrzymaliśmy Twoją wiadomość i wkrótce się z Tobą skontaktujemy.",
"GoHome": "Idź do domu",
"CreateLiveDemo": "Utwórz demo na żywo",
+ "CreateLiveDemoDescription": "Po wysłaniu tego formularza otrzymasz e-mail z linkiem do swojego demo.",
"RegisterToTheNewsletter": "Zarejestruj się do newslettera, aby otrzymywać informacje dotyczące ABP.IO, w tym nowości itp.",
"EnterYourEmailOrLogin": "Wprowadź swój adres e-mail, aby utworzyć demo lub Zaloguj się przy użyciu istniejącego konta.",
"ApplicationTemplate": "Szablon aplikacji",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
index 4e06b40112..2aebae87cd 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " Uma completa plataforma de desenvolvimento web integrada estrutura ",
"AbpCommercialShortDescription": "ABP Commercial fornece módulos de aplicativos pré-construídos, ferramentas de desenvolvimento rápido de aplicativos, temas de UI profissionais, suporte premium e muito mais.",
"LiveDemo": "Demonstração ao vivo",
+ "LiveDemoLead": "{1} usando sua conta ABP, {3} para abp.io. Ou preencha o formulário abaixo para criar uma demonstração ao vivo agora",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Já existe uma conta com o endereço de e-mail fornecido: {0} Você pode fazer login com sua conta para continuar.",
"GetLicence": "Obtenha uma licença",
"Application": "Aplicativo",
"StartupTemplates": "Modelos de inicialização",
@@ -129,12 +131,14 @@
"YourFullName": "Seu nome completo",
"EmailField": "Endereço de e-mail",
"YourEmailAddress": "Seu endereço de email",
+ "ValidEmailAddressIsRequired": "Um endereço de e-mail válido é obrigatório.",
"HowMayWeHelpYou": "Como podemos ajudá-lo?",
"SendMessage": "Enviar mensagem",
"Success": "Sucesso",
"WeWillReplyYou": "Recebemos sua mensagem e entraremos em contato em breve.",
"GoHome": "Ir para casa",
"CreateLiveDemo": "Criar demonstração ao vivo",
+ "CreateLiveDemoDescription": "Depois de enviar este formulário, você receberá um e-mail contendo o link da sua demonstração.",
"RegisterToTheNewsletter": "Cadastre-se no boletim informativo para receber informações sobre ABP.IO, incluindo novos lançamentos etc.",
"EnterYourEmailOrLogin": "Digite seu endereço de e-mail para criar sua demonstração ou Faça login usando sua conta existente.",
"ApplicationTemplate": "Modelo de aplicativo",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
index 358bd87038..25d24193ad 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial oferă module de aplicaţii pre-construite, instrumente de dezvoltare rapidă a aplicaţiilor, teme UI profesionale, asistenţă premium şi multe altele.",
"LiveDemo": "Live Demo",
+ "LiveDemoLead": "{1} folosind contul ABP, {3} la abp.io. Sau completaţi formularul de mai jos pentru a crea un demo live acum",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Există deja un cont cu adresa de email specificată: {0} Puteţi să vă autentificaţi cu contul dumneavoastră pentru a continua.",
"GetLicence": "Obţine o licenţă",
"Application": "Application",
"StartupTemplates": "Şabloane de lansare",
@@ -129,12 +131,14 @@
"YourFullName": "Numele dumneavoastră complet",
"EmailField": "Adresa de email",
"YourEmailAddress": "Adresa dumneavoastră de email",
+ "ValidEmailAddressIsRequired": "Vă rugăm să introduceţi o adresă de email validă.",
"HowMayWeHelpYou": "Cum vă putem ajuta?",
"SendMessage": "Trimite mesaj",
"Success": "Succes",
"WeWillReplyYou": "Am primit mesajul dumneavoastră şi vă vom contacta cât de repede posibil.",
"GoHome": "Navigaţi acasă",
"CreateLiveDemo": "Crează Demo Live",
+ "CreateLiveDemoDescription": "După ce trimiteţi acest formular, veţi primi un email care conţine link-ul demo-ului dumneavoastră.",
"RegisterToTheNewsletter": "Înregistraţi-va la newsletter pentru a primi informaţii despre ABP.IO, inclusiv lansări noi etc.",
"EnterYourEmailOrLogin": "Introduceţi-vă adresa de email pentru a vă crea demo-ul sau Autentificaţi-vă folosind contul existent.",
"ApplicationTemplate": "Application Template",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json
index 8c53bc9ea8..4832618e30 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " Полная платформа веб-разработки встроенная каркас ",
"AbpCommercialShortDescription": "ABP Commercial предоставляет готовые модули приложений, инструменты для быстрой разработки приложений, профессиональные темы пользовательского интерфейса, поддержку премиум-класса и многое другое.",
"LiveDemo": "Живая демонстрация",
+ "LiveDemoLead": "{1} используя свою учетную запись ABP, {3} на abp.io. Или заполните форму ниже, чтобы создать живую демонстрацию прямо сейчас",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Уже есть учетная запись с указанным адресом электронной почты: {0} Вы можете войти в свою учетную запись, чтобы продолжить.",
"GetLicence": "Получить лицензию",
"Application": "заявка",
"StartupTemplates": "Шаблоны запуска",
@@ -129,12 +131,14 @@
"YourFullName": "Ваше полное имя",
"EmailField": "Адрес электронной почты",
"YourEmailAddress": "Ваш адрес электронной почты",
+ "ValidEmailAddressIsRequired": "Требуется действительный адрес электронной почты.",
"HowMayWeHelpYou": "Как мы можем Вам помочь?",
"SendMessage": "Отправить сообщение",
"Success": "Успех",
"WeWillReplyYou": "Мы получили ваше сообщение и скоро свяжемся с вами.",
"GoHome": "Иди домой",
"CreateLiveDemo": "Создать живую демонстрацию",
+ "CreateLiveDemoDescription": "После отправки этой формы вы получите электронное письмо со ссылкой на демонстрацию.",
"RegisterToTheNewsletter": "Подпишитесь на рассылку новостей, чтобы получать информацию о ABP.IO, в том числе о новых выпусках и т. Д.",
"EnterYourEmailOrLogin": "Введите свой адрес электронной почты, чтобы создать демоверсию, или войдите , используя существующую учетную запись.",
"ApplicationTemplate": "Шаблон приложения",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
index b0a6d6490e..0d4ca5e610 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Kompletná web vývojová platformapostavená na frameworku",
"AbpCommercialShortDescription": "ABP Commercial poskytuje predpripravené aplikačné moduly, nástroje na rýchly vývoj aplikácií, profesionálne témy používateľského rozhrania, prémiovú podporu a ďalšie.",
"LiveDemo": "Live ukážka",
+ "LiveDemoLead": "{1} použitím vášho ABP účtu, {3} na abp.io. Alebo vyplňte nižšie uvedený formulár a vytvorte si teraz live ukážku",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Už existuje účet s danou emailovou adresou: {0} Môžete sa prihlásiť pomocou svojho účtu a pokračovať.",
"GetLicence": "Získajte licenciu",
"Application": "Aplikácia",
"StartupTemplates": "Štartovacie šablóny",
@@ -129,12 +131,14 @@
"YourFullName": "Vaše celé meno",
"EmailField": "Emailová adresa",
"YourEmailAddress": "Vaša emailová adresa",
+ "ValidEmailAddressIsRequired": "Je potrebná platná emailová adresa.",
"HowMayWeHelpYou": "Ako vám môžeme pomôcť?",
"SendMessage": "Odoslať správu",
"Success": "Úspech",
"WeWillReplyYou": "Dostali sme vašu správu a čoskoro vás budeme kontaktovať.",
"GoHome": "Prejsť Domov",
"CreateLiveDemo": "Vytvoriť live ukážku",
+ "CreateLiveDemoDescription": "Po odoslaní tohto formulára obdržíte e-mail obsahujúci odkaz na vašu ukážku.",
"RegisterToTheNewsletter": "Zaregistrujte sa na odber noviniek a dostávajte informácie o ABP.IO, vrátane nových verzií atď.",
"EnterYourEmailOrLogin": "Zadajte svoju emailovú adresu a vytvorte si ukážku alebo sa prihláste pomocou svojho existujúceho konta.",
"ApplicationTemplate": "Šablóna žiadosti",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
index 85acb70552..6687f04ec6 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": "Popolna platforma za spletno razvojvgrajena okvir",
"AbpCommercialShortDescription": "ABP Commercial ponuja vnaprej izdelane aplikacijske module, orodja za hiter razvoj aplikacij, profesionalne teme uporabniškega vmesnika, vrhunsko podporo in še več.",
"LiveDemo": "Demo v živo",
+ "LiveDemoLead": "{1} s svojim ABP računom, {3} na abp.io. Ali izpolnite spodnji obrazec, da ustvarite demo v živo zdaj",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Za navedeni e-poštni naslov že obstaja račun: {0} Lahko se prijavite s svojim računom, da nadaljujete.",
"GetLicence": "Pridobite licenco",
"Application": "Aplikacija",
"StartupTemplates": "Predloge za zagon",
@@ -129,12 +131,14 @@
"YourFullName": "Tvoje polno ime",
"EmailField": "Email naslov",
"YourEmailAddress": "Vaš email naslov",
+ "ValidEmailAddressIsRequired": "Veljaven e-poštni naslov je obvezen",
"HowMayWeHelpYou": "Kako vam lahko pomagamo?",
"SendMessage": "Pošlji sporočilo",
"Success": "uspeh",
"WeWillReplyYou": "Prejeli smo vaše sporočilo in vas bomo v kratkem kontaktirali.",
"GoHome": "Pojdi domov",
"CreateLiveDemo": "Ustvari demo v živo",
+ "CreateLiveDemoDescription": "Ko pošljete ta obrazec, boste prejeli e-poštno sporočilo s povezavo do svojega demo.",
"RegisterToTheNewsletter": "Registrirajte se za glasilo, če želite prejemati informacije o ABP.IO, vključno z novimi izdajami itd.",
"EnterYourEmailOrLogin": "Vnesite svoj e-poštni naslov, če želite ustvariti predstavitev, ali Prijavite se z obstoječim računom.",
"ApplicationTemplate": "Predloga aplikacije",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
index 7c4df52c6c..1dad32c034 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
@@ -48,6 +48,8 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial, önceden oluşturulmuş uygulama modülleri, hızlı uygulama geliştirme araçları, profesyonel UI temaları, premium destek ve daha fazlasını sağlar.",
"LiveDemo": "Canlı Demo",
+ "LiveDemoLead": "{1} ABP hesabınızı kullanarak, {3} abp.io'ya hoş geldiniz. Veya aşağıdaki formu doldurarak şimdi canlı bir demo oluşturun",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Zaten {0} e-posta adresiyle bir hesap var. Devam etmek için hesabınızla giriş yapabilirsiniz.",
"GetLicence": "Lisans Alın",
"Application": "Başvuru",
"StartupTemplates": "Başlangıç Şablonları",
@@ -131,12 +133,14 @@
"YourFullName": "Tam adınız",
"EmailField": "E-posta Adresi",
"YourEmailAddress": "E-posta adresiniz",
+ "ValidEmailAddressIsRequired": "Geçerli bir e-posta adresi gereklidir",
"HowMayWeHelpYou": "Size nasıl yardımcı olabiliriz?",
"SendMessage": "Mesaj gönder",
"Success": "Başarı",
"WeWillReplyYou": "Mesajınızı aldık ve kısa süre içinde sizinle iletişime geçeceğiz.",
"GoHome": "Eve git",
"CreateLiveDemo": "Canlı Demo Oluştur",
+ "CreateLiveDemoDescription": "Bu formu gönderdikten sonra, demo bağlantınızı içeren bir e-posta alacaksınız.",
"RegisterToTheNewsletter": "ABP.IO hakkında yeni yayınlar vb. dahil olmak üzere bilgi almak için haber bültenine kaydolun.",
"EnterYourEmailOrLogin": "Demonuzu oluşturmak için e-posta adresinizi girin veya mevcut hesabınızı kullanarak Giriş yapın.",
"ApplicationTemplate": "Uygulama Şablonu",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
index e5ed696808..05658075db 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
@@ -46,6 +46,8 @@
"IndexPageHeroSection": " Nền tảng phát triển web hoàn chỉnh được tích hợp sẵn khung ",
"AbpCommercialShortDescription": "ABP Commercial cung cấp các mô-đun ứng dụng được tạo sẵn, công cụ phát triển ứng dụng nhanh chóng, các chủ đề giao diện người dùng chuyên nghiệp, hỗ trợ cao cấp và hơn thế nữa.",
"LiveDemo": "Bản thử trực tiếp",
+ "LiveDemoLead": "{1} hoặc {3} đến abp.io. Hoặc điền vào biểu mẫu bên dưới để tạo bản trình diễn trực tiếp ngay bây giờ",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "Đã có một tài khoản với địa chỉ email đã cho: {0} Bạn có thể đăng nhập vào tài khoản của mình để tiếp tục.",
"GetLicence": "Nhận giấy phép",
"Application": "Ứng dụng",
"StartupTemplates": "Mẫu khởi động",
@@ -129,12 +131,14 @@
"YourFullName": "Tên đầy đủ của bạn",
"EmailField": "Địa chỉ email",
"YourEmailAddress": "Địa chỉ email của bạn",
+ "ValidEmailAddressIsRequired": "Địa chỉ email hợp lệ là bắt buộc",
"HowMayWeHelpYou": "Chúng tôi có thể giúp gì cho bạn?",
"SendMessage": "Gửi tin nhắn",
"Success": "Sự thành công",
"WeWillReplyYou": "Chúng tôi đã nhận được tin nhắn của bạn và sẽ sớm liên hệ với bạn.",
"GoHome": "Về nhà",
"CreateLiveDemo": "Tạo bản trình diễn trực tiếp",
+ "CreateLiveDemoDescription": "Sau khi bạn gửi biểu mẫu này, bạn sẽ nhận được một email chứa liên kết bản demo của mình.",
"RegisterToTheNewsletter": "Đăng ký nhận bản tin để nhận thông tin về ABP.IO, bao gồm các bản phát hành mới, v.v.",
"EnterYourEmailOrLogin": "Nhập địa chỉ e-mail của bạn để tạo bản demo hoặc Đăng nhập bằng tài khoản hiện có của bạn.",
"ApplicationTemplate": "Mẫu ứng dụng",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
index 0aadd74a52..dc2046e197 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
@@ -49,6 +49,8 @@
"IndexPageHeroSection": "一个完整的web开发平台基于 框架",
"AbpCommercialShortDescription": "ABP商业版提供了预构建的应用程序模块, 快速的应用程序开发工具, 专业的UI主题, 高级支持等.",
"LiveDemo": "在线演示",
+ "LiveDemoLead": "{1} 到你的ABP账户, {3} 到 abp.io. 或者填写下面的表单立即创建在线演示",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "已经有一个使用此电子邮件地址的帐户: {0} 你可以使用你的帐户登录继续.",
"GetLicence": "获得许可",
"Application": "应用程序",
"StartupTemplates": "启动模板",
@@ -132,12 +134,14 @@
"LastNameField": "姓氏",
"EmailField": "E-mail地址",
"YourEmailAddress": "你的e-mail地址",
+ "ValidEmailAddressIsRequired": "请输入有效的e-mail地址",
"HowMayWeHelpYou": "需要获得购买帮助?(提供中文服务)",
"SendMessage": "发送消息",
"Success": "成功",
"WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.",
"GoHome": "回到主页面",
"CreateLiveDemo": "创建在线演示",
+ "CreateLiveDemoDescription": "一旦你提交此表单,你将收到一封包含你的演示链接的电子邮件.",
"RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.",
"EnterYourEmailOrLogin": "输入你的e-mail地址来创建你的演示或者使用你的已有账号登录.",
"ApplicationTemplate": "应用程序模板",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
index 1f50563750..a90e7f20bb 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
@@ -48,6 +48,8 @@
"IndexPageHeroSection": "一個完整的web開發平臺基於 框架",
"AbpCommercialShortDescription": "ABP商業版提供了預構建的應用程序模塊, 快速的應用程序開發工具, 專業的UI主題, 高級支持等.",
"LiveDemo": "在線演示",
+ "LiveDemoLead": " {1} 使用你的ABP賬號, {3} 到 abp.io. 或者填寫下面的表單立即創建一個在線演示",
+ "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "已經有一個使用該電子郵件地址的賬號: {0} 你可以使用你的賬號登錄以繼續.",
"GetLicence": "獲得許可",
"Application": "應用程序",
"StartupTemplates": "啟動模板",
@@ -131,12 +133,14 @@
"YourFullName": "你的全名",
"EmailField": "E-mail地址",
"YourEmailAddress": "你的e-mail地址",
+ "ValidEmailAddressIsRequired": "請輸入有效的e-mail地址",
"HowMayWeHelpYou": "我們如何幫助你",
"SendMessage": "發送消息",
"Success": "成功",
"WeWillReplyYou": "你的消息已經發送! 我們會在短時間內給你答復.",
"GoHome": "回到主頁面",
"CreateLiveDemo": "創建在線演示",
+ "CreateLiveDemoDescription": "一旦你提交此表單,你將收到一封包含你的演示鏈接的電子郵件.",
"RegisterToTheNewsletter": "註冊到時事簡報以獲取有關ABP.IO的消息,比如新發布的內容.",
"EnterYourEmailOrLogin": "輸入你的e-mail地址來創建你的演示或者使用你的已有賬號登錄.",
"ApplicationTemplate": "應用程序模板",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index e6b3cf46f7..d2ea2d3a0b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -18,7 +18,7 @@
"Save": "Save",
"SameUrlAlreadyExist": "Same url already exists if you want to add this post, you should change the url!",
"UrlIsNotValid": "Url is not valid.",
- "UrlNotFound" : "Url not found.",
+ "UrlNotFound": "Url not found.",
"UrlContentNotFound": "Url content not found.",
"Summary": "Summary",
"MostRead": "Most Read",
@@ -37,6 +37,7 @@
"ThisExtensionIsNotAllowed": "This extension is not allowed.",
"TheFileIsTooLarge": "The file is too large.",
"GoToThePost": "Go to the Post",
+ "GoToTheVideo": "Go to the Video",
"Contribute": "Contribute",
"OverallProgress": "Overall Progress",
"Done": "Done",
@@ -170,7 +171,7 @@
"Discord_Page_Announce": "We are happy to announce ABP Community Discord Server!",
"Discord_Page_Description_1": "ABP Community has been growing since day one. We wanted to take it to the next step by creating an official ABP Discord server so the ABP Community can interact with each other using the wonders of instant messaging.",
"Discord_Page_Description_2": "ABP Community Discord Server is the place where you can showcase your creations using ABP Framework, share the tips that worked for you, catch up with the latest news and announcements about ABP Framework, just chat with community members to exchange ideas, and have fun!",
- "Discord_Page_Description_3": "This ABP Community Discord Server is the official one with the ABP Core Team is present on the server to monitor.",
+ "Discord_Page_Description_3": "This ABP Community Discord Server is the official one with the ABP Core Team is present on the server to monitor.",
"Discord_Page_JoinToServer": "Join ABP Discord Server",
"Events_Page_MetaTitle": "ABP Community Events",
"Events_Page_MetaDescription": "The live shows, hosted by the ABP Team, are casual sessions full of community content, demos, Q&A, and discussions around what's happening in ABP.",
@@ -189,6 +190,71 @@
"SeeMoreVideos": "See more videos",
"DiscordPageTitle": "ABP Discord Community",
"ViewVideo": "View Video",
- "AbpCommunityTitleContent": "ABP Community - Open Source ABP Framework"
+ "AbpCommunityTitleContent": "ABP Community - Open Source ABP Framework",
+ "CommunitySlogan": "A unique community platform for ABP Lovers",
+ "RaffleIsNotActive": "Raffle is not active",
+ "YouAreAlreadyJoinedToThisRaffle": "You are already joined to this raffle",
+ "InvalidSubscriptionCode": "Invalid subscription code",
+ "Raffle:{0}": "Raffle: {0}",
+ "Join": "Join",
+ "Leave": "Leave",
+ "LoginToJoin": "Login to join",
+ "ToEnd:": "To end:",
+ "ToStart:": "To start:",
+ "days": "days",
+ "hrs": "hrs",
+ "min": "min",
+ "sec": "sec",
+ "Winners": "Winners",
+ "To{0}LuckyWinners": "to {0} lucky winner(s)",
+ "ActiveRaffles": "Active Raffles",
+ "UpcomingRaffles": "Upcoming Raffles",
+ "CompletedRaffles": "Completed Raffles",
+ "NoActiveRaffleTitle": "No active raffle is available at the moment.",
+ "NoActiveRaffleDescription": "No active raffle is available at the moment.",
+ "RaffleSubscriptionCodeInputMessage": "This raffle requires a registration code. Please enter the registration code below:",
+ "RaffleSubscriptionCodeInputErrorMessage": "The registration code is incorrect. Please try again.",
+ "GoodJob!": "Good Job!",
+ "RaffleJoinSuccessMessage": "You are successfully registered for the raffle. You will be informed via email if you win the prize!",
+ "RaffleLoginAndRegisterMessage": "You should sign in to join a raffle. You can create an account for free if you haven't registered yet.",
+ "Ok": "Ok",
+ "SeeDetails": "See Details",
+ "WaitingForTheDraw": "Waiting for the draw",
+ "AllAttendees": "All Attendees",
+ "SeeRaffleDetail": "See Raffle Detail",
+ "SeeRaffle": "See Raffle",
+ "ParticipationIsComplete!": "Participation is complete!",
+ "ABPCoreDevelopmentTeam": "ABP Core Development Team",
+ "RegisterTheEvent": "Register the Event",
+ "GoToConferencePage": "Go to Conference Page",
+ "BuyTicket": "Buy Ticket",
+ "SeeEvent": "See Event",
+ "PreviousEvents": "Previous Events",
+ "OtherLiveEvents": "Other Live Events",
+ "SponsoredConferences": "Sponsored Conferences",
+ "SponsoredConferencesDescription": "We are honoring to support .NET communities and events for software developers.",
+ "UpcomingEvents": "Upcoming Events",
+ "UpcomingCommunityTalkEventDescription": "The live shows, hosted by the ABP Team, are casual sessions full of community content, demos, Q&A, and discussions around what's happening in ABP.",
+ "UpcomingConferenceEventDescription": "ABP .NET Conference is a virtual event for the .NET Developer community to come together and listen to talks about the .NET world, common software development practices and the open source ABP Framework.",
+ "LastOneYear": "Last 1 Year",
+ "AllTimes": "All Times",
+ "TopContributors": "Top Contributors",
+ "{0}Posts": "{0} Posts",
+ "LATESTPOSTS": "LATEST POSTS",
+ "NoContributorsFound": "No contributors found!",
+ "LatestPost": "Latest post",
+ "MEMBERSINCE{0}": "MEMBER SINCE {0}",
+ "CopyLink": "Copy Link",
+ "ShareOnTwitter": "Share on Twitter",
+ "ShareOnLinkedIn": "Share on LinkedIn",
+ "MoreFrom{0}": "More from {0}",
+ "SeeAllFrom{0}": "See all from {0}",
+ "MostWatched": "Most Watched",
+ "Articles({0})": "Articles ({0})",
+ "Videos({0})": "Videos ({0})",
+ "LatestArticles": "Latest Articles",
+ "RaffleHeader": "Hello ABP Community Member!",
+ "RafflesInfo": " This is the raffle page dedicated to show our appreciation towards you for being an active Community Member. We do ABP Community Talks,ABP .NET Conference, attend or sponsor to the .NET-related events in which we give away some gifts.
You can follow this page to see the upcoming raffles, attend them, or see previous raffles we draw including the winners.
Thank you for being an active member! See you in the upcoming raffles.",
+ "RafflesInfoTitle": "ABP Community Raffles"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json
index ae3354617b..36cad167bd 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json
@@ -3,6 +3,7 @@
"texts": {
"Buy": "Buy",
"SeeBookDetails": "See Book Details",
- "MasteringAbpFrameworkEBookDescription": "This book will help you gain a complete understanding of the framework and modern web application development techniques."
+ "MasteringAbpFrameworkEBookDescription": "This book will help you gain a complete understanding of the framework and modern web application development techniques.",
+ "Feedback": "Feedback"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ar.json
index 592665c698..26fd7af520 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ar.json
@@ -16,7 +16,7 @@
"Tutorial": "الدورة التعليمية",
"UsingCLI": "باستخدام واجهة الأوامر CLI",
"SeeDetails": "انظر التفاصيل",
- "AbpShortDescription": "إطار عمل ABP هو بنية أساسية كاملة لإنشاء تطبيقات ويب حديثة باتباع أفضل ممارسات واتفاقيات تطوير البرامج.",
+ "AbpShortDescription": "يعد ABP Framework بنية تحتية كاملة لإنشاء حلول برمجية ذات بنيات حديثة تعتمد على النظام الأساسي ASP.NET Core.",
"SourceCodeUpper": "الكود الأصل",
"LatestReleaseLogs": "أحدث سجلات الإصدار",
"Infrastructure": "البنية التحتية",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/cs.json
index 7fa321b7b9..09e87ba3be 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/cs.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/cs.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Pomocí CLI",
"SeeDetails": "Zobrazit podrobnosti",
- "AbpShortDescription": "ABP Framework je kompletní infrastruktura pro vytváření moderních webových aplikací podle osvědčených postupů a konvencí vývoje softwaru.",
+ "AbpShortDescription": "ABP Framework je kompletní infrastruktura pro vytváření softwarových řešení s moderními architekturami založenými na platformě ASP.NET Core.",
"SourceCodeUpper": "ZDROJOVÝ KÓD",
"LatestReleaseLogs": "Nejnovější protokoly vydání",
"Infrastructure": "Infrastruktura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/de.json
index 28821200c8..5c9855d4ac 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/de.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/de.json
@@ -16,7 +16,7 @@
"Tutorial": "Lernprogramm",
"UsingCLI": "mit CLI",
"SeeDetails": "Details ansehen",
- "AbpShortDescription": "ABP Framework ist eine vollständige Infrastruktur zum Erstellen moderner Webanwendungen unter Befolgung von Best Practices und Konventionen für Softwareentwicklung.",
+ "AbpShortDescription": "ABP Framework ist eine vollständige Infrastruktur zur Erstellung von Softwarelösungen mit modernen Architekturen basierend auf der ASP.NET Core-Plattform.",
"SourceCodeUpper": "QUELLCODE",
"LatestReleaseLogs": "Akteulle Release",
"Infrastructure": "Infrastrutkur",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json
index d40b66788d..0682e1f114 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json
@@ -15,7 +15,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Using CLI",
"SeeDetails": "See Details",
- "AbpShortDescription": "ABP Framework is a complete infrastructure to create modern web applications by following the software development best practices and conventions.",
+ "AbpShortDescription": "ABP Framework is a complete infrastructure for creating software solutions with modern architectures based on the ASP.NET Core platform.",
"SourceCodeUpper": "SOURCE CODE",
"LatestReleaseLogs": "Latest release logs",
"Infrastructure": "Infrastructure",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
index 3351b7d8cf..a7e109f8ab 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Using CLI",
"SeeDetails": "See Details",
- "AbpShortDescription": "ABP Framework is a complete infrastructure to create modern web applications by following the best practices and conventions of software development.",
+ "AbpShortDescription": "ABP Framework is a complete infrastructure for creating software solutions with modern architectures based on the ASP.NET Core platform.",
"SourceCodeUpper": "SOURCE CODE",
"LatestReleaseLogs": "Latest release logs",
"Infrastructure": "Infrastructure",
@@ -174,6 +174,7 @@
"CreateProjectWizard": "This wizard creates a new project from the startup template which is properly configured to jump start your project.",
"TieredOption": "Creates a tiered solution where Web and Http API layers are physically separated. If not checked, creates a layered solution which is less complex and suitable for most scenarios.",
"SeparateIdentityServerOption": "Separates the server side into two applications: The first one is for the identity server and the second one is for your server side HTTP API.",
+ "SeparateAuthenticationServerOption": "Separates the server side into two applications: The first one is for the authentication server and the second one is for your server side HTTP API.",
"ProgressiveWebApplicationOption": "Specifies the project as Progressive Web Application",
"UseslatestPreVersion": "Uses the latest pre-release version",
"ReadTheDocumentation": "Read The Documentation",
@@ -296,6 +297,7 @@
"EnterYouEmailToGetNews": "Enter your email to get the latest news about the ABP Framework",
"Tiered": "Tiered",
"SeparateIdentityServer": "Separate Identity Server",
+ "SeparateAuthenticationServer": "Separate Authentication Server",
"ProgressiveWebApplication": "Progressive Web Application",
"Preview": "Preview",
"CreateANewSolution": "Create a new solution",
@@ -430,6 +432,16 @@
"PackageDetailPage_ManualInstallationDescription2": "Then add the {0} dependency to your module class as shown in the following example",
"PackageDetailPage_SeeDocumentation": "See the documentation to learn how to use this package in your applications.",
"PackageDetailPage_InstallingUsingPMC": "3: Installing with the Package Manager Console",
- "PackageDetailPage_InstallingUsingPMCDescription1": "Open the Package Manager Console in Visual Studio (Tools -> Nuget Package Manager -> Package Manager Console) and execute the following command"
+ "PackageDetailPage_InstallingUsingPMCDescription1": "Open the Package Manager Console in Visual Studio (Tools -> Nuget Package Manager -> Package Manager Console) and execute the following command",
+ "UIOptions": "UI Options",
+ "Testimonials": "Testimonials",
+ "CoolestCompaniesUseABPFramework": "Coolest Companies Use ABP Framework",
+ "Index_Page_Testimonial_1": "ABP Framework is not just a tool but a catalyst that has accelerated my growth as a developer. It has made it possible for me to build new features faster than ever before, reminiscent of the experiences of other users. The unified coding pattern has streamlined my projects, giving me more time to focus on creating rather than troubleshooting.\nI would say the ABP Framework has been the cornerstone of my early professional journey. It has facilitated my transition from an aspiring developer to a confident professional ready to make a mark in the software world. I am looking forward to the exciting projects that await me, knowing that ABP will be there to guide me. It is more than just a product; it's a partner in success.",
+ "Index_Page_Testimonial_2": "ABP Framework is not only a framework, it is also a guidance for project development/management, because it provides DDD, GenericRepository, DI, Microservice, Modularity trainings. Even if you are not going to use framework itself, you can develop yourself with docs.abp.io which is well and professionally prepared. (OpenIddict, Redis, Quartz etc.)\nBecause many thing pre-built, it shortens project development time significantly. (Such as login page, exception handling, data filtering-seeding, audit logging, localization, auto api controller etc.)\nAs an example from our app, i have used Local Event Bus for stock control. So, I am able to manage order movements by writing stock handler.\nIt is wonderful not to lose time for CreationTime, CreatorId. They are filled automatically.",
+ "VideosLoginAndRegisterMessage": "You must sign in to watch videos. You can create an account for watch if you haven't.",
+ "Filter": "Filter",
+ "VideoCourses": "Video Courses"
}
}
+
+
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/es.json
index 88f28ede88..b2d6020e46 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/es.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/es.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Usando CLI",
"SeeDetails": "Ver detalles",
- "AbpShortDescription": "ABP Framework es una completa infraestructure para crear modernas aplicaciones web que sigue las mejores prácticas y convenciones de desarrollo de software.",
+ "AbpShortDescription": "ABP Framework es una infraestructura completa para la creación de soluciones de software con arquitecturas modernas basadas en la plataforma ASP.NET Core.",
"SourceCodeUpper": "CÓDIGO FUENTE",
"LatestReleaseLogs": "Últimos registros de lanzamiento",
"Infrastructure": "infraestructura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fi.json
index c41f58399d..db08a3479a 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fi.json
@@ -16,7 +16,7 @@
"Tutorial": "Opetusohjelma",
"UsingCLI": "CLI:n käyttö",
"SeeDetails": "Katso yksityiskohdat",
- "AbpShortDescription": "ABP Framework on täydellinen infrastruktuuri nykyaikaisten verkkosovellusten luomiseen noudattamalla ohjelmistokehityksen parhaita käytäntöjä ja käytäntöjä.",
+ "AbpShortDescription": "ABP Framework on täydellinen infrastruktuuri ohjelmistoratkaisujen luomiseen moderneilla arkkitehtuureilla, jotka perustuvat ASP.NET Core -alustaan.",
"SourceCodeUpper": "LÄHDEKOODI",
"LatestReleaseLogs": "Uusimmat julkaisulokit",
"Infrastructure": "Infrastruktuuri",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json
index e66bc4082a..376fd9a728 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json
@@ -16,7 +16,7 @@
"Tutorial": "Didacticiel",
"UsingCLI": "Utilisation de la CLI",
"SeeDetails": "Voir les détails",
- "AbpShortDescription": "ABP Framework est une infrastructure complète pour créer des applications Web modernes en suivant les meilleures pratiques et conventions de développement logiciel.",
+ "AbpShortDescription": "ABP Framework est une infrastructure complète pour créer des solutions logicielles avec des architectures modernes basées sur la plateforme ASP.NET Core.",
"SourceCodeUpper": "CODE SOURCE",
"LatestReleaseLogs": "Derniers journaux de version",
"Infrastructure": "Infrastructure",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json
index 1b4bd1c879..c101c8bdf9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json
@@ -16,7 +16,7 @@
"Tutorial": "ट्यूटोरियल",
"UsingCLI": "सीएलआई का उपयोग करना",
"SeeDetails": "विवरण देखें",
- "AbpShortDescription": "एबीपी फ्रेमवर्क सॉफ्टवेयर विकास सर्वोत्तम प्रथाओं और सम्मेलनों का पालन करके आधुनिक वेब एप्लिकेशन बनाने के लिए एक पूर्ण बुनियादी ढांचा है।",
+ "AbpShortDescription": "ABP फ्रेमवर्क ASP.NET कोर प्लेटफॉर्म पर आधारित आधुनिक आर्किटेक्चर के साथ सॉफ्टवेयर समाधान बनाने के लिए एक संपूर्ण बुनियादी ढांचा है।",
"SourceCodeUpper": "सोर्स कोड",
"LatestReleaseLogs": "नवीनतम रिलीज़ लॉग",
"Infrastructure": "भूमिकारूप व्यवस्था",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hu.json
index a3f4d84e26..2dfae14e99 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hu.json
@@ -16,7 +16,7 @@
"Tutorial": "Oktatóanyag",
"UsingCLI": "CLI használata",
"SeeDetails": "Lásd a részleteket",
- "AbpShortDescription": "Az ABP Framework egy komplett infrastruktúra modern webalkalmazások létrehozásához, követve a szoftverfejlesztés legjobb gyakorlatait és konvencióit.",
+ "AbpShortDescription": "Az ABP Framework egy komplett infrastruktúra modern architektúrákkal rendelkező szoftvermegoldások létrehozásához, amelyek az ASP.NET Core platformon alapulnak.",
"SourceCodeUpper": "FORRÁSKÓD",
"LatestReleaseLogs": "Legújabb kiadási naplók",
"Infrastructure": "Infrastruktúra",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/is.json
index 15941b2f20..f044092f19 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/is.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/is.json
@@ -16,7 +16,7 @@
"Tutorial": "Kennsla",
"UsingCLI": "Nota CLI",
"SeeDetails": "Sjá meira",
- "AbpShortDescription": "ABP Framework hefur fullkomna innviði til að búa til nútímaleg vefforrit með því að fylgja bestu starfsháttum og venjum hugbúnaðarþróunar.",
+ "AbpShortDescription": "ABP Framework er fullkominn innviði til að búa til hugbúnaðarlausnir með nútíma arkitektúr sem byggir á ASP.NET Core pallinum.",
"SourceCodeUpper": "FRUMKÓÐI",
"LatestReleaseLogs": "Nýjustu útgáfuupplýsingar",
"Infrastructure": "Innviðir",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json
index 5cc16b4646..959159e373 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Utilizzo della CLI",
"SeeDetails": "Vedi i dettagli",
- "AbpShortDescription": "ABP Framework è un'infrastruttura completa per creare applicazioni Web moderne seguendo le migliori pratiche e convenzioni di sviluppo software.",
+ "AbpShortDescription": "ABP Framework è un'infrastruttura completa per la creazione di soluzioni software con architetture moderne basate sulla piattaforma ASP.NET Core.",
"SourceCodeUpper": "CODICE SORGENTE",
"LatestReleaseLogs": "Ultimi note di rilascio",
"Infrastructure": "Infrastruttura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/nl.json
index 4bc2cffb2a..cd656a3cc2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/nl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/nl.json
@@ -16,7 +16,7 @@
"Tutorial": "zelfstudie",
"UsingCLI": "CLI . gebruiken",
"SeeDetails": "Zie de details",
- "AbpShortDescription": "ABP Framework is een complete infrastructuur om moderne webapplicaties te creëren door de best practices en conventies voor softwareontwikkeling te volgen.",
+ "AbpShortDescription": "ABP Framework is een complete infrastructuur voor het creëren van softwareoplossingen met moderne architecturen gebaseerd op het ASP.NET Core-platform.",
"SourceCodeUpper": "BRONCODE",
"LatestReleaseLogs": "Laatste release-logboeken",
"Infrastructure": "Infrastructuur",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pl-PL.json
index cb33d69ab6..04d3bdb07a 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pl-PL.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pl-PL.json
@@ -16,7 +16,7 @@
"Tutorial": "Instruktaż",
"UsingCLI": "Korzystanie z CLI",
"SeeDetails": "Patrz szczegóły",
- "AbpShortDescription": "ABP Framework to kompletna infrastruktura do tworzenia nowoczesnych aplikacji internetowych zgodnie z najlepszymi praktykami i konwencjami tworzenia oprogramowania.",
+ "AbpShortDescription": "ABP Framework to kompletna infrastruktura do tworzenia rozwiązań programowych o nowoczesnych architekturach w oparciu o platformę ASP.NET Core.",
"SourceCodeUpper": "KOD ŹRÓDŁOWY",
"LatestReleaseLogs": "Dzienniki ostatnich wydań",
"Infrastructure": "Infrastruktura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pt-BR.json
index b468c06403..7fd68de3be 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pt-BR.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/pt-BR.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Usando CLI",
"SeeDetails": "Ver detalhes",
- "AbpShortDescription": "ABP é uma arquitetura completa e uma forte infraestrutura para criar aplicativos da web modernos! Segue as melhores práticas e convenções para fornecer uma sólida experiência de desenvolvimento.",
+ "AbpShortDescription": "ABP Framework é uma infraestrutura completa para criação de soluções de software com arquiteturas modernas baseadas na plataforma ASP.NET Core.",
"SourceCodeUpper": "CÓDIGO FONTE",
"LatestReleaseLogs": "Últimos registros de lançamento",
"Infrastructure": "Infraestrutura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
index 003309aa74..f501a0f6ef 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
@@ -16,7 +16,7 @@
"Tutorial": "Tutorial",
"UsingCLI": "Folosind CLI",
"SeeDetails": "Vedeţi detalii",
- "AbpShortDescription": "ABP Framework este o infrastructură completă pentru crearea aplicaţiilor moderne web prin folosirea celor mai bune practici şi convenţii de dezvoltare software.",
+ "AbpShortDescription": "ABP Framework este o infrastructură completă pentru crearea de soluții software cu arhitecturi moderne bazate pe platforma ASP.NET Core.",
"SourceCodeUpper": "COD SURSĂ",
"LatestReleaseLogs": "Cele mai recente jurnale de lansare",
"Infrastructure": "Infrastructura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ru.json
index 8df80b7422..0af1329385 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ru.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ru.json
@@ -16,7 +16,7 @@
"Tutorial": "Руководство",
"UsingCLI": "Использование CLI",
"SeeDetails": "Смотрите подробности",
- "AbpShortDescription": "ABP Framework - это полная инфраструктура для создания современных веб-приложений с соблюдением лучших практик и соглашений в области разработки программного обеспечения.",
+ "AbpShortDescription": "ABP Framework — это полноценная инфраструктура для создания программных решений с современной архитектурой на базе платформы ASP.NET Core.",
"SourceCodeUpper": "ИСХОДНЫЙ КОД",
"LatestReleaseLogs": "Журналы последних выпусков",
"Infrastructure": "Инфраструктура",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sk.json
index f578158624..59aa30362f 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sk.json
@@ -16,7 +16,7 @@
"Tutorial": "Návod",
"UsingCLI": "Pomocou CLI",
"SeeDetails": "Pozri podrobnosti",
- "AbpShortDescription": "ABP Framework je kompletná infraštruktúra na vytváranie moderných webových aplikácií podľa najlepších postupov a konvencií vývoja softvéru.",
+ "AbpShortDescription": "ABP Framework je kompletná infraštruktúra na vytváranie softvérových riešení s modernými architektúrami založenými na platforme ASP.NET Core.",
"SourceCodeUpper": "ZDROJOVÝ KÓD",
"LatestReleaseLogs": "Najnovšie release logy",
"Infrastructure": "Infraštruktúra",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sl.json
index c7a1f495f2..01c8683215 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/sl.json
@@ -16,7 +16,7 @@
"Tutorial": "Vadnica",
"UsingCLI": "Uporaba CLI",
"SeeDetails": "Glejte Podrobnosti",
- "AbpShortDescription": "ABP Framework je popolna infrastruktura za ustvarjanje sodobnih spletnih aplikacij z upoštevanjem najboljših praks in konvencij pri razvoju programske opreme.",
+ "AbpShortDescription": "ABP Framework je celovita infrastruktura za ustvarjanje programskih rešitev s sodobnimi arhitekturami, ki temeljijo na platformi ASP.NET Core.",
"SourceCodeUpper": "IZVORNA KODA",
"LatestReleaseLogs": "Najnovejši dnevniki izdaje",
"Infrastructure": "Infrastruktura",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
index dcc04e9f79..f3b440e785 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
@@ -16,7 +16,7 @@
"Tutorial": "Öğretici",
"UsingCLI": "CLI Kullanmak",
"SeeDetails": "Detayları Görüntüle",
- "AbpShortDescription": "ABP modern web uygulamaları geliştirmek için eksiksiz bir mimari ve günlü bir altyapıdır! Size SOLID geliştirme tecrübelerini sunmak için en iyi uygulama ve kuralları takip eder.",
+ "AbpShortDescription": "ABP Framework, ASP.NET Core platformunu temel alan modern mimarilerle yazılım çözümleri oluşturmaya yönelik eksiksiz bir altyapıdır.",
"SourceCodeUpper": "KAYNAK KOD",
"LatestReleaseLogs": "Son release kayıtları",
"Infrastructure": "Altyapı",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/vi.json
index b67ff75480..1092c8d9c0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/vi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/vi.json
@@ -16,7 +16,7 @@
"Tutorial": "Hướng dẫn",
"UsingCLI": "Sử dụng CLI",
"SeeDetails": "Xem chi tiết",
- "AbpShortDescription": "ABP Framework là một cơ sở hạ tầng hoàn chỉnh để tạo ra các ứng dụng web hiện đại bằng cách tuân theo các quy ước và thực tiễn tốt nhất về phát triển phần mềm.",
+ "AbpShortDescription": "ABP Framework là cơ sở hạ tầng hoàn chỉnh để tạo ra các giải pháp phần mềm có kiến trúc hiện đại dựa trên nền tảng ASP.NET Core.",
"SourceCodeUpper": "MÃ NGUỒN",
"LatestReleaseLogs": "Nhật ký phát hành mới nhất",
"Infrastructure": "Cơ sở hạ tầng",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
index 7fca00dd3e..c189506dd1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
@@ -16,7 +16,7 @@
"Tutorial": "教程",
"UsingCLI": "使用CLI",
"SeeDetails": "见详细",
- "AbpShortDescription": "ABP是用于创建现代Web应用程序的完整架构和强大的基础设施! 遵循最佳实践和约定,为你提供SOLID开发经验.",
+ "AbpShortDescription": "ABP Framework 是一个完整的基础架构,用于创建基于 ASP.NET Core 平台的现代架构的软件解决方案。",
"SourceCodeUpper": "源代码",
"LatestReleaseLogs": "最新发布日志",
"Infrastructure": "基础设施",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
index e3e3ded37c..9e12b4801e 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
@@ -16,7 +16,7 @@
"Tutorial": "教學",
"UsingCLI": "使用CLI",
"SeeDetails": "看詳細",
- "AbpShortDescription": "ABP是用於建立現代Web應用程式的完整架構和強大的基礎設施! 遵循最佳實作和約定,為您提供SOLID開發經驗.",
+ "AbpShortDescription": "ABP Framework 是一個完整的基礎架構,用於建立基於 ASP.NET Core 平台的現代架構的軟體解決方案。",
"SourceCodeUpper": "原始碼",
"LatestReleaseLogs": "最新發佈日誌",
"Infrastructure": "基礎設施",
diff --git a/common.props b/common.props
index e7ecc39b83..b39a45b734 100644
--- a/common.props
+++ b/common.props
@@ -1,7 +1,7 @@
latest
- 7.4.2
+ 8.0.0$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
@@ -18,7 +18,7 @@
-
+ allruntime; build; native; contentfiles; analyzers
diff --git a/configureawait.props b/configureawait.props
index 93d9dfa6a4..4356600b62 100644
--- a/configureawait.props
+++ b/configureawait.props
@@ -1,7 +1,7 @@
-
-
+
+ Allruntime; build; native; contentfiles; analyzers
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/POST.md b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/POST.md
new file mode 100644
index 0000000000..c7d8411886
--- /dev/null
+++ b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/POST.md
@@ -0,0 +1,287 @@
+# ABP.IO Platform 7.4 RC Has Been Released
+
+Today, we are happy to release the [ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) version **7.4 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version.
+
+Try this version and provide feedback for a more stable version of ABP v7.4! Thanks to all of you.
+
+## Get Started with the 7.4 RC
+
+Follow the steps below to try version 7.4.0 RC today:
+
+1) **Upgrade** the ABP CLI to version `7.4.0-rc.1` using a command line terminal:
+
+````bash
+dotnet tool update Volo.Abp.Cli -g --version 7.4.0-rc.1
+````
+
+**or install** it if you haven't before:
+
+````bash
+dotnet tool install Volo.Abp.Cli -g --version 7.4.0-rc.1
+````
+
+2) Create a **new application** with the `--preview` option:
+
+````bash
+abp new BookStore --preview
+````
+
+See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options.
+
+> You can also use the [Get Started](https://abp.io/get-started) page to generate a CLI command to create a new application.
+
+You can use any IDE that supports .NET 7.x, like [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/).
+
+## Migration Guides
+
+There are a few breaking changes in this version that may affect your application.
+Please see the following migration documents, if you are upgrading from v7.3 or earlier:
+
+* [ABP Framework 7.3 to 7.4 Migration Guide](https://docs.abp.io/en/abp/7.4/Migration-Guides/Abp-7_4)
+
+## What's New with ABP Framework 7.4?
+
+In this section, I will introduce some major features released in this version. Here is a brief list of the titles that will be explained in the next sections:
+
+* Dynamic Setting Store
+* Introducing the `AdditionalAssemblyAttribute`
+* `CorrelationId` Support on Distributed Events
+* Database Migration System for EF Core
+* Other News
+
+### Dynamic Setting Store
+
+Prior to this version, it was hard to define settings in different microservices and centrally manage all setting definitions in a single admin application. To make that possible, we used to add project references for all the microservices' service contract packages from a single microservice, so it can know all the setting definitions and manage them.
+
+In this version, ABP Framework introduces the Dynamic Setting Store, which is an important feature that allows you to collect and get all setting definitions from a single point and overcome the setting management problems on microservices.
+
+> *Note*: If you are upgrading from an earlier version and using the Setting Management module, you need to create a new migration and apply it to your database because a new database table has been added for this feature.
+
+### Introducing the `AdditionalAssemblyAttribute`
+
+In this version, we have introduced the `AdditionalAssemblyAttribute` to define additional assemblies to be part of a module. ABP Framework automatically registers all the services of your module to the [Dependency Injection System](https://docs.abp.io/en/abp/latest/Dependency-Injection). It finds the service types by scanning types in the assembly that define your module class. Typically, every assembly contains a separate module class definition and modules depend on each other using the `DependsOn` attribute.
+
+In some rare cases, your module may consist of multiple assemblies and only one of them defines a module class, and you want to make the other assemblies parts of your module. This is especially useful if you can't define a module class in the target assembly or you don't want to depend on that module's dependencies.
+
+In that case, you can use the `AdditionalAssembly` attribute as shown below:
+
+```csharp
+[DependsOn(...)] // Your module dependencies as you normally would do
+[AdditionalAssembly(typeof(IdentityServiceModule))] // A type in the target assembly (in another assembly)
+public class IdentityServiceTestModule : AbpModule
+{
+ ...
+}
+```
+
+With the `AdditionalAssembly` attribute definition, ABP loads the assembly containing the `IdentityServiceModule` class as a part of the identity service module. Notice that in this case, none of the module dependencies of the `IdentityServiceModule` are loaded. Because we are not depending on the `IdentityServiceModule`, instead we are just adding its assembly as a part of the `IdentityServiceTestModule`.
+
+> You can check the [Module Development Basics](https://docs.abp.io/en/abp/7.4/Module-Development-Basics) documentation to learn more.
+
+### `CorrelationId` Support on Distributed Events
+
+In this version, `CorrelationId` (a unique key that is used in distributed applications to trace requests across multiple services/operations) is attached to the distributed events, so you can relate events with HTTP requests and can trace all the related activities.
+
+ABP Framework generates a `correlationId` for the first time when an operation is started and then attaches the current `correlationId` to distributed events as an additional property. For example, if you are using the [transactional outbox or inbox pattern provided by ABP Framework](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#outbox-inbox-for-transactional-events), you can see the `correlationId` in the extra properties of the `IncomingEventInfo` or `OutgoingEventInfo` classes with the standard `X-Correlation-Id` key.
+
+> You can check [this issue](https://github.com/abpframework/abp/issues/16773) for more information.
+
+### Database Migration System for EF Core
+
+In this version, ABP Framework provides base classes and events to migrate the database schema and seed the database on application startup. This system works compatibly with multi-tenancy and whenever a new tenant is created or a tenant's database connection string has been updated, it checks and applies database migrations for the new tenant state.
+
+This system is especially useful to migrate databases for microservices. In this way, when you deploy a new version of a microservice, you don't need to manually migrate its database.
+
+You need to take the following actions to use the database migration system:
+
+* Create a class that derives from `EfCoreRuntimeDatabaseMigratorBase` class, override and implement its `SeedAsync` method. And lastly, execute the `CheckAndApplyDatabaseMigrationsAsync` method of your class in the `OnPostApplicationInitializationAsync` method of your module class.
+* Create a class that derives from `DatabaseMigrationEventHandlerBase` class, override and implement its `SeedAsync` method. Then, whenever a new tenant is created or a tenant's connection string is changed then the `SeedAsync` method will be executed.
+
+### Other News
+
+* [OpenIddict](https://github.com/openiddict/openiddict-core/tree/4.7.0) library has been upgraded to **v4.7.0**. See [#17334](https://github.com/abpframework/abp/pull/17334) for more info.
+* ABP v7.4 introduces the `Volo.Abp.Maui.Client` package, which is used by the MAUI mobile application in ABP Commercial. See [#17201](https://github.com/abpframework/abp/pull/17201) for more info.
+* In this version, the `AbpAspNetCoreIntegratedTestBase` class gets a generic type parameter, which expects either a startup class or an ABP module class. This allows us to use configurations from an ABP module or old-style ASP.NET Core Startup class in a test application class and this simplifies the test application project. See [#17039](https://github.com/abpframework/abp/pull/17039) for more info.
+
+## What's New with ABP Commercial 7.4?
+
+We've also worked on [ABP Commercial](https://commercial.abp.io/) to align the features and changes made in the ABP Framework. The following sections introduce new features coming with ABP Commercial 7.4.
+
+### Dynamic Text Template Store
+
+Prior to this version, it was hard to create text templates in different microservices and centrally manage them in a single admin application. For example, if you would define a text template in your ordering microservice, then those text templates could not be seen on the administration microservice because the administration microservice would not have any knowledge about that text template (because it's hard-coded in the ordering microservice).
+
+For this reason, in this version, the Dynamic Text Template Store has been introduced to make the [Text Template Management module](https://docs.abp.io/en/commercial/latest/modules/text-template-management) compatible with microservices and distributed systems. It allows you to store and get all text templates from a single point. Thanks to that, you can centrally manage the text templates in your admin application.
+
+> *Note*: If you are upgrading from an earlier version and are using the Text Template Management module, you need to create a new migration and apply it to your database.
+
+To enable the dynamic template store, you just need to configure the `TextTemplateManagementOptions` and set the `IsDynamicTemplateStoreEnabled` as true in your module class:
+
+```csharp
+Configure(options =>
+{
+ options.IsDynamicTemplateStoreEnabled = true;
+});
+```
+
+Notice this is only needed in the microservice where you centrally manage your text template contents. So, typically you would use the configuration above in your administration microservice. Other microservices automatically save their text template contents to the central database.
+
+### Suite: Custom Code Support
+
+In this version, we have implemented the custom code support in Suite. This allows you to customize the generated code-blocks and preserve your custom code changes in the next CRUD Page Generation in Suite. ABP Suite specifies hook-points to allow adding custom code blocks. Then, the code that you wrote to these hook points will be respected and will not be overridden in the next entity generation.
+
+
+
+To enable custom code support, you should check the *Customizable code* option in the crud page generation page. When you enable the custom code support, you will be seeing some hook-points in your application.
+
+For example, on the C# side, you'll be seeing some abstract classes and classes that derive from them (for entities, application services, interfaces, domain services, and so on...). You can write your custom code in those classes (`*.Extended.cs`) and the next time when you need to re-generate the entity, your custom code will not be overridden (only the base abstract classes will be re-generated and your changes on Suite will be respected):
+
+Folder structure | Book.Extended.cs
+:-------------------------:|:-------------------------:
+ | 
+
+> *Note*: If you want to override the entity and add custom code, please do not touch the code between `...` placeholders, because the constructor of the entity should be always re-generated in case of a new property added.
+
+On the UI side, you can see the *comment placeholders* on the pages for MVC & Blazor applications. These are hook-points provided by ABP Suite and you can write your custom code between these comment sections:
+
+Folder structure | Books/Index.cshtml
+:-------------------------:|:-------------------------:
+ | 
+
+### MAUI & React Native UI Revisions
+
+In this version, we have revised MAUI & React Native mobile applications and added new pages, functionalities and made improvements on the UI side.
+
+
+
+For example, in the MAUI application, we have implemented the following functionalities and changed the UI completely:
+
+* **User Management Page**: Management page for your application users. You can search, add, update, or delete users of your application.
+* **Tenants**: Management page for your tenants.
+* **Settings**: Management page for your application settings. On this page, you can change **the current language**, **the profile picture**, **the current password**, or/and **the current theme**.
+
+Also, we have aligned the features on both of these mobile options (MAUI & React Native) and showed them in the ["ABP Community Talks 2023.5: Exploring the Options for Mobile Development with the ABP Framework"](https://community.abp.io/events/mobile-development-with-the-abp-framework-ogtwaz5l).
+
+> If you have missed the event, you can watch from 👉 [here](https://www.youtube.com/watch?v=-wrdngeKgZw).
+
+### New LeptonX Theme Features
+
+In the new version of LeptonX Theme, which is v2.4.0-rc.1, there are some new features that we want to mention.
+
+#### Mobile Toolbars
+
+The [Toolbar System](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) is used to define *toolbars* on the user interface. Modules (or your application) can add items to a toolbar, then the UI themes can render the toolbar on the layout.
+
+LeptonX Theme extends this system even further and introduces mobile toolbars with this version. You can create a component and add it as a mobile toolbar as below:
+
+```csharp
+public class MyToolbarContributor : IToolbarContributor
+{
+ public Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
+ {
+ if (context.Toolbar.Name == LeptonXToolbars.MainMobile)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(ShoppingCardToolbarComponent)));
+
+ //other mobile toolbars...
+ }
+
+ return Task.CompletedTask;
+ }
+}
+```
+
+Then, the LeptonX Theme will render these mobile toolbars like in the figure below:
+
+
+
+> **Note**: The Angular UI hasn't been completed yet. We aim to complete it as soon as possible and include it in the next release.
+
+#### New Error Page Designs
+
+In this version, we have implemented new error pages. Encounter a fresh look during error situations with the 'New Error Page Designs,' providing informative and visually appealing error displays that enhance user experience:
+
+
+
+#### Fluid Layout
+
+In this version, LeptonX Theme introduces the fresh-looking **Fluid Layout**, which is a layout that lets you align elements so that they automatically adjust their alignment and proportions for different page sizes and orientations.
+
+
+
+> You can visit [the live demo of LeptonX Theme](https://x.leptontheme.com/side-menu) and try the Fluid Layout now!
+
+### Check & Move Related Entities on Deletion/Demand
+
+In application modules, there are some entities that have complete relationships with each other such as role-user relations. In such cases, it's a typical requirement to check & move related entities that have a relation with the other entity that is about to be deleted.
+
+For example, if you need to delete an edition from your system, you would typically want to move the tenant that is associated with that edition. For this purpose, in this version, ABP Commercial allows you to move related entities on deletion/demand.
+
+
+
+Currently, this feature is implemented for SaaS and Identity Pro modules and for the following relations:
+
+* Edition - Tenant
+* Role - User
+* Organization Unit - User
+
+Also, it's possible to move the related associated-records before deleting the record. For example, you can move all tenants from an edition as shown in the figure below:
+
+"Move all tenants" action | "Move all tenants" modal
+:-------------------------:|:-------------------------:
+ | 
+
+### CMS Kit Pro: Page Feedback
+
+In this version, the **Page Feedback** feature has been added to the [CMS Kit Pro](https://docs.abp.io/en/commercial/latest/modules/cms-kit/index) module. This feature allows you to get feedback from a page in your application.
+
+This is especially useful if you have content that needs feedback from users. For example, if you have documentation or a blog website, it's a common requirement to assess the quality of the articles and get feedback from users. In that case, you can use this feature:
+
+
+
+### Chat Module: Deleting Messages & Conversations
+
+In this version, the [Chat Module](https://docs.abp.io/en/commercial/latest/modules/chat) allows you to delete individual messages or a complete conversation.
+
+You can enable or disable the message/conversation deletion globally on your application:
+
+
+
+> **Note**: The Angular UI hasn't been completed yet. We aim to complete it as soon as possible and include it in the next release.
+
+### Password Complexity Indicators
+
+In this version, ABP Framework introduces an innovative ["Password Complexity Indicator"](https://docs.abp.io/en/commercial/7.4/ui/angular/password-complexity-indicator-component) feature, designed to enhance security and user experience. This feature dynamically evaluates and rates the strength of user-generated passwords, providing real-time feedback to users as they create or update their passwords. By visually indicating the complexity level, users are guided toward crafting stronger passwords that meet modern security standards.
+
+
+
+You can check the [Password Complexity Indicator Angular documentation](https://docs.abp.io/en/commercial/7.4/ui/angular/password-complexity-indicator-component) to learn more.
+
+> **Note**: Currently, this feature is only available for the Angular UI, but we will be implemented for other UIs in the next version.
+
+## Community News
+
+### DevNot Developer Summit 2023
+
+
+
+We are thrilled to announce that the co-founder of [Volosoft](https://volosoft.com/) and Lead Developer of the ABP Framework, Halil Ibrahim Kalkan will give a speech about "Building a Kubernetes Integrated Local Development Environment" in the [Developer Summit 2023 event](https://summit.devnot.com/) on the 7th of October.
+
+### New ABP Community Posts
+
+There are exciting articles contributed by the ABP community as always. I will highlight some of them here:
+
+* [ABP Commercial - GDPR Module Overview](https://community.abp.io/posts/abp-commercial-gdpr-module-overview-kvmsm3ku) by [Engincan Veske](https://twitter.com/EngincanVeske)
+* [Video: ABP Framework Data Transfer Objects](https://community.abp.io/videos/abp-framework-data-transfer-objects-qwebfqz5) by [Hamza Albreem](https://github.com/braim23)
+* [Video: ABP Framework Essentials: MongoDB](https://community.abp.io/videos/abp-framework-essentials-mongodb-gwlblh5x) by [Hamza Albreem](https://github.com/braim23)
+* [ABP Modules and Entity Dependencies](https://community.abp.io/posts/abp-modules-and-entity-dependencies-hn7wr093) by [Jack Fistelmann](https://github.com/nebula2)
+* [How to add dark mode support to the Basic Theme in 3 steps?](https://community.abp.io/posts/how-to-add-dark-mode-support-to-the-basic-theme-in-3-steps-ge9c0f85) by [Enis Necipoğlu](https://twitter.com/EnisNecipoglu)
+* [Deploying docker image to Azure with yml and bicep through Github Actions](https://community.abp.io/posts/deploying-docker-image-to-azure-with-yml-and-bicep-through-github-actions-cjiuh55m) by [Sturla](https://community.abp.io/members/Sturla)
+
+Thanks to the ABP Community for all the content they have published. You can also [post your ABP-related (text or video) content](https://community.abp.io/articles/submit) to the ABP Community.
+
+## Conclusion
+
+This version comes with some new features and a lot of enhancements to the existing features. You can see the [Road Map](https://docs.abp.io/en/abp/7.4/Road-Map) documentation to learn about the release schedule and planned features for the next releases. Please try ABP v7.4 RC and provide feedback to help us release a more stable version.
+
+Thanks for being a part of this community!
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cs.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cs.png
new file mode 100644
index 0000000000..1179118621
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cs.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cshtml.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cshtml.png
new file mode 100644
index 0000000000..0ed90a33de
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/book-extended-cshtml.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/cover-image.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/cover-image.png
new file mode 100644
index 0000000000..06ced79397
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/cover-image.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/developersummit.jpg b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/developersummit.jpg
new file mode 100644
index 0000000000..65bae90315
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/developersummit.jpg differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/editions.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/editions.png
new file mode 100644
index 0000000000..331706daa7
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/editions.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/error-page.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/error-page.png
new file mode 100644
index 0000000000..8ece260ec3
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/error-page.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/fluid-layout.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/fluid-layout.png
new file mode 100644
index 0000000000..6150f3e2bd
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/fluid-layout.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/maui.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/maui.png
new file mode 100644
index 0000000000..4205001d80
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/maui.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/mobile-toolbars.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/mobile-toolbars.png
new file mode 100644
index 0000000000..6dcde5da60
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/mobile-toolbars.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-all-tenants.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-all-tenants.png
new file mode 100644
index 0000000000..b893360447
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-all-tenants.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-tenants.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-tenants.png
new file mode 100644
index 0000000000..fb6b8364fb
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/move-tenants.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/page-feedback.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/page-feedback.png
new file mode 100644
index 0000000000..dbdd9fe199
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/page-feedback.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/password-complexity.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/password-complexity.png
new file mode 100644
index 0000000000..55bc8a8f43
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/password-complexity.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/settings.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/settings.png
new file mode 100644
index 0000000000..1e835661a0
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/settings.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-backend.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-backend.png
new file mode 100644
index 0000000000..cb14dfc0f1
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-backend.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-ui.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-ui.png
new file mode 100644
index 0000000000..132988a873
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code-ui.png differ
diff --git a/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code.png b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code.png
new file mode 100644
index 0000000000..2e510d0768
Binary files /dev/null and b/docs/en/Blog-Posts/2023-08-15 v7_4_Preview/suite-custom-code.png differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/POST.md b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/POST.md
new file mode 100644
index 0000000000..604d4c5c6c
--- /dev/null
+++ b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/POST.md
@@ -0,0 +1,98 @@
+# Unleash the Power of ABP CMS Kit: A Dynamic Content Showcase
+
+We're excited to introduce to you [ABP](https://abp.io/)'s [CMS Kit Module](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Index) – a versatile module that empowers you to build your own dynamic content website with ease. In this introductory blog post, we'll first take a look at the **CMS Kit Module** and then we'll take you on a journey through our **CMS Kit Demo Application**, showcasing the incredible capabilities of this feature-rich module.
+
+## Overview of the CMS Kit Module
+
+At the heart of ABP's CMS Kit Module is a robust Content Management System (CMS) designed to simplify content creation and management. With the CMS Kit, you have the tools to build your own dynamic content website, complete with a range of features tailored to your specific needs. It provides core **building blocks** and fully working sub-systems to create your own website with the CMS features or use the building blocks in your websites for any purpose.
+
+### CMS Kit: The Building Blocks (a.k.a Features)
+
+The following features are currently available and ready to use:
+
+* **Blogging**: Create your blog and publish posts (with markdown / HTML support)
+* **Dynamic Pages**: Create pages with dynamic URLs (with markdown / HTML support)
+* **Dynamic Menu**: Manage your application’s main menu on the fly
+* **Tagging**: Tag any kind of content, like a blog post
+* **Comments**: Allow users to comment and discuss in your application
+* **Reactions**: Allow users to react to your content using simple smileys
+* **Rating**: Reusable component to rate other contents
+* **Global Resources**: Dynamically add CSS / JavaScript to your pages or blog posts
+* **Dynamic Widgets**: Build widgets and use them in dynamic content, like blog posts
+
+> For more information, please check the [CMS Kit Module documentation](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Index). In the documentation, you can see descriptions for each feature, learn how to install & configure the module, and much more...
+
+### CMS Kit Pro: The Building Blocks (a.k.a Features)
+
+CMS Kit Pro is a part of [ABP Commercial](https://commercial.abp.io/) and provides additional features. The following features are provided by the CMS Kit Pro Module:
+
+* **Contact Form**: Easily add a «contact us» form to your website
+* **Newsletter**: Allow users to subscribe to your newsletter (with multiple categories)
+* **URL Forwarding**: Create short URLs or redirect users to other pages (for example: [abp.io/dapr](https://abp.io/dapr))
+* **Poll**: Create quick polls for your users
+* **Page Feedback**: Collect feedbacks from users for your content
+
+> For more information, check the [CMS Kit Pro Module documentation](https://docs.abp.io/en/commercial/latest/modules/cms-kit/index).
+
+## Explore the CMS Kit Demo Application
+
+As the core ABP development team, we've created a sample application to showcase the incredible capabilities of the ABP's CMS Kit Module. You can explore the source code of the application on our [GitHub repository](https://github.com/abpframework/cms-kit-demo) to get a deeper understanding of how the CMS Kit works under the hood. While developing the application, we aimed to build a real-world application and use almost all of the CMS Kit Features.
+
+In the next sections, we will provide a detailed walkthrough of the application and highlight each CMS Kit feature that has been incorporated into it.
+
+### Dynamic Menu Creation with CMS Kit's Menu System
+
+One of the standing out features of the CMS Kit is its [Menu System](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Menus), which allows for the creation and dynamic ordering of application menu items. Say goodbye to static menus; with CMS Kit, you have the power to tailor your menu structure according to your evolving content needs.
+
+You can see the homepage of the application in the following figure:
+
+
+
+The application menu items in the navbar are **created & ordered dynamically** with the [CMS Kit's Menu System](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Menus):
+
+
+
+### Custom Implementations with Comment & Reaction Features
+
+Our demo application goes a step further by demonstrating custom implementations, such as an **image gallery**, seamlessly integrated with CMS Kit's [Comment](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Comments) & [Reaction](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Reactions) Features:
+
+| Gallery | Detail Page |
+|------------------------ |-----------------------|
+|  |  |
+
+It's pretty easy to integrate CMS Kit Features such as Comments & Reactions into your existing pages. You can check the [source code of the application](https://github.com/abpframework/cms-kit-demo/blob/main/src/CmsKitDemo/Pages/Gallery/Detail.cshtml) and see how to integrate the features.
+
+### Robust Blogging Capabilities
+
+Blogging has never been easier! With the CMS Kit's [Blogging Feature](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Blogging), you can effortlessly manage your blog content, complete with [Ratings](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Ratings), [Comments](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Comments), [Tags](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Tags), and [Reactions](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Reactions) features as enabled:
+
+| Blog | Blog Post |
+|------------------------ |-----------------------|
+|  |  |
+
+You can enable/disable CMS Kit Features per blog on the admin side easily:
+
+
+
+### Dynamic Pages with Style and Script Integration
+
+*Products* pages showcase the flexibility of the CMS Kit's [Pages Feature](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Pages), allowing for dynamic content creation, style customization, and script integration. Your website can now truly reflect your unique brand and content style.
+
+You can create pages with dynamic URLs on the admin side:
+
+
+
+After you have created the page, you can access it via `/{slug}` URL on the public-web side:
+
+
+
+## What's Next?
+
+Please try the CMS Kit Module now and provide [feedback](https://github.com/abpframework/abp) to help us to build a more effective content management kit!
+
+## Resources
+
+* [CMS Kit Demo: Source Code](https://github.com/abpframework/cms-kit-demo)
+* [cms-kit-demo.abp.io](https://cms-kit-demo.abp.io/)
+* [CMS Kit Module documentation](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Index)
+* [CMS Kit Pro Module documentation](https://docs.abp.io/en/commercial/latest/modules/cms-kit/index)
\ No newline at end of file
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blog-detail.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blog-detail.jpg
new file mode 100644
index 0000000000..d1e2a06f94
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blog-detail.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blogs.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blogs.jpg
new file mode 100644
index 0000000000..70d276349c
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/blogs.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/cmskit-module-features.png b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/cmskit-module-features.png
new file mode 100644
index 0000000000..b6dd409e0a
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/cmskit-module-features.png differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/homepage.png b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/homepage.png
new file mode 100644
index 0000000000..3c485415aa
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/homepage.png differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery-detail.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery-detail.jpg
new file mode 100644
index 0000000000..70ea35ea2d
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery-detail.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery.jpg
new file mode 100644
index 0000000000..b8b6291342
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/image-gallery.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/menu-admin-side.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/menu-admin-side.jpg
new file mode 100644
index 0000000000..c4dd12275e
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/menu-admin-side.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/pages-admin-side.jpg b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/pages-admin-side.jpg
new file mode 100644
index 0000000000..27ba597e13
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/pages-admin-side.jpg differ
diff --git a/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/products-abp-commercial.png b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/products-abp-commercial.png
new file mode 100644
index 0000000000..0401a947f5
Binary files /dev/null and b/docs/en/Blog-Posts/2023-09-23-CMS-Kit-Demo/products-abp-commercial.png differ
diff --git a/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/POST.md b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/POST.md
new file mode 100644
index 0000000000..9ce3e26967
--- /dev/null
+++ b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/POST.md
@@ -0,0 +1,80 @@
+# ABP.IO Platform 7.4 Final Has Been Released!
+
+[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 7.4 versions have been released today.
+
+## What's New With Version 7.4?
+
+All the new features were already explained in detail in the [7.4 RC Announcement Post](https://blog.abp.io/abp/ABP.IO-Platform-7-4-RC-Has-Been-Published), so no need to go over them again. Check it out for more details.
+
+## Getting Started with 7.4
+
+### Creating New Solutions
+
+You can create a new solution with the ABP Framework version 7.4 by either using the `abp new` command or generating the CLI command on the [get started page](https://abp.io/get-started).
+
+> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for more.
+
+### How to Upgrade an Existing Solution
+
+#### Install/Update the ABP CLI
+
+First of all, install the ABP CLI or upgrade it to the latest version.
+
+If you haven't installed it yet:
+
+```bash
+dotnet tool install -g Volo.Abp.Cli
+```
+
+To update the existing CLI:
+
+```bash
+dotnet tool update -g Volo.Abp.Cli
+```
+
+#### Upgrading Existing Solutions with the ABP Update Command
+
+[ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command:
+
+```bash
+abp update
+```
+
+Run this command in the root folder of your solution.
+
+## Migration Guides
+
+There are breaking changes in this version that may affect your application.
+Please see the following migration documents, if you are upgrading from v7.3:
+
+* [ABP Framework 7.3 to 7.4 Migration Guide](https://docs.abp.io/en/abp/7.4/Migration-Guides/Abp-7_4)
+
+## Community News
+
+### ABP Community Talks 2023.7: Build Your Content Management System with .NET
+
+We as the ABP team organized the [**ABP Community Talks 2023.7: Build Your Content Management System with .NET**](https://community.abp.io/events/build-your-own-cms-with-.net-a-first-look-at-abps-content-management-system-kit-3nfvm9ix) event to explore the depths of the CMS Kit Module and its real-world applications. The talk delved into the intricacies of the CMS Kit Module, providing valuable insights into its features and functionalities. Attendees had the opportunity to witness the module in action through live demonstrations and interactive Q&A sessions.
+
+For those who missed the live session, you can catch up on all the enriching discussions and demonstrations by watching the record below 👇:
+
+
+
+### BASTA! Mainz 2023
+
+
+
+BASTA! Mainz 2023 has wrapped up, and what an extraordinary journey it has been! We have shared our impressions, highlights, and the incredible impact it had on the tech community in Germany and beyond in a blog post, which you can find at [https://blog.abp.io/abp/BASTA-Mainz-2023-What-a-Blast-in-Germany](https://blog.abp.io/abp/BASTA-Mainz-2023-What-a-Blast-in-Germany).
+
+### New ABP Community Posts
+
+There are exciting articles contributed by the ABP community as always. I will highlight some of them here:
+
+* [Moving Background Job Execution To A Separate Application](https://community.abp.io/posts/moving-background-job-execution-to-a-separate-application-my9cgo9a) by [liangshiwei](https://github.com/RealLowis).
+* [Cascading Option Loading with Extensions System in ABP Angular](https://community.abp.io/posts/cascading-option-loading-with-extensions-system-in-abp-angular-gcxgp0v9) by [Masum Ulu](https://twitter.com/masumulu).
+* [How to use domain-based tenant resolver in ABP with Angular and OpenIddict](https://community.abp.io/posts/how-to-use-domainbased-tenant-resolver-in-abp-with-angular-and-openiddict-v9y8da7v) by [Mahmut Gündoğdu](https://twitter.com/MahmutGundogdu).
+
+Thanks to the ABP Community for all the content they have published. You can also [post your ABP-related (text or video) content](https://community.abp.io/articles/submit) to the ABP Community.
+
+## About the Next Version
+
+The next feature version will be 8.0. You can follow the [release planning here](https://github.com/abpframework/abp/milestones). Please [submit an issue](https://github.com/abpframework/abp/issues/new) if you have any problems with this version.
diff --git a/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/abp-community-talk.png b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/abp-community-talk.png
new file mode 100644
index 0000000000..80938f8e06
Binary files /dev/null and b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/abp-community-talk.png differ
diff --git a/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/basta-mainz.png b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/basta-mainz.png
new file mode 100644
index 0000000000..a84abea379
Binary files /dev/null and b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/basta-mainz.png differ
diff --git a/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/cover-image.png b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/cover-image.png
new file mode 100644
index 0000000000..06ced79397
Binary files /dev/null and b/docs/en/Blog-Posts/2023-10-09 v7_4_Release_Stable/cover-image.png differ
diff --git a/docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md b/docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md
index 6abf984298..ae688d6981 100644
--- a/docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md
+++ b/docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md
@@ -594,7 +594,7 @@ namespace BookStore.EntityFrameworkCore
/* Configure your own tables/entities inside here */
builder.Entity(b =>
{
- b.ToTable(BookStoreConsts.DbTablePrefix + "Authors" + BookStoreConsts.DbSchema);
+ b.ToTable(BookStoreConsts.DbTablePrefix + "Authors", BookStoreConsts.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name)
@@ -608,7 +608,7 @@ namespace BookStore.EntityFrameworkCore
builder.Entity(b =>
{
- b.ToTable(BookStoreConsts.DbTablePrefix + "Books" + BookStoreConsts.DbSchema);
+ b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name)
@@ -624,7 +624,7 @@ namespace BookStore.EntityFrameworkCore
builder.Entity(b =>
{
- b.ToTable(BookStoreConsts.DbTablePrefix + "Categories" + BookStoreConsts.DbSchema);
+ b.ToTable(BookStoreConsts.DbTablePrefix + "Categories", BookStoreConsts.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name)
@@ -634,7 +634,7 @@ namespace BookStore.EntityFrameworkCore
builder.Entity(b =>
{
- b.ToTable(BookStoreConsts.DbTablePrefix + "BookCategories" + BookStoreConsts.DbSchema);
+ b.ToTable(BookStoreConsts.DbTablePrefix + "BookCategories", BookStoreConsts.DbSchema);
b.ConfigureByConvention();
//define composite key
diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md
index a8f1aeadfa..73d2e6bad5 100644
--- a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md
+++ b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md
@@ -315,7 +315,7 @@ import { CreateBookComponent } from './create-book/create-book.component';
import { EditBookComponent } from './edit-book/edit-book.component';
const routes: Routes = [
- { path: '', component: BookComponent, canActivate: [AuthGuard, PermissionGuard] },
+ { path: '', component: BookComponent, canActivate: [authGuard, permissionGuard] },
{ path: 'create', component: CreateBookComponent },
{ path: 'edit/:id', component: EditBookComponent },
];
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md
new file mode 100644
index 0000000000..2db041436c
--- /dev/null
+++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md
@@ -0,0 +1,450 @@
+# Cascading Option Loading with Extensions System in ABP Angular
+
+This article will show how to load cascading options with an extensions system in ABP Angular. For this example, we'll simulate renting a book process. Besides our default form properties, we'll contribute `Name` property to our `Rent Form Modal` in the Books module. This property will be loaded after `Genre` is selected.
+
+> Before starting this article, I suggest you read the [ABP Angular Dynamic Form Extensions](https://docs.abp.io/en/abp/latest/UI/Angular/Dynamic-Form-Extensions)
+
+### Environment
+
+- **ABP Framework Version:** ~7.3.0 (`~` means that use the latest patch version of the specified release)
+- **DB Provider:** MongoDB
+- **Angular Version:** ~16.0.0
+
+### Project structure
+
+The books module is not a library; for this demo, it'll placed in the application itself.
+
+
+
+- **books folder:** Contains default form properties, tokens, models, etc. It's similar to the ABP module structure.
+- Also I've used **standalone** and **signals** feature in this demo.
+- **books-extended folder:** Contains only `Name` property for the contribute `Rent Form Modal` inside the Books module.
+- **For more readability, I've used TS path aliases in this demo. Don't forget to export files in `index.ts` file 🙂**
+
+
+
+### First look at the demo
+
+
+
+### What is the Extension system?
+
+
+
+# Reviewing the code step by step
+
+**1. Create default form properties for `Rent Form` in the `Books` module**
+
+- `getInjected` function is the key point of the cascading loading
+- We can reach and track any value from `Service` or `Component`
+- In that way we can load options according to the selected value
+
+```ts
+// ~/books/defaults/default-books-form.props.ts
+
+import { Validators } from "@angular/forms";
+import { map, of } from "rxjs";
+import { ePropType, FormProp } from "@abp/ng.theme.shared/extensions";
+import { BookDto, AuthorService, BooksService } from "../proxy";
+import { RentBookComponent } from "../components";
+import { DefaultOption } from "../utils";
+
+const { required } = Validators;
+
+export const DEFAULT_RENT_FORM_PROPS = FormProp.createMany([
+ {
+ type: ePropType.String,
+ id: "authorId",
+ name: "authorId",
+ displayName: "BookStore::Author",
+ defaultValue: null,
+ validators: () => [required],
+ options: (data) => {
+ const { authors } = data.getInjected(AuthorService);
+
+ return of([
+ DefaultOption,
+ ...authors().map((author) => ({ value: author.id, key: author.name })),
+ ]);
+ },
+ },
+ {
+ type: ePropType.String,
+ id: "genreId",
+ name: "genreId",
+ displayName: "BookStore::Genre",
+ defaultValue: null,
+ validators: () => [required],
+ options: (data) => {
+ const rentBookComponent = data.getInjected(RentBookComponent);
+ const { genres } = data.getInjected(BooksService);
+
+ const genreOptions = genres().map(({ id, name }) => ({
+ value: id,
+ key: name,
+ }));
+
+ return rentBookComponent.form.controls.authorId.valueChanges.pipe(
+ map((value: string | undefined) =>
+ value ? [DefaultOption, ...genreOptions] : [DefaultOption]
+ )
+ );
+ },
+ },
+ {
+ type: ePropType.Date,
+ id: "returnDate",
+ name: "returnDate",
+ displayName: "BookStore::ReturnDate",
+ defaultValue: null,
+ validators: () => [required],
+ },
+]);
+```
+
+**2. Configure tokens and config options**
+
+The documentation explains these steps; that's why I won't explain it again. If documents or samples are not enough, please let me know in the comments 🙂
+
+**Extensions Token**
+
+```ts
+// ~/books/tokens/extensions.token.ts
+
+import { CreateFormPropContributorCallback } from "@abp/ng.theme.shared/extensions";
+import { InjectionToken } from "@angular/core";
+import { BookDto } from "../proxy";
+import { eBooksComponents } from "../enums";
+import { DEFAULT_RENT_FORM_PROPS } from "../defaults";
+
+export const DEFAULT_BOOK_STORE_CREATE_FORM_PROPS = {
+ [eBooksComponents.RentBook]: DEFAULT_RENT_FORM_PROPS,
+};
+
+export const BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS =
+ new InjectionToken(
+ "BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS"
+ );
+
+type CreateFormPropContributors = Partial<{
+ [eBooksComponents.RentBook]: CreateFormPropContributorCallback[];
+ /**
+ * Other creation form prop contributors...
+ */
+ // [eBooksComponents.CreateBook]: CreateFormPropContributorCallback[];
+}>;
+```
+
+**Extensions Config Option**
+
+```ts
+// ~/books/models/config-options.ts
+
+import { CreateFormPropContributorCallback } from "@abp/ng.theme.shared/extensions";
+import { BookDto } from "../proxy";
+import { eBooksComponents } from "../enums";
+
+export type BookStoreRentFormPropContributors = Partial<{
+ [eBooksComponents.RentBook]: CreateFormPropContributorCallback[];
+}>;
+
+export interface BooksConfigOptions {
+ rentFormPropContributors?: BookStoreRentFormPropContributors;
+}
+```
+
+**3. Extensions Guard**
+
+It'll to collect all contributors from [ExtensionsService](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/theme-shared/extensions/src/lib/services/extensions.service.ts)
+
+```ts
+// ~/books/guards/extensions.guard.ts
+
+import { Injectable, inject } from "@angular/core";
+import { Observable, map, tap } from "rxjs";
+import { ConfigStateService, IAbpGuard } from "@abp/ng.core";
+import {
+ ExtensionsService,
+ getObjectExtensionEntitiesFromStore,
+ mapEntitiesToContributors,
+ mergeWithDefaultProps,
+} from "@abp/ng.theme.shared/extensions";
+import {
+ BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS,
+ DEFAULT_BOOK_STORE_CREATE_FORM_PROPS,
+} from "../tokens";
+
+@Injectable()
+export class BooksExtensionsGuard implements IAbpGuard {
+ protected readonly configState = inject(ConfigStateService);
+ protected readonly extensions = inject(ExtensionsService);
+
+ canActivate(): Observable {
+ const createFormContributors =
+ inject(BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, { optional: true }) || {};
+
+ return getObjectExtensionEntitiesFromStore(
+ this.configState,
+ "BookStore"
+ ).pipe(
+ mapEntitiesToContributors(this.configState, "BookStore"),
+ tap((objectExtensionContributors) => {
+ mergeWithDefaultProps(
+ this.extensions.createFormProps,
+ DEFAULT_BOOK_STORE_CREATE_FORM_PROPS,
+ objectExtensionContributors.createForm,
+ createFormContributors
+ );
+ }),
+ map(() => true)
+ );
+ }
+}
+```
+
+Yes, I'm still using class-based guard 🙂 much more flexible...
+
+**4. RentBookComponent**
+
+- Our trackable variable is defined here `(form:FormGroup)`, which means We'll track this variable in `options` property at defaults || contributors files.
+- Providing `AuthorService`, also `EXTENSIONS_IDENTIFIER` for the reach dynamic properties
+
+```ts
+import {
+ ChangeDetectionStrategy,
+ Component,
+ EventEmitter,
+ Injector,
+ Output,
+ inject,
+} from "@angular/core";
+import { FormGroup } from "@angular/forms";
+import { CoreModule, uuid } from "@abp/ng.core";
+import { ThemeSharedModule } from "@abp/ng.theme.shared";
+import {
+ EXTENSIONS_IDENTIFIER,
+ FormPropData,
+ UiExtensionsModule,
+ generateFormFromProps,
+} from "@abp/ng.theme.shared/extensions";
+import { AuthorService, BookDto, BooksService } from "../../proxy";
+import { eBooksComponents } from "../../enums";
+
+@Component({
+ standalone: true,
+ selector: "app-rent-book",
+ templateUrl: "./rent-book.component.html",
+ imports: [CoreModule, UiExtensionsModule, ThemeSharedModule],
+ providers: [
+ {
+ provide: EXTENSIONS_IDENTIFIER,
+ useValue: eBooksComponents.RentBook,
+ },
+ AuthorService,
+ ],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class RentBookComponent {
+ protected readonly injector = inject(Injector);
+ protected readonly authorService = inject(AuthorService);
+ protected readonly booksService = inject(BooksService);
+
+ //#region Just for demo
+ readonly #authors = this.authorService.authors();
+ readonly #genres = this.booksService.genres();
+ readonly #books = this.booksService.books();
+ //#endregion
+
+ protected modalVisible = true;
+ @Output() modalVisibleChange = new EventEmitter();
+
+ selected: BookDto;
+ form: FormGroup;
+ modalBusy = false;
+
+ protected buildForm(): void {
+ const data = new FormPropData(this.injector, this.selected);
+ this.form = generateFormFromProps(data);
+ }
+
+ constructor() {
+ this.buildForm();
+ }
+
+ save(): void {
+ if (this.form.invalid) {
+ return;
+ }
+
+ this.modalBusy = true;
+
+ const { authorId, genreId, bookId, returnDate } = this.form.value;
+
+ //#region Just for demo
+ const authorName = this.#authors.find(({ id }) => id === authorId).name;
+ const genreName = this.#genres.find(({ id }) => id === genreId).name;
+ const bookName = this.#books.find(({ id }) => id === bookId).name;
+ //#endregion
+
+ this.booksService.rentedBooks.update((books) => [
+ {
+ id: uuid(),
+ name: bookName,
+ author: authorName,
+ genre: genreName,
+ returnDate,
+ },
+ ...books,
+ ]);
+
+ this.modalBusy = false;
+ this.modalVisible = false;
+ }
+}
+```
+
+```html
+
+
+
{{ 'BookStore::RentABook' | abpLocalization }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'AbpIdentity::Save' | abpLocalization }}
+
+
+
+```
+
+Up to now, we have constructed our module's default form properties.
+
+- As you can see, there are no book names we'll add them via contributors
+
+
+
+## Next, add new property dynamically (book name list as dropdown)
+
+- Created new folder ./src/app/books-extended
+- Create contributors/form-prop.contributors.ts
+
+```ts
+// ~/books-extened/contributors/form-prop.contributors.ts
+
+import { Validators } from "@angular/forms";
+import { map } from "rxjs";
+import {
+ ePropType,
+ FormProp,
+ FormPropList,
+} from "@abp/ng.theme.shared/extensions";
+import {
+ BookDto,
+ BookStoreRentFormPropContributors,
+ BooksService,
+ DefaultOption,
+ RentBookComponent,
+ eBooksComponents,
+} from "@book-store/books";
+
+const { required, maxLength } = Validators;
+
+const bookIdProp = new FormProp({
+ type: ePropType.String,
+ id: "bookId",
+ name: "bookId",
+ displayName: "BookStore::Name",
+ options: (data) => {
+ const rentBook = data.getInjected(RentBookComponent);
+ const { books } = data.getInjected(BooksService);
+ const bookOptions = books().map(({ id, name }) => ({
+ value: id,
+ key: name,
+ }));
+
+ return rentBook.form.controls.genreId.valueChanges.pipe(
+ map((value: string | undefined) =>
+ value ? [DefaultOption, ...bookOptions] : [DefaultOption]
+ )
+ );
+ },
+ validators: () => [required, maxLength(255)],
+});
+
+export function bookIdPropContributor(propList: FormPropList) {
+ propList.addByIndex(bookIdProp, 2);
+}
+
+export const bookStoreRentFormPropContributors: BookStoreRentFormPropContributors =
+ {
+ [eBooksComponents.RentBook]: [bookIdPropContributor],
+ };
+```
+
+- Load new contributions via routing & forLazy method
+
+```ts
+// ~/app-routing.module.ts
+import { bookStoreRentFormPropContributors } from "./books-extended/contributors/form-prop.contributors";
+
+const routes: Routes = [
+ // other routes...
+ {
+ path: "books",
+ loadChildren: () =>
+ import("@book-store/books").then((m) =>
+ m.BooksModule.forLazy({
+ rentFormPropContributors: bookStoreRentFormPropContributors,
+ })
+ ),
+ },
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes, {})],
+ exports: [RouterModule],
+})
+export class AppRoutingModule {}
+```
+
+Finally, we've added a new property to our module, and it'll be loaded after `Genre` is selected.
+
+## Conclusion
+
+
+
+- In ABP Angular, we can create form properties and load dropdown options dynamically via the Extensions System
+- We can reach and track any value from `Service` or `Component`
+- We can create our custom library or module and contribute it to any module in the application
+
+Thanks for reading, I hope it was helpful. If you have any questions, please let me know in the comments section. 👋👋
+
+> You can find the source code of this article on [Github](https://github.com/abpframework/abp-samples/tree/master/AngularCascadingOptionLoading/Volo.BookStore)
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif
new file mode 100644
index 0000000000..ae69070f28
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif differ
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png
new file mode 100644
index 0000000000..7f806ec42d
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png differ
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png
new file mode 100644
index 0000000000..2d3a828773
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png differ
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png
new file mode 100644
index 0000000000..e29d525f7b
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png differ
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png
new file mode 100644
index 0000000000..6b06e8ca90
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png differ
diff --git a/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/POST.md b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/POST.md
new file mode 100644
index 0000000000..a68bc106a5
--- /dev/null
+++ b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/POST.md
@@ -0,0 +1,236 @@
+# Moving Background Job Execution To A Separate Application
+
+In this article, I will show you how to move the background job execution to a separate application.
+
+Here are some benefits of doing this:
+
+* If your background jobs consume high system resources (CPU, RAM or Disk), then you can deploy that background application to a dedicated server so it won't affect your application's performance.
+* You can scale your background job application independently from your web application. For example, you can deploy multiple instances of your background job application to a Kubernetes cluster and scale it easily.
+
+Here are some disadvantages of doing this:
+
+* You need to deploy and maintain at least two applications instead of one.
+* You need to implement a mechanism to share the common code between your applications. For example, you can create a shared project and add it to your applications as a project reference.
+
+## Source code
+
+You can find the source code of the application at [abpframework/abp-samples](https://github.com/abpframework/abp-samples/tree/master/SeparateBackgroundJob).
+
+You can check the PR to see the changes step by step: [abpframework/abp-samples#250](https://github.com/abpframework/abp-samples/pull/250)
+
+## Creating the Web Application
+
+First, we need to create a new web application using the ABP CLI:
+
+```bash
+abp new SeparateBackgroundJob -t app
+```
+
+* Create a shared project named `SeparateBackgroundJob.Common.Shared` to share the `BackgroundJob` and `BackgroundJobArgs` classes between the web and job executor applications.
+* Install the `Volo.Abp.BackgroundJobs.Abstractions` package to the `SeparateBackgroundJob.Common.Shared` project.
+
+Add the `SeparateBackgroundJobCommonSharedModule` class to the `SeparateBackgroundJob.Common.Shared` project:
+
+```csharp
+[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))]
+public class SeparateBackgroundJobCommonSharedModule : AbpModule
+{
+}
+```
+
+Add the `MyReportJob` and `MyReportJobArgs` classes to the `SeparateBackgroundJob.Common.Shared` project:
+
+```csharp
+public class MyReportJob : AsyncBackgroundJob, ITransientDependency
+{
+ public override Task ExecuteAsync(MyReportJobArgs args)
+ {
+ Logger.LogInformation("Executing MyReportJob with args: {0}", args.Content);
+ return Task.CompletedTask;
+ }
+}
+
+public class MyReportJobArgs
+{
+ public string? Content { get; set; }
+}
+```
+
+Add the `SeparateBackgroundJob.Common.Shared` project reference to the `SeparateBackgroundJob.Domain` project and add `SeparateBackgroundJobCommonSharedModule` to the `DependsOn` attribute of the `SeparateBackgroundJobDomainModule` class:
+
+```csharp
+[DependsOn(
+ typeof(SeparateBackgroundJobDomainSharedModule),
+ typeof(AbpAuditLoggingDomainModule),
+ typeof(AbpBackgroundJobsDomainModule),
+ typeof(AbpFeatureManagementDomainModule),
+ typeof(AbpIdentityDomainModule),
+ typeof(AbpOpenIddictDomainModule),
+ typeof(AbpPermissionManagementDomainOpenIddictModule),
+ typeof(AbpPermissionManagementDomainIdentityModule),
+ typeof(AbpSettingManagementDomainModule),
+ typeof(AbpTenantManagementDomainModule),
+ typeof(AbpEmailingModule),
+ typeof(SeparateBackgroundJobCommonSharedModule) //Add this line
+)]
+public class SeparateBackgroundJobDomainModule : AbpModule
+```
+
+Open the `Index.cshtml` and replace the content with the following code:
+
+```csharp
+@page
+@using Microsoft.AspNetCore.Mvc.Localization
+@using SeparateBackgroundJob.Localization
+@using Volo.Abp.Users
+@model SeparateBackgroundJob.Web.Pages.IndexModel
+@inject IHtmlLocalizer L
+@inject ICurrentUser CurrentUser
+
+@section styles {
+
+}
+
+@section scripts {
+
+}
+
+
+
+
+
+ Add NEW BACKGROUND JOB
+
+
+
+
+
+
+
+```
+
+Open the `Index.cshtml.cs` and replace the content with the following code:
+
+```csharp
+public class IndexModel : SeparateBackgroundJobPageModel
+{
+ private readonly IBackgroundJobManager _backgroundJobManager;
+
+ [BindProperty(SupportsGet = true)]
+ public string? ReportContent { get; set; }
+
+ public IndexModel(IBackgroundJobManager backgroundJobManager)
+ {
+ _backgroundJobManager = backgroundJobManager;
+ }
+
+ public void OnGet()
+ {
+
+ }
+
+ public async Task OnPostAsync()
+ {
+ await _backgroundJobManager.EnqueueAsync(new MyReportJobArgs
+ {
+ Content = ReportContent
+ });
+
+ Alerts.Success("Job is queued!");
+ }
+}
+```
+
+Run the application and navigate to the home page. You should see the following page:
+
+
+
+When you enter some text and click the **Add** button, the job will be queued and executed in the web application:
+
+## Creating the Console Application
+
+Now we split the background job execution to a separate console application.
+
+Open the `SeparateBackgroundJobWebModule` class to disable the background job execution in the web application:
+
+```csharp
+public class SeparateBackgroundJobWebModule : AbpModule
+{
+ ....
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ ...
+
+ //Disable background job execution in the web application
+ Configure(options =>
+ {
+ options.IsJobExecutionEnabled = false;
+ });
+ }
+
+ ...
+}
+```
+
+* Create a new console application using the ABP CLI:
+
+```bash
+abp new BackgroundJobExecutor -t console
+```
+
+* Add the `BackgroundJobExecutor` project to the solution of the web application.
+* Add the `SeparateBackgroundJob.Common.Shared` project reference to the `BackgroundJobExecutor` project.
+* Install the `Volo.Abp.BackgroundJobs.EntityFrameworkCore` and `Volo.Abp.EntityFrameworkCore.SqlServer` packages to the `BackgroundJobExecutor` project.
+
+Update the `BackgroundJobExecutorModule` class as follows:
+
+```csharp
+[DependsOn(
+ typeof(AbpAutofacModule),
+ typeof(AbpBackgroundJobsEntityFrameworkCoreModule),
+ typeof(AbpEntityFrameworkCoreSqlServerModule),
+ typeof(SeparateBackgroundJobCommonSharedModule)
+)]
+public class BackgroundJobExecutorModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.UseSqlServer();
+ });
+ }
+
+ ....
+}
+```
+
+Open the `appsettings.json` file to configure the [connection string](https://docs.abp.io/en/abp/latest/Connection-Strings#configure-the-connection-strings):
+
+```json
+{
+ "ConnectionStrings": {
+ "AbpBackgroundJobs": "Server=(LocalDb)\\MSSQLLocalDB;Database=SeparateBackgroundJob;Trusted_Connection=True"
+ }
+}
+```
+
+> You must use the same connection string for the web application, `AbpBackgroundJobs` is the default connection string name for the background job module.
+
+The solution structure should look like this:
+
+
+
+Now, run the web and console application. When you enter some text and click the **Add** button, the job will be queued and executed in the console application:
+
+
diff --git a/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/1.png b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/1.png
new file mode 100644
index 0000000000..37089353eb
Binary files /dev/null and b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/1.png differ
diff --git a/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/2.png b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/2.png
new file mode 100644
index 0000000000..0e56eee637
Binary files /dev/null and b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/2.png differ
diff --git a/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/solution.png b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/solution.png
new file mode 100644
index 0000000000..ab7abe9a89
Binary files /dev/null and b/docs/en/Community-Articles/2023-09-20-Moving-Background-Job-Execution-To-A-Separate-Application/images/solution.png differ
diff --git a/docs/en/Community-Articles/2023-10-09-How-to-Upload-and-Download-Files-in-the-ABP-Framework-using-Angular/POST.md b/docs/en/Community-Articles/2023-10-09-How-to-Upload-and-Download-Files-in-the-ABP-Framework-using-Angular/POST.md
new file mode 100644
index 0000000000..b6e2cc581a
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-09-How-to-Upload-and-Download-Files-in-the-ABP-Framework-using-Angular/POST.md
@@ -0,0 +1,114 @@
+# How to Upload and Download Files in the ABP Framework using Angular
+In this article, I will describe how to upload and download files with the ABP framework using Angular as the UI template, most of the code is compatible with all template types. In this article, I just gather some information in one post. Nothing is new. I Googled how to manage files in ABP and I didn't find anything. So I decided write a simple article as an answer to this question.
+
+### Creating App Service.
+
+An empty AppService that uses `IRemoteStreamContent` was created. ABP describes the IRemoteStreamContent as:
+
+> ABP Framework provides a special type, IRemoteStreamContent to be used to get or return streams in the application services.
+
+```csharp
+public class StorageAppService: AbpFileUploadDownloadDemoAppService // <- a inherited from ApplicationService. `ProjectName`+'AppService'.
+{
+ public Guid UploadFile(IRemoteStreamContent file)
+ {
+ Stream fs = file.GetStream();
+
+ //save your file with guid or implement your logic
+ var id = Guid.NewGuid();
+ var filePath = "Insert your file path here/" + id.ToString();
+ using var stream = new FileStream(filePath, FileMode.Create);
+ fs.CopyTo(stream);
+ return id;
+ }
+ public IRemoteStreamContent DownloadFile(Guid FileName)
+ {
+ //find your file with guid or implement your logic
+ var filePath = "Insert your file path here" ;
+ var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
+ return new RemoteStreamContent(fs);
+ }
+}
+```
+
+When you want to upload a file, app service param must be IRemoteStreamContent or RemoteStreamContent. You should be able to access a file data with the getStream method in the AppService. After that, There is no ABP spesific code. It's a c# spesific class. You can save a file system, move somewhere or serilize as base64 etc.
+
+when you want to download a file, A method should return IRemoteStreamContent or RemoteStreamContent.
+RemoteStreamContent gets a required parameter. The parameter type must be Stream. (FileStream, MemoryStream, Custom etc...)
+
+For more information please read the topic in the Documentation: https://docs.abp.io/en/abp/latest/Application-Services#working-with-streams
+
+### Creating Angular proxy services
+
+ABP creates proxy files with the `abp generate-proxy -t ng` command. let's check the code.
+
+```javascript
+
+ uploadFileByFile = (file: FormData, config?: Partial) =>
+ this.restService.request({
+ method: 'POST',
+ responseType: 'text',
+ url: '/api/app/storage/upload-file',
+ body: file,
+ },
+ { apiName: this.apiName,...config });
+
+```
+The function name is a little bit weird but let's focus the first parameter. The type of file param is `FormData`. FormData is a native object in JavaSript Web API. See the details. https://developer.mozilla.org/en-US/docs/Web/API/FormData .
+
+How to use the `uploadFileByFile` function.
+
+```javascript
+const myFormData = new FormData();
+myFormData.append('file', inputFile); // file must match variable name in AppService
+storageService.uploadFileByFile(myFormData).subscribe()
+```
+The inputFile type is File. In most cases it comes from the ``, File belongs to the Javacsript Web Api. see the details https://developer.mozilla.org/en-US/docs/Web/API/File
+
+
+Let's continue with "download"
+
+```javascript
+
+ downloadFileByFileName = (FileName: string, config?: Partial) =>
+ this.restService.request({
+ method: 'POST',
+ responseType: 'blob',
+ url: '/api/app/storage/download-file',
+ params: { fileName: FileName },
+ },
+ { apiName: this.apiName,...config });
+
+```
+
+The return type of function is Blob. Blob is another javacript object. See the details: https://developer.mozilla.org/en-US/docs/Web/API/Blob.
+
+Now our code is not ABP Spesific. It is just javascript code. If you don't want to save the blob, here I asked my best AI friend ChatGPT. `Hello, chat! The programming lang is javascript. My variable type is Blob. How do I save file to client's machine?`
+
+Our the gifted friend gives us the code
+```javascript
+function saveBlobToFile(blob, fileName) {
+ // Create a blob URL
+ const blobURL = window.URL.createObjectURL(blob);
+
+ // Create an anchor element for the download
+ const a = document.createElement("a");
+ a.href = blobURL;
+ a.download = fileName || 'download.dat'; // Provide a default file name if none is provided
+
+ // Append the anchor to the document
+ document.body.appendChild(a);
+
+ // Simulate a click on the anchor to initiate the download
+ a.click();
+
+ // Clean up: remove the anchor and revoke the blob URL
+ document.body.removeChild(a);
+ window.URL.revokeObjectURL(blobURL);
+}
+
+// Usage example
+const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
+saveBlobToFile(blob, 'hello.txt');
+```
+
diff --git a/docs/en/Community-Articles/2023-10-23-NET-8-Feature-containers/POST.md b/docs/en/Community-Articles/2023-10-23-NET-8-Feature-containers/POST.md
new file mode 100644
index 0000000000..73bea079a1
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-23-NET-8-Feature-containers/POST.md
@@ -0,0 +1,30 @@
+# New Containers feature with NET 8.0
+
+This article will show you the new feature of containers with NET 8.0.
+
+## Non-root user
+
+The `Non-root user` feature on net 8 is a security measure that allows users to have limited access to the system without having full administrative privileges. Hosting containers as `non-root` aligns with the principle of least privilege.
+It’s free security provided by the operating system. If you run your app as root, your app process can do anything in the container, like modify files, install packages, or run arbitrary executables.
+That’s a concern if your app is ever attacked. If you run your app as non-root, your app process cannot do much, greatly limiting what a bad actor could accomplish.
+
+## Default ASP.NET Core port changed from 80 to 8080
+
+In .NET 8, there has been a change in the default port used by ASP.NET Core applications. Previously, the default port assigned to ASP.NET Core applications was `80`. However, starting from .NET 8, the default port has been changed to `8080`.
+This change was made to avoid conflicts with other applications and services that commonly use port 80, such as web servers like IIS or Apache. By using port 8080 as the default, there is less potential for clashes and easier deployment of ASP.NET Core applications alongside other services.
+
+It's important to note that this change only affects the default port used when an ASP.NET Core application is run without explicitly specifying a port.
+
+If you want your application to continue using port 80, you can still specify it during the application launch or configure it in the application settings.
+
+* Recommended: Explicitly set the `ASPNETCORE_HTTP_PORTS`, `ASPNETCORE_HTTPS_PORTS`, and `ASPNETCORE_URLS` environment variables to the desired port. Example: `docker run --rm -it -p 9999:80 -e ASPNETCORE_HTTP_PORTS=80 `
+* Update existing commands and configuration that rely on the expected default port of port 80 to reference port 8080 instead. Example: `docker run --rm -it -p 9999:8080 `
+
+> The `dockerfile` of ABP templates has been updated to use port `80`.
+
+## References
+
+- [Secure your .NET cloud apps with rootless Linux Containers](https://devblogs.microsoft.com/dotnet/securing-containers-with-rootless/)
+- [Containers breaking changes](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8#containers)
+- [ASP.NET Core apps use port 8080 by default](https://learn.microsoft.com/en-us/dotnet/core/compatibility/8.0#containers)
+- [Docker images for ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/building-net-docker-images?view=aspnetcore-8.0)
diff --git a/docs/en/Community-Articles/2023-10-23-NET-8-Feature-raw-sql-queries-for-unmapped-types/POST.md b/docs/en/Community-Articles/2023-10-23-NET-8-Feature-raw-sql-queries-for-unmapped-types/POST.md
new file mode 100644
index 0000000000..11d8e67563
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-23-NET-8-Feature-raw-sql-queries-for-unmapped-types/POST.md
@@ -0,0 +1,53 @@
+# New Raw SQL queries for unmapped types feature with EF Core 8.0
+
+## Introduction
+
+I would love to talk about the new feature in EF Core 8.0, specifically the `raw SQL queries for unmapped types`.
+This feature was recently introduced by Microsoft and is aimed at providing more flexibility and customization in database queries.
+
+## What is the raw SQL queries for the unmapped types feature?
+
+To give you a better understanding, let's look at a sample repository method with the ABP framework.
+Here is an example of a raw SQL query using the new feature:
+
+````csharp
+public interface IAuthorRepository : IRepository
+{
+ Task> GetAllAuthorNamesAsync();
+}
+
+public class AuthorIdWithNames
+{
+ public Guid Id { get; set; }
+
+ public string Name { get; set; }
+}
+
+public class EfCoreAuthorRepository : EfCoreRepository, IAuthorRepository
+{
+ public EfCoreAuthorRepository(IDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+
+ public virtual async Task> GetAllAuthorNamesAsync()
+ {
+ return await (await GetDbContextAsync()).Database.SqlQuery(@$"SELECT Id, Name FROM Authors").ToListAsync();
+ }
+}
+````
+
+In this code, we can see that we are using the `SqlQuery` method to execute a raw SQL query on a custom type, `AuthorIdWithNames` in this case. This allows us to retrieve data that may not be mapped to any of our entity classes in the context.
+
+## In summary
+
+This feature can be particularly useful in scenarios where we need to access data from tables or views that are not directly mapped to our entities. It also provides an alternative to using stored procedures for querying data.
+
+However, it's important to note that using raw SQL queries can increase the risk of SQL injection attacks. So, it's recommended to use parameterized queries to prevent this. Additionally, this feature may not work with certain database providers, so it's important to check for compatibility before implementing it.
+
+In conclusion, the raw SQL queries for unmapped types feature in EF Core 8.0 is a great addition for developers looking for more flexibility in database queries. It allows us to work with data that may not be directly mapped to our entities and can be a useful tool in certain scenarios. Just remember to use parameterized queries and check for compatibility before implementing it.
+
+## References
+
+- [Raw SQL queries for unmapped types](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#raw-sql-queries-for-unmapped-types)
+- [SQL Queries](https://learn.microsoft.com/en-us/ef/core/querying/sql-queries#querying-scalar-(non-entity)-types)
diff --git a/docs/en/Community-Articles/2023-10-28-EF-Core-8-Primitive-Collections/POST.md b/docs/en/Community-Articles/2023-10-28-EF-Core-8-Primitive-Collections/POST.md
new file mode 100644
index 0000000000..79d1b100c9
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-28-EF-Core-8-Primitive-Collections/POST.md
@@ -0,0 +1,118 @@
+# EF Core 8 Primitive collections
+
+What can we do when we want to store a list of primitive types? Before EF Core 8, there were two options:
+
+- Create a wrapper class and a related table, then add a foreign key linking each value to its owner of the collection.
+- Use [value converter](https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions) to serialize-deserialize as JSON.
+
+The first option covers most scenarios if we need to add some additional properties to this type but let's say we're never gonna need this type additionality.
+
+## Which collection types are supported ?
+
+EF Core has the capability to map the `IEnumerable` public properties that have both a getter and a setter, with the `T` representing a primitive type
+
+```csharp
+public class PrimitiveCollections
+{
+ public IEnumerable Ints { get; set; }
+ public ICollection Strings { get; set; }
+ public ISet DateTimes { get; set; }
+ public IList Dates { get; set; }
+ public uint[] UnsignedInts { get; set; }
+ public List Booleans { get; set; }
+ public List Urls { get; set; }
+}
+```
+
+> Some generic arguments are not considered primitive on the database side, such as `uint` and `Uri`. However, these types are also considered as primitive because there are [built-in value converters](https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#built-in-converters).
+
+## Demo
+
+In this sample, we have a `Car` class with a `Color` enum, and the `Car` class has a `Colors` property.
+
+```csharp
+public enum Color
+{
+ Black,
+ White,
+ Red,
+ Blue
+}
+
+public class Car
+{
+ public int Id { get; set; }
+ public string Brand { get; set; }
+ public string Model { get; set; }
+ public ISet Colors { get; set; } = new HashSet();
+
+ public Car(string brand, string model)
+ {
+ Brand = brand;
+ Model = model;
+ }
+}
+```
+
+When we want to list the cars if they have any of the specific colors.
+
+```csharp
+var colors = new HashSet { Color.Blue, Color.White };
+var cars = await context
+ .Cars
+ .Where(x=> x.Colors.Intersect(colors).Any())
+ .ToListAsync();
+```
+
+The SQL result looks like this; as you can see, it sends colors as parameters instead of adding them inline. It also uses the `json_each` function to deserialize on the database side.
+
+```sql
+SELECT "c"."Id", "c"."Brand", "c"."Colors", "c"."Model"
+ FROM "Cars" AS "c"
+ WHERE EXISTS (
+ SELECT 1
+ FROM (
+ SELECT "c0"."value"
+ FROM json_each("c"."Colors") AS "c0"
+ INTERSECT
+ SELECT "c1"."value"
+ FROM json_each(@__colors_0) AS "c1"
+ ) AS "t")
+
+```
+
+When we insert to the car table.
+
+```csharp
+var car = new Car("Maserati", "GranTurismo")
+{
+ Colors = new HashSet()
+ {
+ Color.Black,
+ Color.Blue
+ }
+};
+context.Cars.Add(car);
+await context.SaveChangesAsync();
+```
+
+The SQL statement looks like this, and as you can see, it automatically serializes into the Colors parameter as JSON.
+
+```sql
+ Executed DbCommand (0ms) [Parameters=
+ [@p0='Maserati' (Nullable = false) (Size = 8),
+ @p1='[0,3]' (Nullable = false) (Size = 5),
+ @p2='Flow' (Nullable = false) (Size = 4)
+ ], CommandType='Text', CommandTimeout='30']
+ INSERT INTO "Cars" ("Brand", "Colors", "Model")
+ VALUES (@p0, @p1, @p2)
+ RETURNING "Id";
+```
+## Conclusion
+
+We don't need to do anything if we just use a collection of primitive types. It serializes and deserializes them as JSON automatically. Additionally, it sends the primitive collection as a parameter to cache the query.
+
+## References
+
+- [EF Core 8 Primitive collections](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#primitive-collection-properties)
+- [.NET Data Community Standup - Collections of primitive values in EF Core](https://www.youtube.com/watch?v=AUS2OZjsA2I)
diff --git a/docs/en/Community-Articles/2023-10-30-Enhancements-to-JSON-column-mapping/POST.md b/docs/en/Community-Articles/2023-10-30-Enhancements-to-JSON-column-mapping/POST.md
new file mode 100644
index 0000000000..db8f72ca17
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-30-Enhancements-to-JSON-column-mapping/POST.md
@@ -0,0 +1,124 @@
+# EF Core 8 - Enhancements to JSON column mapping
+
+In this article, we will examine the enhancements introduced in EF Core 8 for the JSON column feature, building upon the foundation laid by [JSON columns in Entity Framework Core 7](https://community.abp.io/posts/json-columns-in-entity-framework-core-7-cjaom76j).
+
+## The entity classes we will be using in the article
+
+```csharp
+public class Person
+{
+ public int Id { get; set; }
+ [Required]
+ public string Name { get; set; }
+ [Required]
+ public ContactDetails ContactDetails { get; set; }
+}
+
+public class ContactDetails
+{
+ public List Addresses { get; set; } = new();
+ public string? Phone { get; set; }
+}
+
+public class Address
+{
+ public Address(string street, string city, string postcode, string country)
+ {
+ Street = street;
+ City = city;
+ Postcode = postcode;
+ Country = country;
+ }
+
+ public string Street { get; set; }
+ public string City { get; set; }
+ public string Postcode { get; set; }
+ public string Country { get; set; }
+ public bool IsMainAddress { get; set; }
+}
+```
+
+## The DbContext class we will be using in the article
+
+```csharp
+public class AppDbContext : DbContext
+{
+ public DbSet Persons { get; set; } = null!;
+
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+#if SQLSERVER
+ optionsBuilder.UseSqlServer("Server=localhost;Database=EfCore8Json;Trusted_Connection=True;TrustServerCertificate=True");
+#elif SQLITE
+ optionsBuilder.UseSqlite("Data Source=EfCore8Json.db");
+#endif
+ base.OnConfiguring(optionsBuilder);
+ }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity(b =>
+ {
+ b.ToTable("Persons");
+ b.HasKey(x => x.Id);
+ b.Property(x => x.Name).IsRequired();
+ b.OwnsOne(x => x.ContactDetails, cb =>
+ {
+ cb.ToJson();
+ cb.Property(x => x.Phone);
+ cb.OwnsMany(x => x.Addresses);
+ });
+ });
+
+ base.OnModelCreating(modelBuilder);
+ }
+}
+```
+
+## Translate element access into JSON arrays
+
+EF Core 8 supports indexing in JSON arrays when executing queries. For example, the following query returns individuals whose first address is the main address in the database:
+
+```csharp
+var query = dbContext.Persons
+ .Select(x => x.ContactDetails.Addresses[0])
+ .Where(x => x.IsMainAddress == true)
+ .ToListAsync();
+```
+
+The generated SQL query is as follows when using SQL Server:
+
+```sql
+SELECT JSON_QUERY([p].[ContactDetails], '$.Addresses[0]'), [p].[Id]
+FROM [Persons] AS [p]
+WHERE CAST(JSON_VALUE([p].[ContactDetails], '$.Addresses[0].IsMainAddress') AS bit) = CAST(1 AS bit)
+```
+
+> Note: If you attempt to access an index that is outside of the array, it will return null.
+
+## JSON Columns for SQLite
+
+In EF Core 7, JSON column mapping was supported for Azure SQL/SQL Server. In EF Core 8, this support has been extended to include SQLite as well.
+
+### Queries into JSON columns
+
+The following query returns individuals whose first address is the main address in the database:
+
+```csharp
+var query = dbContext.Persons
+ .Select(x => x.ContactDetails.Addresses[0])
+ .Where(x => x.IsMainAddress == true)
+ .ToListAsync();
+```
+
+The generated SQL query is as follows when using SQLite:
+
+```sql
+SELECT "p"."ContactDetails" ->> '$.Addresses[0]', "p"."Id"
+FROM "Persons" AS "p"
+WHERE "p"."ContactDetails" ->> '$.Addresses[0].IsMainAddress' = 0
+```
+
+## References
+
+- [EF Core 8 - Enhancements to JSON column mapping](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#enhancements-to-json-column-mapping)
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/POST.md b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/POST.md
new file mode 100644
index 0000000000..9142a36be9
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/POST.md
@@ -0,0 +1,196 @@
+# .NET 8 - ASP.NET Core Metrics
+
+In this article, I'll show you the new built-in metrics of .NET 8, which are basically numerical measurements reported over time in your application and can be used to monitor the health of your application and generate reports according to those numerical values. We will see what the metrics are, why to use them, and how to use them in detail. So, let's dive in.
+
+## What are Metrics?
+
+Metrics are numerical measurements reported over time. These measurements are crucial for monitoring the health of an application and generating alerts when necessary. In the context of a web service, various metrics can be tracked, such as:
+
+* Requests per second.
+* Response time.
+* Status code counts etc...
+
+These metrics are not just collected; they are reported to a monitoring system at regular intervals. By doing so, the development and operations teams can visualize these metrics on dashboards. These dashboards provide a real-time overview of the application's performance and health.
+
+## Pre-Built Metrics
+
+ASP.NET Core has many built-in metrics. You can see the following figure for a list of built-in metrics for ASP.NET Core:
+
+
+
+> See https://learn.microsoft.com/en-us/dotnet/core/diagnostics/built-in-metrics-aspnetcore and https://github.com/dotnet/aspnetcore/issues/47536 for all built-in metrics and their descriptions.
+
+For example, we have the `kestrel-current-connections` metric that shows the _number of connections that are currently active on the server_ and the `http-server-request-duration` metric that shows _the duration of HTTP requests on the server_.
+
+All of these and other built-in metrics are produced by using the [**System.Diagnostics.Metrics**](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics) API and with a small amount of code, we can use & view them.
+
+## Using Pre-Built Metrics
+
+Let's see the pre-built metrics in action.
+
+Create a new ASP.NET Core app with the following command and change the directory to the created application folder:
+
+```bash
+dotnet new web -o MetricsDemo
+cd MetricsDemo
+```
+
+After that, open the application in your favorite IDE and add the following service registration code to your application:
+
+```csharp
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddOpenTelemetry()
+ .WithMetrics(builder =>
+ {
+ builder.AddPrometheusExporter();
+
+ builder.AddMeter("Microsoft.AspNetCore.Hosting",
+ "Microsoft.AspNetCore.Server.Kestrel");
+ builder.AddView("http.server.request.duration",
+ new ExplicitBucketHistogramConfiguration
+ {
+ Boundaries = new double[] { 0, 0.005, 0.01, 0.025, 0.05,
+ 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 }
+ });
+ });
+```
+
+Here, we have done the following steps:
+
+* The `AddOpenTelemetry` method registers the required **OpenTelemetry** services into the DI container.
+* In the `WithMetrics` method, we add pre-built metrics to the `OpenTelemetryBuilder` in the `AddMeter` method (_Microsoft.AspNetCore.Hosting_ and _Microsoft.AspNetCore.Server.Kestrel_ are pre-built metrics provided by ASP.NET Core).
+* We have also used the `AddView` method to customize the output of the metrics by the SDK. It can also be used to customize which [Instruments](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument) are to be processed or ignored.
+
+After making the related configurations, let's add the middleware below and view the metrics:
+
+```csharp
+app.MapPrometheusScrapingEndpoint();
+
+app.MapGet("/", () =>
+{
+ Thread.Sleep(2000);
+
+ return "Hello, ABP Community member: " + DateTime.Now.Ticks.ToString()[^3..];
+});
+```
+
+* `MapPrometheusScrapingEndpoint`: Adds the OpenTelemetry Prometheus scraping endpoint middleware to the pipeline and then we can see the all metrics by navigating to the **/metrics** endpoints (optional):
+
+
+
+### View Metrics
+
+You can use the `dotnet-counters` command-line tool, which allows you to view live metrics for .NET Core apps. You can run the following command to install the tool:
+
+```bash
+dotnet tool update -g dotnet-counters
+```
+
+After the tool is installed, you can run the application and by running the `dotnet-counters` tool in a terminal, you can monitor for the specific metrics:
+
+```bash
+dotnet-counters monitor -n MetricsDemo --counters Microsoft.AspNetCore.Hosting
+```
+
+When you run the command, it will print a message like the one below and will wait for an initial request to your application:
+
+```txt
+Press p to pause, r to resume, q to quit.
+ Status: Waiting for initial payload...
+```
+
+If you send a request to your application, then the related built-in metrics that you have added will be collected and will be shown in the terminal instantly:
+
+
+
+Also, you can check for the other metric that we have used in the configuration, which is _Microsoft.AspNetCore.Server.Kestrel_ by setting it as a counter as in the command below, and when you send a request to your application, you will see different metrics:
+
+```bash
+dotnet-counters monitor -n MetricsDemo --counters Microsoft.AspNetCore.Server.Kestrel
+```
+
+## Creating Custom Metrics in ASP.NET Core Applications
+
+So far, we have seen what metrics are, which built-in metrics are provided by ASP.NET Core, the use of the built-in metrics and running the `dotnet-counters` global tool to view these metrics. At this point, let's see how we can create custom metrics and view them via the `dotnet-counters` tool.
+
+`IMeterFactory` is the recommended service to create *Meter* instances. ASP.NET Core registers the `IMeterFactory` in dependency injection (DI) by default. The meter factory integrates metrics with DI, making isolating and collecting metrics easy.
+
+Assume that, we want to create a metric that holds the sold products in our application. For that purpose, as a first step, we can create a metric class as follows:
+
+```csharp
+using System.Diagnostics.Metrics;
+
+namespace MetricsDemo;
+
+public class ProductMetrics
+{
+ private readonly Counter _soldProductsCount;
+
+ public ProductMetrics(IMeterFactory meterFactory)
+ {
+ var meterInstance = meterFactory.Create("MetricsDemo.ProductStore");
+ _soldProductsCount = meterInstance.CreateCounter("metricsdemo.productstore.sold_products_count");
+ }
+
+ public void IncreaseSoldProductCount(int quantity)
+ {
+ _soldProductsCount.Add(quantity);
+ }
+}
+```
+
+In this class, we are creating a counter and defining metrics that we want to collect and view. `MetricsDemo.ProductStore` is the **counter name** and `metricsdemo.productstore.sold_products_count` is the **metric**. In our example, we need to register this class with a `Singleton` lifetime because we don't want to reset the counter and want to keep it during the application runtime.
+
+> The [System.Diagnostics.Metrics.Meter](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics.meter) type is the entry point for a library to create a named group of instruments. Instruments record the numeric measurements that are needed to calculate metrics. Here we used [CreateCounter](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics.meter.createcounter) to create a Counter instrument named _metricsdemo.productstore.sold_products_count_.
+
+So, register the type with the DI container in the `Program.cs` file (or you can implement the `ISingletonDependency` interface, if you are using an ABP based application):
+
+```csharp
+builder.Services.AddSingleton();
+```
+
+Then, we can inject this class and increase the sold product count whenever it's needed. Since we have registered it in DI, we can use it in minimal APIs as in the following example:
+
+```csharp
+app.MapPost("/complete-sale", ([FromBody] ProductSoldModel model, ProductMetrics metrics) =>
+{
+ // ... business logic such as saving the product to the database etc... ...
+
+ metrics.IncreaseSoldProductCount(model.Quantity);
+});
+```
+
+Whenever a request is made to this endpoint the metric that we've defined (_metricsdemo.productstore.sold_products_count_) will be increased and we can see this metric via the `dotnet-counters` global tool. You can run the following command to see the metrics:
+
+```bash
+dotnet-counters monitor -n MetricsDemo --counters MetricsDemo.ProductStore
+```
+
+Here is an example output that you would see if you have made a POST request to the `/complete-sale` endpoint:
+
+```txt
+Press p to pause, r to resume, q to quit.
+ Status: Paused
+
+[MetricsDemo.ProductStore]
+ metricsdemo.productstore.sold_products_count (Count / 1 sec) 20
+```
+
+### Advanced: View Metrics in Prometheus & Grafana - Building Dashboards
+
+It's a common requirement to build a dashboard and monitor the metrics and check the health of your applications. At that point, you can expose the metrics and scrape them using the [Prometheus](https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-8.0#set-up-and-configure-prometheus) and build a dashboard by using the [Grafana](https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-8.0#show-metrics-on-a-grafana-dashboard).
+
+If you want to build a dashboard, you can see [this documentation from Microsoft](https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-8.0#view-metrics-in-grafana-with-opentelemetry-and-prometheus), which shows how to set up the **Prometheus server** and show metrics on a **Grafana** dashboard.
+
+Also, you can check [this video](https://www.youtube.com/watch?v=A2pKhNQoQUU) if you want to see it in action.
+
+## Conclusion
+
+In this article, I've shown you the new built-in metrics of .NET8, described what metrics are, which pre-built metrics are provided by ASP.NET Core, how to use & view these pre-built metrics and finally, I have shown you how to create custom metrics and view them in a dashboard. If you want to learn more about the **Metrics System of .NET**, you can check out the references that I have shared below.
+
+## References
+
+* https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-8.0
+* https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-5/
+* https://www.youtube.com/watch?v=A2pKhNQoQUU
diff --git a/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metric-response.png b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metric-response.png
new file mode 100644
index 0000000000..035e76de7d
Binary files /dev/null and b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metric-response.png differ
diff --git a/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metrics.png b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metrics.png
new file mode 100644
index 0000000000..7cf3a1896d
Binary files /dev/null and b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/built-in-metrics.png differ
diff --git a/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/metrics-endpoint.png b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/metrics-endpoint.png
new file mode 100644
index 0000000000..70933e0f6e
Binary files /dev/null and b/docs/en/Community-Articles/2023-10-30-NET-8-ASP-NET-Core-Metrics/metrics-endpoint.png differ
diff --git a/docs/en/Community-Articles/2023-10-31-NET-8-ASP-NET-Core-Minimal-APIs/POST.md b/docs/en/Community-Articles/2023-10-31-NET-8-ASP-NET-Core-Minimal-APIs/POST.md
new file mode 100644
index 0000000000..03ca906884
--- /dev/null
+++ b/docs/en/Community-Articles/2023-10-31-NET-8-ASP-NET-Core-Minimal-APIs/POST.md
@@ -0,0 +1,156 @@
+# New Minimal APIs features in ASP.NET Core 8.0
+
+In this article, we will see the new features of Minimal APIs in ASP.NET Core 8.0.
+
+## Binding to forms
+
+We can bind to forms using the [FromForm] attribute. Let's see an example:
+
+```csharp
+app.MapPost("/books", async ([FromForm] string name,
+ [FromForm] BookType bookType, IFormFile? cover, BookDb db) =>
+{
+ var book = new Book
+ {
+ Name = name,
+ BookType = bookType
+ };
+
+ if (cover is not null)
+ {
+ var coverName = Path.GetRandomFileName();
+
+ using var stream = File.Create(Path.Combine("wwwroot", coverName));
+ await cover.CopyToAsync(stream);
+ book.Cover = coverName;
+ }
+
+ db.Books.Add(book);
+ await db.SaveChangesAsync();
+
+ return Results.Ok();
+});
+```
+
+Another way is using the [AsParameters] attribute, the following code binds from form values to properties of the `NewBookRequest` record struct:
+
+```csharp
+public record NewBookRequest([FromForm] string Name, [FromForm] BookType BookType, IFormFile? Cover);
+
+app.MapPost("/books", async ([AsParameters] NewBookRequest request, BookDb db) =>
+{
+ var book = new Book
+ {
+ Name = request.Name,
+ BookType = request.BookType
+ };
+
+ if (request.Cover is not null)
+ {
+ var coverName = Path.GetRandomFileName();
+
+ using var stream = File.Create(Path.Combine("wwwroot", coverName));
+ await request.Cover.CopyToAsync(stream);
+ book.Cover = coverName;
+ }
+
+ db.Books.Add(book);
+ await db.SaveChangesAsync();
+
+ return Results.Ok();
+});
+```
+
+## Antiforgery
+
+ASP.NET Core 8.0 adds support for antiforgery tokens. We can call the `AddAntiforgery` method to register the antiforgery services and `WebApplicationBuilder` will automatically add the antiforgery middleware to the pipeline:
+
+```csharp
+var builder = WebApplication.CreateBuilder();
+
+builder.Services.AddAntiforgery();
+
+var app = builder.Build();
+
+// Implicitly added by WebApplicationBuilder if AddAntiforgery is called.
+// app.UseAntiforgery();
+
+app.MapGet("/", () => "Hello World!");
+
+app.Run();
+```
+
+Example of using antiforgery tokens:
+
+```csharp
+
+// Use the antiforgery service to generate tokens.
+app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
+{
+ var token = antiforgery.GetAndStoreTokens(context);
+ return Results.Content(...., "text/html");
+});
+
+// It will automatically validate the token.
+app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
+
+// Disable antiforgery validation for this endpoint.
+app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
+ .DisableAntiforgery();
+```
+
+
+## Native AOT
+
+ASP.NET Core 8.0 adds support for Native AOT.
+
+You can add `PublishAot` to the project file to enable Native AOT:
+
+```xml
+
+ true
+
+```
+
+### Web API (native AOT) template
+
+You can use the `dotnet new webapiaot` command to create a new Minimal APIs project with Native AOT enabled.
+
+```diff
++using System.Text.Json.Serialization;
+
+-var builder = WebApplication.CreateBuilder();
++var builder = WebApplication.CreateSlimBuilder(args);
+
++builder.Services.ConfigureHttpJsonOptions(options =>
++{
++ options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
++});
+
+var app = builder.Build();
+
+var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
+
+var todosApi = app.MapGroup("/todos");
+todosApi.MapGet("/", () => sampleTodos);
+todosApi.MapGet("/{id}", (int id) =>
+ sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+
+app.Run();
+
++[JsonSerializable(typeof(Todo[]))]
++internal partial class AppJsonSerializerContext : JsonSerializerContext
++{
++
++}
+```
+
+* Reflection isn't supported in native AOT, you must use the `JsonSerializable` attribute to specify the types that you want to serialize/deserialize.
+
+## References
+
+* https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-8.0?view=aspnetcore-8.0#minimal-apis
+* https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/parameter-binding?view=aspnetcore-8.0#explicit-binding-from-form-values
+* https://learn.microsoft.com/en-us/aspnet/core/fundamentals/native-aot?view=aspnetcore-8.0
diff --git a/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/POST.md b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/POST.md
new file mode 100644
index 0000000000..22c621aa1b
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/POST.md
@@ -0,0 +1,138 @@
+# ASP.NET 8: What's New About Authentication and Authorization
+
+In ASP.NET 8, the concept of authentication and authorization is undergoing a transformation. Specifically, ASP.NET Core Identity is transitioning from a focus on traditional web pages to a more API-driven approach. We will see what the Identity API endpoints are, why we need them, and how to use them in detail. So, let's dive in.
+
+## What is ASP.NET Core Identity?
+
+ASP.NET Core Identity is like an extra toolkit that comes with ASP.NET Core. It offers a bunch of services to help you deal with user accounts in your ASP.NET Core application. These services include both basic concepts and ready-made solutions for each task.
+
+With ASP.NET Core Identity, you can save user accounts in your app, handle user information, add extra security with two-factor authentication, and even connect other log in options, like social media logins, to user accounts. In simple terms, it's all about keeping user accounts in your app and making it easy for users to log in.
+
+
+
+Prior to ASP.NET 8, there were limitations on using ASP.NET Identity in Single Page Applications (SPAs). Because the ASP.NET Core Identity framework is primarily tailored for traditional server-rendered web applications, like ASP.NET Core MVC or Razor Pages apps. However, the Identity API endpoints that come with ASP.NET 8 aim to solve token-based authentication and authorization in SPA without external dependencies.
+
+## Why do we need Identity APIs?
+
+The introduction of Identity endpoints in ASP.NET 8 aims to streamline the process of integrating ASP.NET Core Identity into both API server applications and front-end SPAs like those built with JavaScript or Blazor. To understand the importance of these endpoints, let's first examine the disadvantages of using ASP.NET Core Identity before ASP.NET 8.
+
+Let's delve into a common scenario:
+
+Imagine you have a straightforward application composed of an ASP.NET Core backend that exposes APIs. On the client side, you have a SPA application that communicates with these APIs. Now, you want to incorporate user accounts, complete with authentication and authorization, into your application.
+
+Before the advent of the identity endpoints, you could add ASP.NET Core Identity and the default Razor Pages UI to your app by adding a few packages, updating your database schema, and registering some services. However, this approach had some disadvantages. From a user experience perspective, the full-page refreshes of Razor Pages can be a major drawback especially compared to the fluidity of SPAs. On the other hand, from a developer's perspective, if you want the default pages to be compatible with the rest of your application, you may need to update more than 30 pages. Moreover, the default Razor Pages UI uses traditional cookie-based authentication, not bearer tokens.
+
+In ASP.NET 8, identity endpoints were introduced to simplify the process of adding user accounts to ASP.NET Core API apps used with SPAs or mobile. These endpoints streamline the user management process by providing an alternative to the traditional Razor Page Identity UI pages. Additionally, a new endpoint is included for retrieving bearer tokens, which can be used for authentication. These changes directly address the concerns mentioned earlier, making it easier to create a user-friendly and integrated experience within your app, with no full-page refreshes or styling conflicts.
+
+## How to add Identity APIs?
+
+In this part, I'll create a demo application, add all of the required packages, and lastly map the Identity APIs.
+
+Create a new ASP.NET Core app with the following command and change the directory to the created application folder:
+
+```bash
+dotnet new webapi --name NewIdentityEndpoints -o IdentityDemo
+cd IdentityDemo
+```
+
+After that, open the application in your favorite IDE and add the required packages:
+
+```csharp
+
+
+```
+
+**Note:** I used the `.NET 8.0.100-rc.2-**` SDK for everything in this post.
+
+Then replace `Program.cs` as below:
+
+```csharp
+using System.Security.Claims;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddAuthentication().AddBearerToken(IdentityConstants.BearerScheme);
+builder.Services.AddAuthorizationBuilder();
+
+builder.Services.AddDbContext(options => options.UseInMemoryDatabase("AppDb"));
+
+builder.Services.AddIdentityCore()
+.AddEntityFrameworkStores()
+.AddApiEndpoints();
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+
+var app = builder.Build();
+
+app.MapGroup("/my-identity-api").MapIdentityApi();
+
+app.MapGet("/", (ClaimsPrincipal user) => $"Hello {user.Identity!.Name}").RequireAuthorization();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseSwagger();
+ app.UseSwaggerUI();
+}
+
+app.Run();
+
+class MyCustomUser : IdentityUser { }
+
+class ApplicationDbContext : IdentityDbContext
+{
+ public ApplicationDbContext(DbContextOptions options) : base(options) { }
+}
+
+```
+
+When you run the application, you will see a result as the following:
+
+
+
+## Custom Authorization Policies
+
+Prior to ASP.NET 8, adding a parameterized authorization policy to an endpoint required writing a lot of code.
+
+- Implementing an `AuthorizeAttribute` for each policy
+- Implementing an `AuthorizationPolicyProvider` to process a custom policy from a string-based contract
+- Implementing an `AuthorizationRequirement` for the policy
+- Implementing an `AuthorizationHandler` for each requirement
+
+However, implementing the `IAuthorizationRequirementData` interface that comes with ASP.NET 8, your application code should look like this:
+
+```csharp
+class MinimumAgeAuthorizeAttribute : AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationRequirementData
+{
+ public MinimumAgeAuthorizeAttribute(int age) => Age =age;
+ public int Age { get; }
+
+ public IEnumerable GetRequirements()
+ {
+ yield return this;
+ }
+}
+
+class MinimumAgeAuthorizationHandler : AuthorizationHandler
+{
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeAuthorizeAttribute requirement)
+ {
+ ...
+ }
+}
+```
+
+See [here](https://gist.github.com/captainsafia/7c54e92d12df695ff0908e989fb8531f) for the complete code.
+
+## Conclusion
+
+In this article, I've shown you the Identity APIs introduced with ASP.NET 8, why we need them, and how we can add them to our application, and finally I explained how to define a custom authorization policy with fewer lines of code.
+
+## References
+- https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-8.0?view=aspnetcore-8.0#authentication-and-authorization
+- https://auth0.com/blog/whats-new-dotnet8-authentication-authorization/
+- https://andrewlock.net/exploring-the-dotnet-8-preview-introducing-the-identity-api-endpoints/
+- https://andrewlock.net/should-you-use-the-dotnet-8-identity-api-endpoints/
diff --git a/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/identity_endpoints_scaffold.png b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/identity_endpoints_scaffold.png
new file mode 100644
index 0000000000..951f6f1da6
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/identity_endpoints_scaffold.png differ
diff --git a/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/new-identity-endpoints.png b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/new-identity-endpoints.png
new file mode 100644
index 0000000000..b8ac5021ee
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-03-ASPNET8-authentication-and-authorization/new-identity-endpoints.png differ
diff --git a/docs/en/Community-Articles/2023-11-05-EF-Core-8-Complex-Types/POST.MD b/docs/en/Community-Articles/2023-11-05-EF-Core-8-Complex-Types/POST.MD
new file mode 100644
index 0000000000..f11dec060d
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-05-EF-Core-8-Complex-Types/POST.MD
@@ -0,0 +1,189 @@
+# Using Complex Types as Value Objects with Entity Framework Core 8.0
+
+Entity Framework Core 8.0 is being shipped in a week as a part of .NET 8.0. In this article, I will introduce the new **[Complex Types](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#value-objects-using-complex-types)** feature of EF Core 8 and show some examples of how you can use it in your projects built with ABP Framework.
+
+## What is a Value Object?
+
+A [Value Object](https://docs.abp.io/en/abp/latest/Value-Objects) is a simple object that has no conceptual identity (Id). Instead, a Value Object is identified by its properties.
+
+A Value Object is typically owned by a parent [Entity](https://docs.abp.io/en/abp/latest/Entities) object. Using [Complex Types](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#value-objects-using-complex-types) with EF Core 8 is the best way to create Value Objects that are stored as a part of your main entity.
+
+## Creating an ABP Project
+
+> **WARNING**: ABP Framework has not a .NET 8.0 compatible version yet. It is planned to be released on November 15, 2023. I created this project with ABP 7.4.1 (based on .NET 7.0), then manually changed the `TargetFramework` (in the `csproj`) to `net8.0` and added the `Microsoft.EntityFrameworkCore.SqlServer` package with version `8.0.0-rc.2.23480.1`. After that, the project is being compiled, but some parts of this article may not work as expected until ABP Framework 8.0-RC.1 is released.
+>
+> **I will update the article once ABP Framework 8.0-RC.1 is released.**
+
+I will show code examples, so I am creating a new ABP project using the following [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) command:
+
+````bash
+abp new ComplexTypeDemo -t app-nolayers
+````
+
+> I prefer a non-layered project to keep the things simple. If you are new to ABP Framework, follow the [Getting Started](https://docs.abp.io/en/abp/latest/Getting-Started-Overall) tutorial to learn how to create a new project from scratch.
+
+Once I created the solution, I am running the following command to execute the database migrations in order to create the initial database:
+
+````bash
+dotnet run --project ComplexTypeDemo --migrate-database
+````
+
+> We could also execute the `migrate-database.ps1` (that is coming as a part of the solution) as a shortcut.
+
+## Creating a Complex Type
+
+Assume that we have a `Customer` [entity](https://docs.abp.io/en/abp/latest/Entities) as shown below:
+
+````csharp
+public class Customer : BasicAggregateRoot
+{
+ public string Name { get; set; }
+ public Address HomeAddress { get; set; }
+ public Address BusinessAddress { get; set; }
+}
+````
+
+Here, we have two address properties, one for home and the other one for business. Since an address is a multi-values property, we can define it as a separate object:
+
+````csharp
+public class Address
+{
+ public string City { get; set; }
+ public string Line1 { get; set; }
+ public string? Line2 { get; set; }
+ public string PostCode { get; set; }
+}
+````
+
+`Address` is a typical complex object. It is actually a part of the `Customer` object, but we wanted to collect its parts into a dedicated class to make it a domain concept and easily manage its properties together.
+
+## Configure EF Core Mappings
+
+We should set the `Address` class as a Complex Type in our EF Core mapping configuration. There are two ways of it.
+
+As the first way, we can add the `ComplexType` attribute on top of the `Address` class:
+
+````csharp
+[ComplexType] // Added this line
+public class Address
+{
+ ...
+}
+````
+
+As an alternative, we can configure the mapping using the fluent mapping API. You can write the following code into the `OnModelCreating` method of your `DbContext` class:
+
+````csharp
+builder.Entity(b =>
+{
+ b.ToTable("Customers");
+ b.ComplexProperty(x => x.HomeAddress); // Mapping a Complex Type
+ b.ComplexProperty(x => x.BusinessAddress); // Mapping another Complex Type
+ //... configure other properties
+});
+
+````
+
+You can further configure the properties of the `Address` class:
+
+````csharp
+b.ComplexProperty(x => x.HomeAddress, a =>
+{
+ a.Property(x => x.City).HasMaxLength(50).IsRequired();
+});
+````
+
+Once you configure the mappings, you can use the [EF Core command-line tool](https://learn.microsoft.com/en-us/ef/core/cli/dotnet) to create a database migration:
+
+````bash
+dotnet ef migrations add "Added_Customer_And_Address"
+````
+
+And update the database:
+
+````bash
+dotnet ef database update
+````
+
+If you check the fields of the `Customers` table in your database, you will see the following fields:
+
+* `Id`
+* `Name`
+* `HomeAddress_City`
+* `HomeAddress_Line1`
+* `HomeAddress_Line2`
+* `HomeAddress_PostCode`
+* `BusinessAddress_City`
+* `BusinessAddress_Line1`
+* `BusinessAddress_Line2`
+* `BusinessAddress_PostCode`
+
+As you see, EF Core stores the `Address` properties as a part of your main entity.
+
+## Querying Objects
+
+You can query entities from database using the properties of a complex type as same as you query by the properties of the main entity.
+
+**Example: Find customers by `BusinessAddress.PostCode`:**
+
+````csharp
+public class MyService : ITransientDependency
+{
+ private readonly IRepository _customerRepository;
+
+ public MyService(IRepository customerRepository)
+ {
+ _customerRepository = customerRepository;
+ }
+
+ public async Task DemoAsync()
+ {
+ var customers = await _customerRepository.GetListAsync(
+ c => c.BusinessAddress.PostCode == "12345"
+ );
+
+ //...
+ }
+}
+````
+
+## Mutable vs Immutable
+
+Entity Framework Core Complex Types can work with mutable and immutable types. In the `Address` example above, I've shown a simple mutable class - that means you can change an individual property of an `Address` object after creating it (or after querying from database). However, designing Value Objects as immutable is a highly common approach.
+
+For example, you can use C#'s `struct` type to define an immutable `Address` type:
+
+````csharp
+public readonly struct Address(string line1, string? line2, string city, string postCode)
+{
+ public string City { get; } = city;
+ public string Line1 { get; } = line1;
+ public string? Line2 { get; } = line2;
+ public string PostCode { get; } = postCode;
+}
+````
+
+See the [Microsoft's documentation](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#mutability) for more examples and different usages.
+
+## Final Notes
+
+There are more details about using Complex Types in your applications. I want to mention some of them here:
+
+* You can have nested complex types. For example, `Address` may have one or more `PhoneNumber` objects as its properties. Everything will work seamlessly.
+* A single instance of a Complex Type can be set to multiple properties (of the same or different entities). In that case, changing the Complex object's properties will affect all of the properties. However, try to avoid that since it may create unnecessary complexities in your code that is hard to understand.
+* You can manipulate mutable complex object properties just as another property in your entity. EF Core change tracking system will track them as you expect.
+* Currently, EF Core doesn't support to have a collection of complex objects in an entity. It works only for properties.
+
+For more details and examples, see the Microsoft's document in the *References* section.
+
+## Source Code
+
+You can find the sample project here:
+
+[https://github.com/hikalkan/samples/tree/master/EfCoreComplexTypeDemo](https://github.com/hikalkan/samples/tree/master/EfCoreComplexTypeDemo)
+
+## References
+
+* [Value objects using Complex Types](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#value-objects-using-complex-types) in [What's new with EF Core 8.0](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew) document by Microsoft.
+* [ABP Entity Framework Core integration document](https://docs.abp.io/en/abp/latest/Entity-Framework-Core)
+
diff --git a/docs/en/Community-Articles/2023-11-06- SerializationDeserialization-Improvements/POST.md b/docs/en/Community-Articles/2023-11-06- SerializationDeserialization-Improvements/POST.md
new file mode 100644
index 0000000000..74022bd572
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-06- SerializationDeserialization-Improvements/POST.md
@@ -0,0 +1,100 @@
+# .NET 8: Serialization Improvements
+
+The [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/api/system.text.json) namespace provides functionality for serializing to and deserializing from JSON. In .NET 8, there have been many improvements to the System.Text.Json serialization and deserialization functionality.
+
+## Source generator
+
+.NET 8 includes enhancements of the System.Text.Json source generator that are aimed at making the Native AOT experience on par with the reflection-based serializer. This is important because now you can select the source generator for System.Text.Json. To see a comparison of Reflection versus source generation in System.Text.Json, check out the comparison [documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/reflection-vs-source-generation?pivots=dotnet-8-0#reflection).
+
+## Interface hierarchies
+
+.NET 8 adds support for serializing properties from interface hierarchies. Here is a code sample that shows this feature.
+
+```csharp
+ICar car = new MyCar { Color = "Red", NumberOfWheels = 4 };
+JsonSerializer.Serialize(car); // {"Color":"Red","NumberOfWheels":4}
+
+public interface IVehicle
+{
+ public string Color { get; set; }
+}
+
+public interface ICar : IVehicle
+{
+ public int NumberOfWheels { get; set; }
+}
+
+public class MyCar : ICar
+{
+ public string Color { get; set; }
+ public int NumberOfWheels { get; set; }
+}
+```
+
+## Naming policies
+
+Two new naming policies `snake_case` and `kebab-case` have been added. You can use them as shown below:
+
+```csharp
+var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
+JsonSerializer.Serialize(new { CreationTime = new DateTime(2023,11,6) }, options); // {"creation_time":"2023-11-06T00:00:00"}
+```
+
+## Read-only properties
+
+With .NET 8, you can deserialize onto read-only fields or properties. This feature can be globally enabled by setting `PreferredObjectCreationHandling` to `JsonObjectCreationHandling.Populate`. You can also enable this feature for a class or one of its members by adding the `[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]` attribute. Here is a sample:
+
+```csharp
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+var book = JsonSerializer.Deserialize("""{"Contributors":["John Doe"],"Author":{"Name":"Sample Author"}}""")!;
+Console.WriteLine(JsonSerializer.Serialize(book));
+
+class Author
+{
+ public required string Name { get; set; }
+}
+
+[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
+class Book
+{
+ // Both of these properties are read-only.
+ public List Contributors { get; } = new();
+ public Author Author { get; } = new() {Name = "Undefined"};
+}
+```
+
+Before .NET 8, the output was like this:
+
+```json
+{"Contributors":[],"Author":{"Name":"Undefined"}}
+```
+
+With .NET 8, the output now looks like this:
+
+```json
+{"Contributors":["John Doe"],"Author":{"Name":"Sample Author"}}
+```
+
+## Disable reflection-based default
+
+One of the nice features about Serialization is, now you can disable using the reflection-based serializer by default. To disable default reflection-based serialization, set the `JsonSerializerIsReflectionEnabledByDefault` MSBuild property to `false` in your project file.
+
+## Streaming deserialization APIs
+
+.NET 8 includes new `IAsyncEnumerable` streaming deserialization extension methods. The new extension methods invoke streaming APIs and return `IAsyncEnumerable`. Here is a sample code that uses this new feature.
+
+```csharp
+const string RequestUri = "https://yourwebsite.com/api/saas/tenants?skipCount=0&maxResultCount=10";
+using var client = new HttpClient();
+IAsyncEnumerable tenants = client.GetFromJsonAsAsyncEnumerable(RequestUri);
+
+await foreach (Tenant tenant in tenants)
+{
+ Console.WriteLine($"* '{tenant.name}' uses '{tenant.editionName
+}' edition");
+}
+```
+
+I have mentioned some of the items for Serialization Improvements in .NET 8. If you want to check the full list, you can read it in the .NET 8's [What's new document](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8#serialization).
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/Post.md b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/Post.md
new file mode 100644
index 0000000000..c3203d481d
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/Post.md
@@ -0,0 +1,94 @@
+# Blazor's History and Full-stack Web UI
+
+
+
+
+Blazor is a web framework that allows developers to build interactive web applications using .NET instead of JavaScript. The first version of Blazor was released on May 14, 2020. Since its initial release, Blazor has evolved with the new versions. Until now, six different versions have been declared. Sometimes, it can be not very clear to see the differences between these approaches. First, let's try to understand these.
+
+* **Blazor-Server**: >> *Loads fast at first* >> In this version, heavy things are done in the server. Browsers are thin clients and download a small page for the first load. The page updates are done via SignalR connection. This was released with .NET Core 3.
+* **Blazor WebAssembly (WASM):** >> *Loads slow at first* >> In this version, some binary files are being downloaded to the browser. This approach takes longer initialization time than the "Server" approach. The hard work is done on the browser.
+* **Blazor Hybrid:** It's a combination of Blazor and Xamarin.Forms. It allows you to run your app on iOS, Android, macOS, and Windows. Blazor Hybrid uses a WebView component to host the Blazor-based user interface within the mobile app.
+* **Blazor Native**: It runs natively on the devices and uses a common UI abstraction to render native controls for that device. This is very similar to how frameworks like Xamarin Forms or React Native work today. It has also been considered but has not reached [the planning stage](https://devblogs.microsoft.com/dotnet/blazor-server-in-net-core-3-0-scenarios-and-performance/).
+
+* **Blazor United**: Recently, Microsoft updated this name to "Fullstack web UI". Blazor-Server and Blazor WASM both have some disadvantages and advantages. So, Microsoft decided to combine these two approaches and find an optimum solution for the entire Blazor version. We can call it *Best of Blazor* 😀
+
+## Why is "Blazor Fullstack Web UI" the best?
+
+These apps are a combination of both Blazor Server and Blazor WASM. It provides the advantages of Blazor Server and WASM. Developers would be able to more fine-tune the rendering mode. **This approach overcomes the large binary downloads of Blazor WASM, and it resolves the Blazor Server's problem, which always needs to be connected to the server via SignalR.**
+
+> Blazor Fullstack Web UI comes with the .NET 8, and it will be published on November 14, 2023.
+
+I took the following photo from Steven Sanderson's talk at NDC Porto 2023. You can read my impressions of this conf at https://volosoft.com/blog/ndc-port-2023-impressions, but after reading this one.
+
+
+
+
+
+There are two basic page styles:
+
+* **HTML**; simple and loads fast! Eg: MVC, Razor Pages
+* **Single Page Apps (SPA):** high interaction with the client and loads slower! Eg: Blazor WASM, Blazor Server...
+
+## HTML + SPA => Blazor Fullstack
+
+Blazor Fullstack (formerly United) is a technology that turns Blazor Server into a SPA style.
+
+.NET 8 will combine Blazor Server's server-side rendering and WebAssembly's client-side interaction.
+
+You can switch between two rendering modes and even mix them on the same page. With .NET 8 there also comes amazing features like;
+
+* [Streaming rendering](https://github.com/dotnet/aspnetcore/issues/46352): With this feature, most of the page will be rendered, and long async operations on the server will still be in progress.
+
+* [Progressive enhancement of form submission & navigation](https://github.com/dotnet/aspnetcore/issues/46399): With this feature, it doesn't fully reload the page after submitting the form. This gives the user a better and smoother experience.
+
+
+
+## How it works?
+
+### Rendering on Server
+
+You can add `WebComponentRenderMode.Server` to your Blazor components so that these components will run interactively. In the below example, the list editor will make AJAX requests to the server like single-page applications.
+
+
+
+
+
+And sure, you can add `WebComponentRenderMode.Server` to your page level, and the complete page will be rendered as a server component. All inputs on this page can work as an interactive server component like SPA mode.
+
+
+
+
+
+### Rendering on Client
+
+You can switch to WebAssembly mode by writing `WebComponentRenderMode.WebAssembly` attribute to your page. By doing so, the whole page should run interactively using WebAssembly. This time there's no server connection anymore because it loads the binaries (WebAssembly runtimes) at the page load.
+
+
+
+
+## Enabling the Blazor Fullstack UI?
+
+To enable Blazor Full-stack Web UI, you need to write `net8.0;net7.0-browser` into the `TargetFrameworks` area of your `csproj` file. These two keywords change your app like this; `net8.0` framework renders on the server, and `net7.0-browser` framework renders on the browser.
+
+
+
+
+## Let the System Decide WebAssembly or Server Approach
+
+You can let the system decide whether it uses `WebAssembly` or `Server`. This can be done with the `Auto` mode of the `WebComponentRenderMode`. In this case, it will not load binary files (WebAssembly files) for the initial page that has `WebComponentRenderMode.Server` attribute, but whenever the user navigates to a page that has `WebComponentRenderMode.WebAssembly`, it will download the runtimes. This will allow us to load the initial page very fast, and when we need interactivity, we can switch to `WebAssembly` and wait for the binaries to download. But this download will be done one time because it will be cached.
+
+
+
+
+
+## Conclusion
+
+I summarized the new generation Blazor in a very simple way. This architecture will be useful to everyone who uses Blazor.
+
+---
+
+*Resources:*
+
+* You can check Dan Roth's GitHub issue 👉 [github.com/dotnet/aspnetcore/issues/46636](https://github.com/dotnet/aspnetcore/issues/46636).
+* Steven Sanderson's YouTube video is very good for understanding these concepts 👉 [Blazor United Prototype Video](https://youtu.be/48G_CEGXZZM).
+
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/cover-image.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/cover-image.png
new file mode 100644
index 0000000000..b3f1d6920e
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/cover-image.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106163046763-1699282281622-2.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106163046763-1699282281622-2.png
new file mode 100644
index 0000000000..62c2bcea95
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106163046763-1699282281622-2.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172420148.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172420148.png
new file mode 100644
index 0000000000..62d2a704b8
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172420148.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172638604.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172638604.png
new file mode 100644
index 0000000000..f28987d536
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106172638604.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173021958.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173021958.png
new file mode 100644
index 0000000000..6120776e90
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173021958.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173411309.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173411309.png
new file mode 100644
index 0000000000..2cc92a9ee3
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173411309.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173849303.png b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173849303.png
new file mode 100644
index 0000000000..13413ca55f
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/image-20231106173849303.png differ
diff --git a/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/POST.md b/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/POST.md
new file mode 100644
index 0000000000..a3c143a9c8
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/POST.md
@@ -0,0 +1,79 @@
+# HierarchyId Support in Entity Framework Core
+
+Entity Framework Core has official support for HierarchyId, which allows you to store and query hierarchical data in SQL Server databases. Hierarchical data is a common data structure found in many applications. Whether you are dealing with organizational structures, product categories, or threaded discussions, handling hierarchies efficiently is crucial. In this blog post, we will explore how to manage hierarchical data using Entity Framework Core (EF Core) in combination with HierarchyId.
+
+## How to use HierarchyId in EF Core
+
+To use HierarchyId in EF Core, you need to install the [Microsoft.EntityFrameworkCore.SqlServer.HierarchyId](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer.HierarchyId/) NuGet package. This package contains query and update support for HierarchyId.
+
+To configure EF Core to use HierarchyId, you need to call the `UseHierarchyId` method when configuring the SQL Server provider.
+
+```csharp
+options.UseSqlServer(
+ connectionString,
+ x => x.UseHierarchyId());
+```
+
+## Modeling Hierarchies
+
+The `HierarchyId` type can be used for properties of an entity type. For example, assume we want to model the personnel in an organization. Each person has a name and a manager. The manager is also a person. We can model this using the following entity type:
+
+```csharp
+public class Person
+{
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public HierarchyId Manager { get; set; }
+}
+```
+
+Each person can be traced from the patriarch down the tree using its `Manager` property. SQL Server uses a compact binary format for these paths, but it is common to parse to and from a human-readable string representation when working with code. In this representation, the position at each level is separated by a `/` character.
+
+
+
+## Querying Hierarchies
+
+HierarchyId exposes several methods that can be used in LINQ queries.
+
+* `GetAncestor(int level)` returns the ancestor at the specified level.
+
+* `GetDescendant(HierarchyId? child1, HierarchyId? child2)` returns the descendant at the specified level.
+
+* `GetLevel()` returns the level of the node in the hierarchy.
+
+* `GetReparentedValue(HierarchyId? oldRoot, HierarchyId? newRoot)` returns the node with a new parent.
+
+* `IsDescendantOf(HierarchyId? parent)` returns whether the node is a descendant of the specified node.
+
+Example:
+
+```csharp
+// Get entities at a given level in the tree
+var generation = await context.Persons.Where(x => x.Manager.GetLevel() == level).ToListAsync();
+
+// Get the direct ancestor of an entity
+var parent = await context.Persons.Where(x => x.Manager.GetAncestor(1) == manager).SingleAsync();
+```
+
+For example, your company may want to change the manager of an organizational unit. To do this, you can use the `GetReparentedValue` method to update the manager for all descendants of the organizational unit.
+
+```csharp
+var newManager = await context.Persons.SingleAsync(x => x.Id == newManagerId);
+
+var descendants = await context.Persons
+ .Where(x => x.Manager.IsDescendantOf(oldManager))
+ .ToListAsync();
+
+foreach (var descendant in descendants)
+{
+ descendant.Manager = descendant.Manager.GetReparentedValue(oldManager.Manager, newManager.Manager);
+}
+
+await context.SaveChangesAsync();
+```
+
+## References
+
+For more information about hierarchy id, see the following resource:
+
+- [https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#hierarchyid-in-net-and-ef-core](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#hierarchyid-in-net-and-ef-core)
diff --git a/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/hierarchy-tree.png b/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/hierarchy-tree.png
new file mode 100644
index 0000000000..e22ed9781c
Binary files /dev/null and b/docs/en/Community-Articles/2023-11-06-EF-Core_Hierarchy-Id/hierarchy-tree.png differ
diff --git a/docs/en/Community-Articles/2023-11-16-Upgrading-Your-Existing-Projects-to-NET8/POST.md b/docs/en/Community-Articles/2023-11-16-Upgrading-Your-Existing-Projects-to-NET8/POST.md
new file mode 100644
index 0000000000..cc154ad9c1
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-16-Upgrading-Your-Existing-Projects-to-NET8/POST.md
@@ -0,0 +1,95 @@
+# Upgrade Your Existing Projects to .NET 8 & ABP 8.0
+
+A new .NET version was released on November 14, 2023 and ABP 8.0 RC.1 shipped based on .NET 8.0 just after Microsoft's .NET 8.0 release. Therefore, it's a good time to see what we need to do to upgrade our existing projects to .NET 8.0.
+
+Despite all the related dependency upgrades and changes made on ABP Framework and ABP Commercial sides, we still need to make some changes. Let's see the required actions that need to be taken in the following sections.
+
+## Installing the .NET 8.0 SDK
+
+To get started with ASP.NET Core in .NET 8.0, you need to install the .NET 8 SDK. You can install it at [https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).
+
+After installing the SDK & Runtime, you can upgrade your existing ASP.NET Core application to .NET 8.0.
+
+## Updating the Target Framework
+
+First, you need to update all your `*.csproj` files to support .NET 8. Find and replace all your `TargetFramework` definitions in the `*.csproj` files to support .NET 8.0:
+
+```xml
+net8.0
+```
+
+> This and all other changes mentioned in this article have already been done in the ABP Framework and ABP Commercial side, so you would not get any problems related to that.
+
+## Updating Microsoft Package Versions
+
+You are probably using some Microsoft packages in your solution, so you need to update them to the latest .NET 8.0 version. Therefore, update all `Microsoft.AspNetCore.*` and `Microsoft.Extensions.*` packages' references to `8.0.0`.
+
+## Checking the Breaking Changes in .NET 8.0
+
+As I have mentioned earlier in this article, on the ABP Framework & ABP Commercial sides all the related code changes have been made, so you would not get any error related to breaking changes introduced with .NET 8.0. However, you still need to check the [Breaking Changes in .NET 8.0 documentation](https://learn.microsoft.com/en-us/dotnet/core/compatibility/8.0), because the breaking changes listed in this documentation still might affect you. Therefore, read them accordingly and make the related changes in your application, if needed.
+
+## Update Your Global Dotnet CLI Tools (optional)
+
+You can update the global dotnet tools to the latest version by running the `dotnet tool update` command. For example, if you are using EF Core, you can update your `dotnet-ef` CLI tool with the following command:
+
+```bash
+dotnet tool update dotnet-ef --global
+```
+
+## Installing/Restoring the Workloads (required for Blazor WASM & MAUI apps)
+
+The `dotnet workload restore` command installs the workloads needed for a project or a solution. This command analyzes a project or solution to determine which workloads are needed and if you have a .NET MAUI or Blazor-WASM project, you can update your workloads by running the following command in a terminal:
+
+```bash
+dotnet workload restore
+```
+
+## Docker Image Updates
+
+If you are using Docker to automate the deployment of applications, you also need to update your images.
+
+For example, you can update the ASP.NET Core image as follows:
+
+```diff
+- FROM mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim AS base
++ FROM mcr.microsoft.com/dotnet/aspnet:8.0-bullseye-slim AS base
+```
+
+You can check the related images from Docker Hub and update them accordingly:
+
+* [https://hub.docker.com/_/microsoft-dotnet-aspnet/](https://hub.docker.com/_/microsoft-dotnet-aspnet/)
+* [https://hub.docker.com/_/microsoft-dotnet-sdk/](https://hub.docker.com/_/microsoft-dotnet-sdk/)
+* [https://hub.docker.com/_/microsoft-dotnet-runtime/](https://hub.docker.com/_/microsoft-dotnet-runtime/)
+
+## Upgrading Your Existing Projects to ABP 8.0
+
+Updating your application to ABP 8.0 is pretty straight-forward. You first need to upgrade the ABP CLI to version `8.0.0-rc.1` using a command line terminal:
+
+````bash
+dotnet tool update Volo.Abp.Cli -g --version 8.0.0-rc.1
+````
+
+**or install** it if you haven't before:
+
+````bash
+dotnet tool install Volo.Abp.Cli -g --version 8.0.0-rc.1
+````
+
+Then, you can use the `abp update` command to update all the ABP related NuGet and NPM packages in your solution:
+
+```bash
+abp update --version 8.0.0-rc.1
+```
+
+After that, you need to check the migration guide documents, listed below:
+
+* [ABP Framework 7.x to 8.0 Migration Guide](https://docs.abp.io/en/abp/8.0/Migration-Guides/Abp-8_0)
+* [ABP Commercial 7.x to 8.0 Migration Guide](https://docs.abp.io/en/commercial/8.0/migration-guides/v8_0)
+
+> Check these documents carefully and make the related changes in your solution to prevent errors.
+
+## Final Words
+
+That's it! These were all the related steps that need to be taken to upgrade your application to .NET 8 and ABP 8.0. Now, you can enjoy the .NET 8 & ABP 8.0 and benefit from the performance improvements and new features.
+
+Happy Coding 🤗
diff --git a/docs/en/Community-Articles/2023-11-97-AOT-Compilation/Post.md b/docs/en/Community-Articles/2023-11-97-AOT-Compilation/Post.md
new file mode 100644
index 0000000000..b39a2af339
--- /dev/null
+++ b/docs/en/Community-Articles/2023-11-97-AOT-Compilation/Post.md
@@ -0,0 +1,72 @@
+# Native AOT Compilation in .NET 8
+Native AOT (Ahead-of-Time) compilation is a feature that allows developers to create a self-contained app compiled to native code that can run on machines without the .NET runtime installed. It results in benefits such as minimized disk footprint, reduced executable size, reduced startup time, and reduced memory demand.
+
+Native AOT compilation isn't a new feature in .NET 8. It's first introduced in .NET 7.
+
+
+Differences between the AOT Compilation of .NET 7 and .NET 8 are:
+
+
+- **System.Text.Json improvements**: .NET 8 adds support for more types, source generation, interface hierarchies, naming policies, read-only properties, and more.
+- **New types for performance**: .NET 8 introduces new types such as FrozenDictionary, FrozenSet, SearchValues, CompositeFormat, TimeProvider, and ITimer to improve the app performance.
+- **System.Numerics and System.Runtime.Intrinsics enhancements**: .NET 8 adds support for Vector512, AVX-512, IUtf8SpanFormattable, Lerp, and more.
+- **System.ComponentModel.DataAnnotations additions**: .NET 8 adds new data validation attributes for cloud-native services and a new ValidateOptionsResultBuilder type.
+- **Hosted services lifecycle methods**: .NET 8 adds new methods such as StartAsync, StopAsync, StartBackgroundAsync, and StopBackgroundAsync for hosted services.
+
+It's important to note that not all features in ASP.NET Core are currently compatible with native AOT. For more information, see [Native AOT deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/).
+
+## How to use Native AOT Compilation in .NET 8
+
+You can add `true` in your project .csproj file to enable Native AOT Compilation.
+
+ - For the new projects, you can create them with the `--aot` parameter. Example: `dotnet new console --aot`.
+
+By default, the compiler chooses a blended approach code optimization but you can specify an optimization preference inside your .csproj file. You can choose **size** or **speed** according your requirements.
+
+```xml
+Size
+```
+
+or
+
+```xml
+Speed
+```
+
+### Results
+
+I have created a simple console application to test the Native AOT Compilation. I have used a simple console application that writes "Hello World!" to the console 100 times. I have tested the application with different optimization preferences. I have used the following results:
+
+
+| | Size | Speed |
+| --- | --- | --- |
+| .NET 8 _(Self-Contained, Single File)_ | 65938 kb | 00.0051806 ~5ms |
+| .NET 7 AOT (default) | 4452 kb | 00.0029823 ~2ms |
+| .NET 8 AOT (default) | 1242 kb | 00.0028638 ~2ms |
+| AOT (Speed)| 1280 kb | 00.0023838 ~2ms |
+| AOT (Size) | 1111 kb | 00.0025145 ~2ms |
+
+Most of existing libraries don't support AOT compilation yet, so I couldn't use [BenchmarkDotnet](https://github.com/dotnet/BenchmarkDotNet) to measure the performance. I have used [Stopwatch](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=net-8.0) to measure the performance. So the performance results may not be accurate but gives insight about the performance difference.
+
+## AOT Support in MAUI
+You can now use Native AOT Compilation on iOS-like target frameworks in .NET MAUI. You can enable AOT compilation with the exact same method by adding `true` to your project .csproj file. According to the dotnet team, apps sizes reduced by 35% and startup times reduced by 28% with AOT compilation. And runtime performance is also improved by 50%.
+
+But there are some limitations in MAUI AOT Compilation. A lot of libraries still don't support AOT compilation and some of platform-specific feaetures may not work at the moment.
+
+## When to use Native AOT Compilation?
+
+Native AOT Compilation is beneficial when you need to optimize your .NET application for speed and size. It's particularly useful for applications that require quick startup times and efficient runtime performance, such as mobile apps or high-performance computing applications.
+
+However, due to its current limitations, it might not be suitable for all projects. If your project relies heavily on libraries that do not support AOT compilation, or if it uses platform-specific features that are not yet compatible with AOT, you might want to hold off on using Native AOT Compilation until further improvements are made.
+
+Always consider the specific needs and constraints of your project before deciding to use Native AOT Compilation.
+
+## Conclusion
+
+Native AOT Compilation is a great feature that improves the performance of .NET applications. It's still in early-stages and not all libraries support it yet. But it's a great beginning for the future of .NET 🚀
+
+## Links
+- Native AOT deployment overview - .NET | Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/.
+- Optimize AOT deployments https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/optimizing
+- What's new in .NET 8 | Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8.
+
diff --git a/docs/en/Dapr/Index.md b/docs/en/Dapr/Index.md
index 060b31aac3..464b56ea30 100644
--- a/docs/en/Dapr/Index.md
+++ b/docs/en/Dapr/Index.md
@@ -60,29 +60,6 @@ Alternatively, you can configure the options in the `Dapr` section of your `apps
}
````
-### Injecting DaprClient
-
-ABP registers the `DaprClient` class to the [dependency injection](../Dependency-Injection.md) system. So, you can inject and use it whenever you need:
-
-````csharp
-public class MyService : ITransientDependency
-{
- private readonly DaprClient _daprClient;
-
- public MyService(DaprClient daprClient)
- {
- _daprClient = daprClient;
- }
-
- public async Task DoItAsync()
- {
- // TODO: Use the injected _daprClient object
- }
-}
-````
-
-Injecting `DaprClient` is the recommended way of using it in your application code. When you inject it, the `IAbpDaprClientFactory` service is used to create it, which is explained in the next section.
-
### IAbpDaprClientFactory
`IAbpDaprClientFactory` can be used to create `DaprClient` or `HttpClient` objects to perform operations on Dapr. It uses `AbpDaprOptions`, so you can configure the settings in a central place.
@@ -113,15 +90,14 @@ public class MyService : ITransientDependency
});
// Create an HttpClient object
- HttpClient httpClient = await _daprClientFactory
- .CreateHttpClientAsync("target-app-id");
+ HttpClient httpClient = await _daprClientFactory.CreateHttpClientAsync("target-app-id");
}
}
````
`CreateHttpClientAsync` method also gets optional `daprEndpoint` and `daprApiToken` parameters.
-> ABP uses `IAbpDaprClientFactory` when it needs to create a Dapr client. You can also use Dapr API to create client objects in your application. Using `IAbpDaprClientFactory` is recommended, but not required.
+> You can use Dapr API to create client objects in your application. Using `IAbpDaprClientFactory` is recommended, but not required.
## C# API Client Proxies Integration
@@ -412,7 +388,7 @@ Or you can set it in your `appsettings.json` file:
}
````
-Once you set it, it is used when you inject `DaprClient` or use `IAbpDaprClientFactory`. If you need that value in your application, you can inject `IDaprApiTokenProvider` and use its `GetDaprApiToken()` method.
+Once you set it, it is used when you use `IAbpDaprClientFactory`. If you need that value in your application, you can inject `IDaprApiTokenProvider` and use its `GetDaprApiToken()` method.
### App API Token
diff --git a/docs/en/Deployment/Configuring-OpenIddict.md b/docs/en/Deployment/Configuring-OpenIddict.md
index bf7bc9c619..b044bcb275 100644
--- a/docs/en/Deployment/Configuring-OpenIddict.md
+++ b/docs/en/Deployment/Configuring-OpenIddict.md
@@ -2,61 +2,46 @@
This document introduces how to configure `OpenIddict` in the `AuthServer` project.
-There are different configurations in the `AuthServer` project for `Development` and `Production` environment.
+There are different configurations in the `AuthServer` project for the `Development` and `Production` environments.
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
- // Development environment
- if (hostingEnvironment.IsDevelopment())
- {
- PreConfigure(options =>
- {
- // This is default value, you can remove this line.
- options.AddDevelopmentEncryptionAndSigningCertificate = true;
- });
- }
-
- // Production or Staging environment
if (!hostingEnvironment.IsDevelopment())
{
- PreConfigure(options =>
- {
- options.AddDevelopmentEncryptionAndSigningCertificate = false;
- });
-
- PreConfigure(builder =>
- {
- builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment));
- builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment));
-
- //...
- });
+ PreConfigure(options =>
+ {
+ options.AddDevelopmentEncryptionAndSigningCertificate = false;
+ });
+
+ PreConfigure(serverBuilder =>
+ {
+ serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", "00000000-0000-0000-0000-000000000000");
+ });
}
}
-
-private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv)
-{
- return new X509Certificate2(Path.Combine(hostingEnv.ContentRootPath, "authserver.pfx"), "00000000-0000-0000-0000-000000000000");
-}
````
## Development Environment
-We've enabled `AddDevelopmentEncryptionAndSigningCertificate` by default on development environment, It registers (and generates if necessary) a user-specific development encryption/development signing certificate. This is a certificate used for signing and encrypting the tokens and for **development environment only**.
+We've enabled `AddDevelopmentEncryptionAndSigningCertificate` by default on the development environment. It registers (and generates if necessary) a user-specific development encryption/development signing certificate. This is a certificate used for signing and encrypting the tokens and for **development environment only**.
`AddDevelopmentEncryptionAndSigningCertificate` cannot be used in applications deployed on IIS or Azure App Service: trying to use them on IIS or Azure App Service will result in an exception being thrown at runtime (unless the application pool is configured to [load a user profile](https://learn.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities#user-profile)).
-To avoid that, consider creating self-signed certificates and storing them in the X.509 certificates storage of the host machine(s). This is the way we do it in production environment.
+To avoid that, consider creating self-signed certificates and storing them in the X.509 certificates storage of the host machine(s). This is the way we do it in the production environment.
## Production Environment
-We've disabled `AddDevelopmentEncryptionAndSigningCertificate` in production environment and tried to setup signing and encrypting certificates using `authserver.pfx`.
+We've disabled `AddDevelopmentEncryptionAndSigningCertificate` in the production environment and tried to setup signing and encrypting certificates using `openiddict.pfx` file.
-You can use the `dotnet dev-certs https -v -ep authserver.pfx -p 00000000-0000-0000-0000-000000000000` command to generate the `authserver.pfx` certificate.
+You can use the `dotnet dev-certs https -v -ep openiddict.pfx -p 00000000-0000-0000-0000-000000000000` command to generate the `authserver.pfx` certificate.
> `00000000-0000-0000-0000-000000000000` is the password of the certificate, you can change it to any password you want.
-> Also, please remember to copy `authserver.pfx` to the [Content Root Folder](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvironment.contentrootpath?view=aspnetcore-7.0) of the `AuthServer` website.
+> Also, please remember to copy `openiddict.pfx` to the [Content Root Folder](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvironment.contentrootpath?view=aspnetcore-7.0) of the `AuthServer` website.
+
+> It is recommended to use **two** RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing.
+
+For more information, please refer to: https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios
diff --git a/docs/en/Deployment/Index.md b/docs/en/Deployment/Index.md
index cae5b8282d..cf7137464f 100644
--- a/docs/en/Deployment/Index.md
+++ b/docs/en/Deployment/Index.md
@@ -6,6 +6,7 @@ However, there are some topics that you should care about when you are deploying
## Guides
+* [Configuring SSL certificate(HTTPS)](SSL.md): Explains how to configure SSL certificate(HTTPS) for your application.
* [Configuring OpenIddict](Configuring-OpenIddict.md): Notes for some essential configurations for OpenIddict.
* [Configuring for Production](Configuring-Production.md): Notes for some essential configurations for production environments.
* [Optimization for Production](Optimizing-Production.md): Tips and suggestions for optimizing your application on production environments.
diff --git a/docs/en/Deployment/SSL.md b/docs/en/Deployment/SSL.md
new file mode 100644
index 0000000000..c48c916d93
--- /dev/null
+++ b/docs/en/Deployment/SSL.md
@@ -0,0 +1,34 @@
+# Configuring Configuring SSL certificate(HTTPS)
+
+A website needs an SSL certificate in order to keep user data secure, verify ownership of the website, prevent attackers from creating a fake version of the site, and gain user trust.
+
+This document introduces how to get and use SSL certificate(HTTPS) for your application.
+
+## Get a SSL Certificate from a Certificate Authority
+
+You can get a SSL certificate from a certificate authority (CA) such as [Let's Encrypt](https://letsencrypt.org/) or [Cloudflare](https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/) and so on.
+
+Once you have a certificate, you need to configure your web server to use it. The following references show how to configure your web server to use a certificate.
+
+* [Host ASP.NET Core on Linux with Apache: HTTPS configuration](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache)
+* [Host ASP.NET Core on Linux with Nginx: HTTPS configuration](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx)
+* [How to Set Up SSL on IIS 7 or later](https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis)
+
+## Create a Self-Signed Certificate
+
+You can create a self-signed certificate for testing purposes or internal use.
+
+There is an article about [how to create a self-signed certificate](https://learn.microsoft.com/en-us/dotnet/core/additional-tools/self-signed-certificates-guide), If you are using IIS, you can use the following this document to [obtain a Certificate](https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis#obtain-a-certificate)
+
+## Common Problems
+
+### The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
+
+This error may occur when using IIS. You need to trust your certificate by `Manage computer certificates`.
+
+## References
+
+* [ABP commercial IIS Deployment](https://docs.abp.io/en/commercial/latest/startup-templates/application/deployment-iis)
+* [HTTPS in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl)
+* [Let's Encrypt](https://letsencrypt.org/getting-started)
+* [Cloudflare's Free SSL / TLS](https://www.cloudflare.com/application-services/products/ssl/)
\ No newline at end of file
diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md
index 2fff974f50..fa825911f7 100644
--- a/docs/en/Distributed-Event-Bus.md
+++ b/docs/en/Distributed-Event-Bus.md
@@ -438,19 +438,23 @@ Enabling the event outbox and inbox systems require a few manual steps for your
### Enabling event outbox
-Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventOutbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
+Enabling event outbox depends on your database provider.
+
+#### Enabling event outbox for Entity Framework Core
+
+Open your `DbContext` class, implement the `IHasEventOutbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
```csharp
public DbSet OutgoingEvents { get; set; }
```
-Add the following lines inside the `OnModelCreating` method of your `DbContext` class (only for EF Core):
+Add the following lines inside the `OnModelCreating` method of your `DbContext` class:
```csharp
builder.ConfigureEventOutbox();
```
-For EF Core, use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database (you can skip this step for MongoDB). If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
+Use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database. If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
```bash
dotnet ef migrations add "Added_Event_Outbox"
@@ -469,23 +473,55 @@ Configure(options =>
});
````
-> **IMPORTANT**: Outbox sending service uses distributed locks to ensure only a single instance of your application consumes the outbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
+#### Enabling event outbox for MongoDB
+
+Open your `DbContext` class, implement the `IHasEventOutbox` interface. You should end up by adding a `IMongoCollection` property into your `DbContext` class:
+
+```csharp
+public IMongoCollection OutgoingEvents => Collection();
+```
+
+Add the following lines inside the `CreateModel` method of your `DbContext` class:
+
+```csharp
+modelBuilder.ConfigureEventOutbox();
+```
+
+Finally, write the following configuration code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md) (replace `YourDbContext` with your own `DbContext` class):
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure(config =>
+ {
+ config.UseMongoDbContext();
+ });
+});
+````
+
+#### Distributed Locking for Outbox
+
+> **IMPORTANT**: Outbox sending service uses distributed locks to ensure only a single instance of your application consumes the outbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the `options.Outboxes.Configure(...)` method) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
### Enabling event inbox
-Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventInbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
+Enabling event inbox depends on your database provider.
+
+#### Enabling event inbox for Entity Framework Core
+
+Open your `DbContext` class, implement the `IHasEventInbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
```csharp
public DbSet IncomingEvents { get; set; }
```
-Add the following lines inside the `OnModelCreating` method of your `DbContext` class (only for EF Core):
+Add the following lines inside the `OnModelCreating` method of your `DbContext` class:
```csharp
builder.ConfigureEventInbox();
```
-For EF Core, use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database (you can skip this step for MongoDB). If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
+Use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database. If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
```bash
dotnet ef migrations add "Added_Event_Inbox"
@@ -504,7 +540,35 @@ Configure(options =>
});
````
-**IMPORTANT**: Inbox processing service uses distributed locks to ensure only a single instance of your application consumes the inbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
+#### Enabling event inbox for MongoDB
+
+Open your `DbContext` class, implement the `IHasEventInbox` interface. You should end up by adding a `IMongoCollection` property into your `DbContext` class:
+
+```csharp
+public IMongoCollection IncomingEvents => Collection();
+```
+
+Add the following lines inside the `CreateModel` method of your `DbContext` class:
+
+```csharp
+modelBuilder.ConfigureEventInbox();
+```
+
+Finally, write the following configuration code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md) (replace `YourDbContext` with your own `DbContext` class):
+
+````csharp
+Configure(options =>
+{
+ options.Inboxes.Configure(config =>
+ {
+ config.UseMongoDbContext();
+ });
+});
+````
+
+#### Distributed Locking for Inbox
+
+> **IMPORTANT**: Inbox processing service uses distributed locks to ensure only a single instance of your application consumes the inbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the `options.Inboxes.Configure(...)` method) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
### Additional Configuration
@@ -529,7 +593,7 @@ Here, the following properties are available on the `config` object:
* `IsSendingEnabled` (default: `true`): You can set to `false` to disable sending outbox events to the actual event bus. If you disable this, events can still be added to outbox, but not sent. This can be helpful if you have multiple applications (or application instances) writing to outbox, but use one of them to send the events.
* `Selector`: A predicate to filter the event (ETO) types to be used for this configuration. Should return `true` to select the event. It selects all the events by default. This is especially useful if you want to ignore some ETO types from the outbox, or want to define named outbox configurations and group events within these configurations. See the *Named Configurations* section.
* `ImplementationType`: Type of the class that implements the database operations for the outbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages.
-* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event outbox* section.
+* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event outbox/inbox* sections.
#### Inbox configuration
diff --git a/docs/en/Dynamic-Claims.md b/docs/en/Dynamic-Claims.md
new file mode 100644
index 0000000000..a3940a142b
--- /dev/null
+++ b/docs/en/Dynamic-Claims.md
@@ -0,0 +1,81 @@
+# Dynamic Claims
+
+When a client authenticates and obtains an access token or an authentication cookie, the claims in that token or cookie are not changed unless it re-authenticates. For most of the claims, that may not be a problem since claims are not frequently changing values. However, some claims may be changed and these changes should be reflected to the current session immediately. For example, we can revoke a role from a user and that should be immediately effective, otherwise user will continue to use that role's permissions until re-login to the application.
+
+ABP's dynamic claims feature is used to automatically and dynamically override the configured claim values in the client's authentication token/cookie by the latest values of these claims.
+
+## How to Use
+
+This feature is disabled by default. You should enable it for your application and use the Dynamic Claims middleware.
+
+> **Beginning from the v8.0, all the [startup templates](Startup-Templates/Index.md) are pre-configured and the dynamic claims feature is enabled by default. So, if you have created a solution with v8.0 and above, you don't need to make any configuration. Follow the instructions only if you've upgraded from a version lower than 8.0.**
+
+### Enabling the Dynamic Claims
+
+You can enable it by the following code:
+
+````csharp
+public override void ConfigureServices(ServiceConfigurationContext context)
+{
+ context.Services.Configure(options =>
+ {
+ options.IsDynamicClaimsEnabled = true;
+ });
+}
+````
+
+This is typically done on the authentication server. In a monolith application, you will typically have a single application, so you can configure it. If you are using the tiered solution structure (where the UI part is hosted in a separate application) you will need to also set the `RemoteRefreshUrl` to the Authentication Server's URL in the UI application. Example:
+
+````csharp
+public override void ConfigureServices(ServiceConfigurationContext context)
+{
+ context.Services.Configure(options =>
+ {
+ options.IsDynamicClaimsEnabled = true;
+ options.RemoteRefreshUrl = configuration["AuthServerUrl"] + options.RemoteRefreshUrl;
+ });
+}
+````
+
+### The Dynamic Claims Middleware
+
+Add the `DynamicClaims` middleware to all the applications that performs authentication (including the authentication server):
+
+````csharp
+public override void OnApplicationInitialization(
+ ApplicationInitializationContext context)
+{
+ //...
+ app.UseDynamicClaims(); // Add this line before UseAuthorization.
+ app.UseAuthorization();
+ //...
+}
+````
+
+## How It Works
+
+The `DynamicClaims` middleware will use `IAbpClaimsPrincipalFactory` to dynamically generate claims for the current user(`HttpContext.User`) in each request.
+
+There are two pre-built implementations of `IAbpDynamicClaimsPrincipalContributor` for different scenarios:
+
+* `IdentityDynamicClaimsPrincipalContributor`: Provided by the [Identity module](Modules/Identity.md) and generates and overrides the actual dynamic claims, and writes to the distributed cache. Typically works in the authentication server in a distributed system.
+* `RemoteDynamicClaimsPrincipalContributor`: For distributed scenarios, this implementation works in the UI application. It tries to get dynamic claim values in the distributed cache. If not found in the distributed cache, it makes an HTTP call to the authentication server and requests filling it by the authentication server. `AbpClaimsPrincipalFactoryOptions.RemoteRefreshUrl` should be properly configure to make it running.
+
+### IAbpDynamicClaimsPrincipalContributor
+
+If you want to add your own dynamic claims contributor, you can create a class that implement the `IAbpDynamicClaimsPrincipalContributor` interface (and register it to the [dependency injection](Dependency-Injection.md) system. ABP Framework will call the `ContributeAsync` method to get the claims. It better to use a kind of cache to improve the performance since that is a frequently executed method (in every HTTP request).
+
+## AbpClaimsPrincipalFactoryOptions
+
+`AbpClaimsPrincipalFactoryOptions` is the main options class to configure the behavior of the dynamic claims system. It has the following properties:
+
+* `IsDynamicClaimsEnabled`: Enable or disable the dynamic claims feature.
+* `RemoteRefreshUrl`: The `url ` of the Auth Server to refresh the cache. It will be used by the `RemoteDynamicClaimsPrincipalContributor`. The default value is `/api/account/dynamic-claims/refresh ` and you should provide the full URL in the authentication server, like `http://my-account-server/api/account/dynamic-claims/refresh `.
+* `DynamicClaims`: A list of dynamic claim types. Only the claims in that list will be overridden by the dynamic claims system.
+* `ClaimsMap`: A dictionary to map the claim types. This is used when the claim types are different between the Auth Server and the client. Already set up for common claim types by default.
+
+## See Also
+
+* [Authorization](Authorization.md)
+* [Claims-based authorization in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/claims)
+* [Mapping, customizing, and transforming claims in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims)
diff --git a/docs/en/Emailing.md b/docs/en/Emailing.md
index bfb3058862..48635b2565 100644
--- a/docs/en/Emailing.md
+++ b/docs/en/Emailing.md
@@ -58,7 +58,11 @@ namespace MyProject
`SendAsync` method has overloads to supply more parameters like;
* **from**: You can set this as the first argument to set a sender email address. If not provided, the default sender address is used (see the email settings below).
+* **to**: You can set the target email address.
+* **subject**: You can set the email subject.
+* **body**: You can set the email body.
* **isBodyHtml**: Indicates whether the email body may contain HTML tags. **Default: true**.
+* **additionalEmailSendingArgs**: This parameter is used to pass additional arguments to the `IEmailSender` implementation. Include: CC(Carbon copy), a list of `EmailAttachment` and an extra properties.
> `IEmailSender` is the suggested way to send emails, since it makes your code provider independent.
diff --git a/docs/en/Entity-Framework-Core-Migrations.md b/docs/en/Entity-Framework-Core-Migrations.md
index 716038d412..9ac7e76f24 100644
--- a/docs/en/Entity-Framework-Core-Migrations.md
+++ b/docs/en/Entity-Framework-Core-Migrations.md
@@ -173,7 +173,7 @@ First step is to change the connection string section inside all the `appsetting
````json
"ConnectionStrings": {
- "Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
+ "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
@@ -184,7 +184,7 @@ Change it as shown below:
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True",
"AbpPermissionManagement": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore_SecondDb;Trusted_Connection=True",
"AbpSettingManagement": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore_SecondDb;Trusted_Connection=True",
- "AbpAuditLogging": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore_SecondDb;Trusted_Connection=True"
+ "AbpAuditLogging": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore_SecondDb;Trusted_Connection=True"
}
````
diff --git a/docs/en/Entity-Framework-Core.md b/docs/en/Entity-Framework-Core.md
index e2cfd21a05..cb9393b1aa 100644
--- a/docs/en/Entity-Framework-Core.md
+++ b/docs/en/Entity-Framework-Core.md
@@ -594,6 +594,18 @@ Whenever you access to a property/collection, EF Core automatically performs an
See also [lazy loading document](https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy) of the EF Core.
+## Read-Only Repositories
+
+ABP Framework provides read-only [repository](Repositories.md) interfaces (`IReadOnlyRepository<...>` or `IReadOnlyBasicRepository<...>`) to explicitly indicate that your purpose is to query data, but not change it. If so, you can inject these interfaces into your services.
+
+Entity Framework Core read-only repository implementation uses [EF Core's No-Tracking feature](https://learn.microsoft.com/en-us/ef/core/querying/tracking#no-tracking-queries). That means the entities returned from the repository will not be tracked by the EF Core [change tracker](https://learn.microsoft.com/en-us/ef/core/change-tracking/), because it is expected that you won't update entities queried from a read-only repository. If you need to track the entities, you can still use the [AsTracking()](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.entityframeworkqueryableextensions.astracking) extension method on the LINQ expression, or `EnableTracking()` extension method on the repository object (See *Enabling / Disabling the Change Tracking* section in this document).
+
+> This behavior works only if the repository object is injected with one of the read-only repository interfaces (`IReadOnlyRepository<...>` or `IReadOnlyBasicRepository<...>`). It won't work if you have injected a standard repository (e.g. `IRepository<...>`) then casted it to a read-only repository interface.
+
+## Enabling / Disabling the Change Tracking
+
+In addition to the read-only repositories, ABP allows to manually control the change tracking behavior for querying objects. Please see the *Enabling / Disabling the Change Tracking* section of the [Repositories documentation](Repositories.md) to learn how to use it.
+
## Access to the EF Core API
In most cases, you want to hide EF Core APIs behind a repository (this is the main purpose of the repository pattern). However, if you want to access the `DbContext` instance over the repository, you can use `GetDbContext()` or `GetDbSet()` extension methods. Example:
diff --git a/docs/en/Getting-Started-Running-Solution-Single-Layer.md b/docs/en/Getting-Started-Running-Solution-Single-Layer.md
index b200720415..58783b8c3b 100644
--- a/docs/en/Getting-Started-Running-Solution-Single-Layer.md
+++ b/docs/en/Getting-Started-Running-Solution-Single-Layer.md
@@ -20,7 +20,7 @@ Check the **connection string** in the `appsettings.json` file under the `YourPr
````json
"ConnectionStrings": {
- "Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
+ "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
diff --git a/docs/en/Getting-Started-Running-Solution.md b/docs/en/Getting-Started-Running-Solution.md
index a7771a0773..921fb2b247 100644
--- a/docs/en/Getting-Started-Running-Solution.md
+++ b/docs/en/Getting-Started-Running-Solution.md
@@ -21,7 +21,7 @@ Check the **connection string** in the `appsettings.json` file under the {{if Ti
````json
"ConnectionStrings": {
- "Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
+ "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
diff --git a/docs/en/Migration-Guides/Abp-8_0.md b/docs/en/Migration-Guides/Abp-8_0.md
new file mode 100644
index 0000000000..dd54665fbb
--- /dev/null
+++ b/docs/en/Migration-Guides/Abp-8_0.md
@@ -0,0 +1,288 @@
+# ABP Version 8.0 Migration Guide
+
+This document is a guide for upgrading ABP v7.x solutions to ABP v8.0. There are some changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
+
+> ABP Framework upgraded to .NET 8.0, so you need to move your solutions to .NET 8.0 if you want to use the ABP 8.0. You can check the [Migrate from ASP.NET Core 7.0 to 8.0](https://learn.microsoft.com/en-us/aspnet/core/migration/70-80) documentation.
+
+## Injected the `IDistributedEventBus` Dependency into the `IdentityUserManager`
+
+In this version, `IDistributedEventBus` service has been injected to the `IdentityUserManager` service, to publish a distributed event when the email or username is changed for a user, this was needed because sometimes there may be scenarios where the old email/username is needed for the synchronization purposes.
+
+Therefore, you might need to update the `IdentityUserManager`'s constructor if you have overridden the class and are using it.
+
+> See the issue for more information: https://github.com/abpframework/abp/pull/17990
+
+## Updated Method Signatures in the Bundling System
+
+In this version, ABP Framework introduced the CDN support for bundling. During the development, we have made some improvements on the bundling system and changed some method signatures.
+
+See https://github.com/abpframework/abp/issues/17864 for more information.
+
+## Replaced `IdentityUserLookupAppService` with the `IIdentityUserIntegrationService`
+
+[Integration Services](../Integration-Services.md) are built for module-to-module (or microservice-to-microservice) communication rather than consumed from a UI or a client application as [Application Services](../Application-Services.md) are intended to do.
+
+In that regard, we are discarding the `IIdentityUserLookupAppService` in the Identity Module and moving its functionality to the `IIdentityUserIntegrationService`. Therefore, if you have used that application service directly, use the integration service (`IIdentityUserIntegrationService`) instead. `IIdentityUserLookupAppService` will be removed in thes next versions, so you may need to create a similar service in your application.
+
+> Notice that integration services have no authorization and are not exposed as HTTP API by default.
+Also, if you have overridden the `IdentityUserLookupAppService` and `IdentityUserIntegrationService` classes in your application, you should update these classes' constructors as follows:
+
+*IdentityUserLookupAppService.cs*
+```csharp
+ public IdentityUserLookupAppService(IIdentityUserIntegrationService identityUserIntegrationService)
+ {
+ IdentityUserIntegrationService = identityUserIntegrationService;
+ }
+```
+
+*IdentityUserIntegrationService.cs*
+
+```diff
+ public IdentityUserIntegrationService(
+ IUserRoleFinder userRoleFinder,
++ IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider)
+ {
+ UserRoleFinder = userRoleFinder;
++ UserLookupServiceProvider = userLookupServiceProvider;
+ }
+```
+
+## MongoDB Event Bus Enhancements
+
+In this version, we have made some enhancements in the transactional inbox/outbox pattern implementation and defined two new methods: `ConfigureEventInbox` and `ConfigureEventOutbox` for MongoDB Event Box collections.
+
+If you call one of these methods in your DbContext class, then this introduces a breaking-change because if you do it, MongoDB collection names will be changed. Therefore, it should be carefully done since existing (non-processed) event records are not automatically moved to new collection and they will be lost. Existing applications with event records should rename the collection manually while deploying their solutions.
+
+See https://github.com/abpframework/abp/pull/17723 for more information. Also, check the documentation for the related configurations: [Distributed Event Bus](../Distributed-Event-Bus.md)
+
+## Moved the CMS Kit Pages Feature's Routing to a `DynamicRouteValueTransformer`
+
+In this version, we have made some improvements in the [CMS Kit's Pages Feature](../Modules/Cms-Kit/Pages.md), such as moving the routing logic to a `DynamicRouteValueTransformer` and etc...
+
+These enhancements led to some breaking changes as listed below that should be taken care of:
+
+* Page routing has been moved to **DynamicRouteValueTransformer**. If you use `{**slug}` pattern in your routing, it might conflict with new CMS Kit routing.
+* `PageConsts.UrlPrefix` has been removed, instead, the default prefix is *pages* for now. Still `/pages/{slug}` route works for backward compatibility alongside with `/{slug}` route.
+
+* **Endpoints changed:**
+ * `api/cms-kit-public/pages/{slug}` endpoint is changed to `api/cms-kit-public/pages/by-slug?slug={slug}`. Now multiple level of page URLs can be used and `/` characters will be transferred as URL Encoded in querysting to the HTTP API.
+ * `api/cms-kit-public/pages` changed to `api/cms-kit-public/pages/home`
+
+>_CmsKit Client Proxies are updated. If you don't send a **custom request** to this endpoint, **you don't need to take an action**_
+
+## Added Integration Postfix for Auto Controllers
+
+With this version on, the `Integration` suffix from controller names while generating [auto controllers](../API/Auto-API-Controllers.md) are not going to be removed, to differ the integration services from application services in the OpenAPI specification:
+
+
+
+> This should not affect most of the applications since you normally do not depend on the controller names in the client side.
+
+See https://github.com/abpframework/abp/issues/17625 for more information (how to preserve the existing behaviour, etc...).
+
+## Revised the reCaptcha Generator for CMS Kit's Comment Feature
+
+In this version, we have made improvements on the [CMS Kit's Comment Feature](../Modules/Cms-Kit/Comments.md) and revised the reCaptcha generation process, and made a performance improvement.
+
+This introduced some breaking changes that you should aware of:
+
+* Lifetime of the `SimpleMathsCaptchaGenerator` changed from singleton to transient,
+* Changed method signatures for `SimpleMathsCaptchaGenerator` class. (all of its methods are now async)
+
+If you haven't override the comment view component, then you don't need to make any changes, however if you have overriden the component and used the `SimpleMathsCaptchaGenerator` class, then you should make the required changes as described.
+
+## Disabled Logging for `HEAD` HTTP Methods
+
+HTTP GET requests should not make any change in the database normally and audit log system of ABP Framework doesn't save audit log objects for GET requests by default. You can configure the `AbpAuditingOptions` and set the `IsEnabledForGetRequests` to **true** if you want to record _GET_ requests as described in [the documentation](../Audit-Logging.md).
+
+Prior to this version, only the _GET_ requests were not saved as audit logs. From this version on, also the _HEAD_ requests will not be saved as audit logs, if the `IsEnabledForGetRequests` explicitly set as **true**.
+
+You don't need to make any changes related to that, however it's important to know this change.
+
+## Obsolete the `AbpAspNetCoreIntegratedTestBase` Class
+
+In this version, `AbpAspNetCoreAsyncIntegratedTestBase` class has been set as `Obsolete` and it's recommended to use `AbpWebApplicationFactoryIntegratedTest` instead.
+
+## Use NoTracking for Readonly Repositories for EF Core
+
+In this version, ABP Framework provides read-only [repository](Repositories.md) interfaces (`IReadOnlyRepository<...>` or `IReadOnlyBasicRepository<...>`) to explicitly indicate that your purpose is to query data, but not change it. If so, you can inject these interfaces into your services.
+
+Entity Framework Core read-only repository implementation uses [EF Core's No-Tracking feature](https://learn.microsoft.com/en-us/ef/core/querying/tracking#no-tracking-queries). That means the entities returned from the repository will not be tracked by the EF Core [change tracker](https://learn.microsoft.com/en-us/ef/core/change-tracking/), because it is expected that you won't update entities queried from a read-only repository.
+
+> This behavior works only if the repository object is injected with one of the read-only repository interfaces (`IReadOnlyRepository<...>` or `IReadOnlyBasicRepository<...>`). It won't work if you have injected a standard repository (e.g. `IRepository<...>`) then casted it to a read-only repository interface.
+
+> See the issue for more information: https://github.com/abpframework/abp/pull/17421
+
+## Use `IAbpDaprClientFactory` to Obtain `DaprClient`
+
+From this version on, instead of injecting the `DaprClient` directly, using the `IAbpDaprClientFactory.CreateAsync` method to create `DaprClient` or `HttpClient` objects to perform operations on Dapr is recommended.
+
+The documentation is already updated according to this suggestion and can be found at https://docs.abp.io/en/abp/8.0/Dapr/Index. So, if you want to learn more you can check the documentation or see the PR: https://github.com/abpframework/abp/pull/18117.
+
+## Angular UI
+
+# Guards
+
+From Angular Documentation;
+
+> Class-based **`Route`** guards are deprecated in favor of functional guards.
+
+- Angular has been using functional guards since version 14. According to this situation we have moved our guards to functional guards.
+
+We have modified our modules to adaptate functional guards.
+
+```diff
+- import {AuthGuard, PermissionGuard} from '@abp/ng.core';
++ import {authGuard, permissionGuard} from '@abp/ng.core';
+
+- canActivate: mapToCanActivate([AuthGuard, PermissionGuard])
++ canActivate: [authGuard, permissionGuard]
+```
+
+You can still use class based guards but we recommend it to use functional guards like us :)
+
+## Upgraded NuGet Dependencies
+
+You can see the following list of NuGet libraries that have been upgraded with .NET 8.0 upgrade, if you are using one of these packages explicitly, you may consider upgrading them in your solution:
+
+| Package | Old Version | New Version |
+| ------------------- | ----------- | ----------- |
+| aliyun-net-sdk-sts | 3.1.0 | 3.1.2 |
+| AsyncKeyedLock | 6.2.1 | 6.2.2 |
+| Autofac | 7.0.0 | 7.1.0 |
+| Autofac.Extras.DynamicProxy | 6.0.1 | 7.1.0 |
+| AutoMapper | 12.0.0 | 12.0.1 |
+| AWSSDK.S3 | 3.7.9.2 | 3.7.300.2 |
+| AWSSDK.SecurityToken | 3.7.1.151 | 3.7.300.2 |
+| Azure.Messaging.ServiceBus | 7.8.1 | 7.17.0 |
+| Azure.Storage.Blobs | 12.15.0 | 12.19.1 |
+| Blazorise | 1.3.1 | 1.3.2 |
+| Blazorise.Bootstrap5 | 1.3.1 | 1.3.2 |
+| Blazorise.Icons.FontAwesome | 1.3.1 | 1.3.2 |
+| Blazorise.Components | 1.3.1 | 1.3.2 |
+| Blazorise.DataGrid | 1.3.1 | 1.3.2 |
+| Blazorise.Snackbar | 1.3.1 | 1.3.2 |
+| Confluent.Kafka | 1.8.2 | 2.3.0 |
+| Dapper | 2.0.123 | 2.1.21 |
+| Dapr.AspNetCore | 1.9.0 | 1.12.0 |
+| Dapr.Client | 1.9.0 | 1.12.0 |
+| Devart.Data.Oracle.EFCore | 10.1.134.7 | 10.1.151.7 |
+| DistributedLock.Core | 1.0.4 | 1.0.5 |
+| DistributedLock.Redis | 1.0.1 | 1.0.2 |
+| EphemeralMongo.Core | 1.1.0 | 1.1.3 |
+| EphemeralMongo6.runtime.linux-x64 | 1.1.0 | 1.1.3 |
+| EphemeralMongo6.runtime.osx-x64 | 1.1.0 | 1.1.3 |
+| EphemeralMongo6.runtime.win-x64 | 1.1.0 | 1.1.3 |
+| FluentValidation | 11.0.1 | 11.8.0 |
+| Hangfire.AspNetCore | 1.8.2 | 1.8.6 |
+| Hangfire.SqlServer | 1.8.2 | 1.8.6 |
+| HtmlSanitizer | 5.0.331 | 8.0.746 |
+| HtmlAgilityPack | 1.11.42 | 1.11.54 |
+| IdentityModel | 6.0.0 | 6.2.0 |
+| IdentityServer4.AspNetIdentity | 4.1.1 | 4.1.2 |
+| JetBrains.Annotations | 2022.1.0 | 2023.3.0 |
+| LibGit2Sharp | 0.26.2 | 0.28.0 |
+| Magick.NET-Q16-AnyCPU | 13.2.0 | 13.4.0 |
+| MailKit | 3.2.0 | 4.3.0 |
+| Markdig.Signed | 0.26.0 | 0.33.0 |
+| Microsoft.AspNetCore.Authentication.JwtBearer | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Authentication.OpenIdConnect | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Authorization | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.Authorization | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.Web | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.WebAssembly | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.WebAssembly.Authentication | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.WebAssembly.DevServer | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Components.WebAssembly.Server | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.DataProtection.StackExchangeRedis | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Mvc.NewtonsoftJson | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.Mvc.Versioning | 5.0.0 | 5.1.0 |
+| Microsoft.AspNetCore.Razor.Language | 6.0.8 | 6.0.25 |
+| Microsoft.AspNetCore.TestHost | 7.0.10 | 8.0.0 |
+| Microsoft.AspNetCore.WebUtilities | 2.2.0 | 8.0.0 |
+| Microsoft.Bcl.AsyncInterfaces | 7.0.0 | 8.0.0 |
+| Microsoft.CodeAnalysis.CSharp | 4.2.0 | 4.5.0 |
+| Microsoft.Data.Sqlite | 7.0.0 | 8.0.0 |
+| Microsoft.EntityFrameworkCore | 7.0.10 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.Design | 7.0.0 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.InMemory | 7.0.10 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.Proxies | 7.0.10 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.Relational | 7.0.10 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.Sqlite | 7.0.10 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.SqlServer | 7.0.0 | 8.0.0 |
+| Microsoft.EntityFrameworkCore.Tools | 7.0.1 | 8.0.0 |
+| Microsoft.Extensions.Caching.Memory | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Caching.StackExchangeRedis | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Configuration.Binder | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Configuration.CommandLine | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Configuration.EnvironmentVariables | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Configuration.UserSecrets | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.DependencyInjection | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.DependencyInjection.Abstractions | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.FileProviders.Composite | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.FileProviders.Embedded | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.FileProviders.Physical | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.FileSystemGlobbing | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Hosting | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Hosting.Abstractions | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Http | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Http.Polly| 7.0.10 | 8.0.0 |
+| Microsoft.Extensions.Identity.Core | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Localization | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Logging | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Logging.Console | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Options | 7.0.0 | 8.0.0 |
+| Microsoft.Extensions.Options.ConfigurationExtensions | 7.0.0 | 8.0.0 |
+| Microsoft.NET.Test.Sdk | 17.2.0 | 17.8.0 |
+| Microsoft.VisualStudio.Web.CodeGeneration.Design | 7.0.0 | 8.0.0 |
+| Minio | 4.0.6 | 6.0.1 |
+| MongoDB.Driver | 2.19.1 | 2.22.0 |
+| NEST | 7.14.1 | 7.17.5 |
+| Newtonsoft.Json | 13.0.1 | 13.0.3 |
+| NSubstitute | 4.3.0 | 5.1.0 |
+| NuGet.Versioning | 5.11.0 | 6.7.0 |
+| NUglify | 1.20.0 | 1.21.0 |
+| Npgsql.EntityFrameworkCore.PostgreSQL | 7.0.0 | 8.0.0-rc.2 |
+| NSubstitute.Analyzers.CSharp | 1.0.15 | 1.0.16 |
+| Octokit | 0.50.0 | 9.0.0 |
+| OpenIddict.Abstractions | 4.8.0 | 4.10.0 |
+| OpenIddict.Core | 4.8.0 | 4.10.0 |
+| OpenIddict.Server.AspNetCore | 4.8.0 | 4.10.0 |
+| OpenIddict.Validation.AspNetCore | 4.8.0 | 4.10.0 |
+| OpenIddict.Validation.ServerIntegration | 4.8.0 | 4.10.0 |
+| Oracle.EntityFrameworkCore | 7.21.8 | 7.21.12 |
+| Polly | 7.2.3 | 8.2.0 |
+| Pomelo.EntityFrameworkCore.MySql | 7.0.0 | 8.0.0-beta.1 |
+| Quartz | 3.4.0 | 3.7.0 |
+| Quartz.Extensions.DependencyInjection | 3.4.0 | 3.7.0 |
+| Quartz.Plugins.TimeZoneConverter | 3.4.0 | 3.7.0 |
+| Quartz.Serialization.Json | 3.3.3 | 3.7.0 |
+| RabbitMQ.Client | 6.3.0 | 6.6.0 |
+| Rebus | 6.6.5 | 7.2.1 |
+| Rebus.ServiceProvider | 7.0.0 | 9.1.0 |
+| Scriban | 5.4.4 | 5.9.0 |
+| Serilog | 2.11.0 | 3.1.1 |
+| Serilog.AspNetCore | 5.0.0 | 8.0.0 |
+| Serilog.Extensions.Hosting | 3.1.0 | 8.0.0 |
+| Serilog.Extensions.Logging | 3.1.0 | 8.0.0 |
+| Serilog.Sinks.Async | 1.4.0 | 1.5.0 |
+| Serilog.Sinks.Console | 3.1.1 | 5.0.0 |
+| Serilog.Sinks.File | 4.1.0 | 5.0.0 |
+| SharpZipLib | 1.3.3 | 1.4.2 |
+| Shouldly | 4.0.3 | 4.2.1 |
+| SixLabors.ImageSharp.Drawing | 2.0.0 | 2.0.1 |
+| Slugify.Core | 3.0.0 | 4.0.1 |
+| StackExchange.Redis | 2.6.122 | 2.7.4 |
+| Swashbuckle.AspNetCore | 6.2.1 | 6.5.0 |
+| System.Collections.Immutable | 7.0.0 | 8.0.0 |
+| System.Linq.Dynamic.Core | 1.3.3 | 1.3.5 |
+| System.Security.Permissions | 7.0.0 | 8.0.0 |
+| System.Text.Encoding.CodePages | 7.0.0 | 8.0.0 |
+| System.Text.Encodings.Web | 7.0.0 | 8.0.0 |
+| System.Text.Json | 7.0.0 | 8.0.0 |
+| TimeZoneConverter | 5.0.0 | 6.1.0 |
+| xunit | 2.4.1 | 2.6.1 |
+| xunit.extensibility.execution | 2.4.1 | 2.6.1 |
+| xunit.runner.visualstudio | 2.4.5 | 2.5.3 |
diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md
index 88a2087ba0..e7dfa97f86 100644
--- a/docs/en/Migration-Guides/Index.md
+++ b/docs/en/Migration-Guides/Index.md
@@ -2,6 +2,7 @@
The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../Upgrading.md).
+- [7.x to 8.0](Abp-8_0.md)
- [7.3 to 7.4](Abp-7_4.md)
- [7.2 to 7.3](Abp-7_3.md)
- [7.1 to 7.2](Abp-7_2.md)
diff --git a/docs/en/Migration-Guides/images/integration-postfix-not-removed.png b/docs/en/Migration-Guides/images/integration-postfix-not-removed.png
new file mode 100644
index 0000000000..183a7a57c2
Binary files /dev/null and b/docs/en/Migration-Guides/images/integration-postfix-not-removed.png differ
diff --git a/docs/en/Modules/Cms-Kit/Blogging.md b/docs/en/Modules/Cms-Kit/Blogging.md
index d45598be52..eb6619a4bc 100644
--- a/docs/en/Modules/Cms-Kit/Blogging.md
+++ b/docs/en/Modules/Cms-Kit/Blogging.md
@@ -29,7 +29,16 @@ A screenshot from the new blog creation modal:

-**Slug** is the URL part of the blog. For this example, the root URL of the blog becomes *https://your-domain.com/blogs/technical-blog/*.
+**Slug** is the URL part of the blog. For this example, the root URL of the blog becomes `your-domain.com/blogs/technical-blog/`.
+
+- You can change the default slug by using `CmsBlogsWebConsts.BlogRoutePrefix` constant. For example, if you set it to `foo`, the root URL of the blog becomes `your-domain.com/foo/technical-blog/`.
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ CmsBlogsWebConsts.BlogsRoutePrefix = "foo";
+ }
+ ```
#### Blog Features
diff --git a/docs/en/Modules/Cms-Kit/Comments.md b/docs/en/Modules/Cms-Kit/Comments.md
index cc8d01249b..ddd39fc675 100644
--- a/docs/en/Modules/Cms-Kit/Comments.md
+++ b/docs/en/Modules/Cms-Kit/Comments.md
@@ -53,6 +53,7 @@ The comment system provides a commenting [widget](../../UI/AspNetCore/Widgets.md
{
entityType = "Product",
entityId = "...",
+ isReadOnly = false,
referralLinks = new [] {"nofollow"}
})
```
diff --git a/docs/en/Modules/Cms-Kit/Ratings.md b/docs/en/Modules/Cms-Kit/Ratings.md
index db58602c15..e6a2ba97fd 100644
--- a/docs/en/Modules/Cms-Kit/Ratings.md
+++ b/docs/en/Modules/Cms-Kit/Ratings.md
@@ -41,7 +41,8 @@ The ratings system provides a rating widget to allow users send ratings to resou
@await Component.InvokeAsync(typeof(RatingViewComponent), new
{
entityType = "Product",
- entityId = "entityId"
+ entityId = "entityId",
+ isReadOnly = false
})
```
diff --git a/docs/en/Object-To-Object-Mapping.md b/docs/en/Object-To-Object-Mapping.md
index c12b260921..40efdd7ee6 100644
--- a/docs/en/Object-To-Object-Mapping.md
+++ b/docs/en/Object-To-Object-Mapping.md
@@ -320,9 +320,22 @@ public class MyCustomUserMapper : IObjectMapper, ITransientDepend
}
````
-ABP automatically discovers and registers the `MyCustomUserMapper` and it is automatically used whenever you use the `IObjectMapper` to map `User` to `UserDto`.
-
-A single class may implement more than one `IObjectMapper` each for a different object pairs.
+ABP automatically discovers and registers the `MyCustomUserMapper` and it is automatically used whenever you use the `IObjectMapper` to map `User` to `UserDto`. A single class may implement more than one `IObjectMapper` each for a different object pairs.
> This approach is powerful since `MyCustomUserMapper` can inject any other service and use in the `Map` methods.
+Once you implement `IObjectMapper`, ABP can automatically convert a collection of `User` objects to a collection of `UserDto` objects. The following generic collection types are supported:
+
+* `IEnumerable`
+* `ICollection`
+* `Collection`
+* `IList`
+* `List`
+* `T[]` (array)
+
+**Example:**
+
+````csharp
+var users = await _userRepository.GetListAsync(); // returns List
+var dtos = ObjectMapper.Map, List>(users); // creates List
+````
diff --git a/docs/en/Repositories.md b/docs/en/Repositories.md
index 95f908d004..03fb27ab50 100644
--- a/docs/en/Repositories.md
+++ b/docs/en/Repositories.md
@@ -176,6 +176,77 @@ Some features (like soft-delete, multi-tenancy and audit logging) won't work, so
The `EnsureExistsAsync` extension method accepts entity id or entities query expression to ensure entities exist, otherwise, it will throw `EntityNotFoundException`.
+### Enabling / Disabling the Change Tracking
+
+ABP provides repository extension methods and attributes those can be used to control the change tracking behavior for queried entities in the underlying database provider.
+
+Disabling change tracking can gain performance if you query many entities from the database for read-only purposes. Querying single or a few entities won't make much performance difference, but you are free to use it whenever you like.
+
+> If the underlying database provider doesn't support change tracking, then this system won't have any effect. [Entity Framework Core](Entity-Framework-Core.md) supports change tracking, for example, while the [MongoDB](MongoDB.md) provider doesn't support it.
+
+#### Repository Extension Methods for Change Tracking
+
+Change tracking is enabled unless you explicitly disable it.
+
+**Example: Using the `DisableTracking` extension method**
+
+````csharp
+public class MyDemoService : ApplicationService
+{
+ private readonly IRepository _personRepository;
+
+ public MyDemoService(IRepository personRepository)
+ {
+ _personRepository = personRepository;
+ }
+
+ public async Task DoItAsync()
+ {
+ // Change tracking is enabled in that point (by default)
+
+ using (_personRepository.DisableTracking())
+ {
+ // Change tracking is disabled in that point
+ var list = await _personRepository.GetPagedListAsync(0, 100, "Name ASC");
+ }
+
+ // Change tracking is enabled in that point (by default)
+ }
+}
+````
+
+> `DisableTracking` extension method returns a `IDisposable` object, so you can safely **restore** the change tracking behavior to the **previous state** one the `using` block ends. Basically, `DisableTracking` method ensures that the change tracking is disabled inside the `using` block, but doesn't affect outside of the `using` block. That means, if change tracking was already disabled, `DisableTracking` and the disposable return value do nothing.
+
+`EnableTracking()` method works exactly opposite to the `DisableTracking()` method. You typically won't use it (because the change tracking is already enabled by default), but it is there in case of you need that.
+
+#### Attributes for Change Tracking
+
+You typically use the `DisableTracking()` method for the application service methods those only returns data, but doesn't make any change on entities. For such cases, you can use the `DisableEntityChangeTracking` attribute on your method/class as a shortcut to disable the change tracking for whole method body.
+
+**Example: Using the `DisableEntityChangeTracking` attribute on a method**
+
+````csharp
+[DisableEntityChangeTracking]
+public virtual async Task> GetListAsync()
+{
+ /* We disabled the change tracking in this method
+ because we won't change the people objects */
+ var people = await _personRepository.GetListAsync();
+ return ObjectMapper.Map, List(people);
+}
+````
+
+`EnableEntityChangeTracking` can be used for the opposite purpose, and it ensures that the change tracking is enabled for a given method. Since the change tracking is enabled by default, `EnableEntityChangeTracking` may be needed only if you know that your method is called from a context that disables the change tracking.
+
+`DisableEntityChangeTracking` and `EnableEntityChangeTracking` attributes can be used on a **method** or on a **class** (which affects all of the class methods).
+
+ABP uses dynamic proxying to make these attributes working. There are some rules here:
+
+* If you are **not injecting** the service over an interface (like `IPersonAppService`), then the methods of the service must be `virtual`. Otherwise, [dynamic proxy / interception](Dynamic-Proxying-Interceptors.md) system can not work.
+* Only `async` methods (methods returning a `Task` or `Task`) are intercepted.
+
+> Change tracking behavior doesn't affect tracking entity objects returned from `InsertAsync` and `UpdateAsync` methods. The objects returned from these methods are always tracked (if the underlying provider has the change tracking feature) and any change you made to these objects are saved into the database.
+
## Other Generic Repository Types
Standard `IRepository` interface exposes the standard `IQueryable` and you can freely query using the standard LINQ methods. This is fine for most of the applications. However, some ORM providers or database systems may not support standard `IQueryable` interface. If you want to use such providers, you can't rely on the `IQueryable`.
@@ -205,8 +276,6 @@ Methods:
- `WithDetails()` 1 overload
- `WithDetailsAsync()` 1 overload
-
-
Where as the `IReadOnlyBasicRepository` provides the following methods:
- `GetCountAsync()`
@@ -217,6 +286,12 @@ They can all be seen as below:

+#### Read Only Repositories behavior in Entity Framework Core
+
+Entity Framework Core read-only repository implementation uses [EF Core's No-Tracking feature](https://learn.microsoft.com/en-us/ef/core/querying/tracking#no-tracking-queries). That means the entities returned from the repository will not be tracked by the EF Core [change tracker](https://learn.microsoft.com/en-us/ef/core/change-tracking/), because it is expected that you won't update entities queried from a read-only repository. If you need to track the entities, you can still use the [AsTracking()](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.entityframeworkqueryableextensions.astracking) extension method on the LINQ expression, or `EnableTracking()` extension method on the repository object (See *Enabling / Disabling the Change Tracking* section in this document).
+
+> This behavior works only if the repository object is injected with one of the read-only repository interfaces (`IReadOnlyRepository<...>` or `IReadOnlyBasicRepository<...>`). It won't work if you have injected a standard repository (e.g. `IRepository<...>`) then casted it to a read-only repository interface.
+
### Generic Repository without a Primary Key
If your entity does not have an Id primary key (it may have a composite primary key for instance) then you cannot use the `IRepository` (or basic/readonly versions) defined above. In that case, you can inject and use `IRepository` for your entity.
diff --git a/docs/en/Startup-Templates/Application.md b/docs/en/Startup-Templates/Application.md
index 0c5e9c4c38..fdb7569ca0 100644
--- a/docs/en/Startup-Templates/Application.md
+++ b/docs/en/Startup-Templates/Application.md
@@ -316,7 +316,7 @@ You should add `routes` property in the `data` object to add a link on the menu
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule),
- canActivate: [AuthGuard, PermissionGuard],
+ canActivate: [authGuard, permissionGuard],
data: {
routes: {
name: 'ProjectName::Menu:Dashboard',
@@ -328,7 +328,7 @@ You should add `routes` property in the `data` object to add a link on the menu
}
```
In the above example;
-* If the user is not logged in, AuthGuard blocks access and redirects to the login page.
+* If the user is not logged in, authGuard blocks access and redirects to the login page.
* PermissionGuard checks the user's permission with the `requiredPolicy` property of the `routes` object. If the user is not authorized to access the page, the 403 page appears.
* The `name` property of `routes` is the menu link label. A localization key can be defined.
* The `iconClass` property of the `routes` object is the menu link icon class.
diff --git a/docs/en/Timing.md b/docs/en/Timing.md
index fce17de4cf..9b3eb0cca9 100644
--- a/docs/en/Timing.md
+++ b/docs/en/Timing.md
@@ -102,7 +102,7 @@ This section covers the ABP Framework infrastructure related to managing time zo
### TimeZone Setting
-ABP Framework defines **a setting**, named `Abp.Timing.Timezone`, that can be used to set and get the time zone for a user, [tenant](Multi-Tenancy.md) or globally for the application. The default value is `UTC`.
+ABP Framework defines **a setting**, named `Abp.Timing.TimeZone`, that can be used to set and get the time zone for a user, [tenant](Multi-Tenancy.md) or globally for the application. The default value is `UTC`.
See the [setting documentation](Settings.md) to learn more about the setting system.
diff --git a/docs/en/Tutorials/Part-5.md b/docs/en/Tutorials/Part-5.md
index f33a41f392..f306b7f4a2 100644
--- a/docs/en/Tutorials/Part-5.md
+++ b/docs/en/Tutorials/Part-5.md
@@ -323,11 +323,11 @@ Open the `/src/app/book/book-routing.module.ts` and replace with the following c
````js
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { AuthGuard, PermissionGuard } from '@abp/ng.core';
+import { authGuard, permissionGuard } from '@abp/ng.core';
import { BookComponent } from './book.component';
const routes: Routes = [
- { path: '', component: BookComponent, canActivate: [AuthGuard, PermissionGuard] },
+ { path: '', component: BookComponent, canActivate: [authGuard, permissionGuard] },
];
@NgModule({
@@ -337,8 +337,8 @@ const routes: Routes = [
export class BookRoutingModule {}
````
-* Imported `AuthGuard` and `PermissionGuard` from the `@abp/ng.core`.
-* Added `canActivate: [AuthGuard, PermissionGuard]` to the route definition.
+* Imported `authGuard` and `permissionGuard` from the `@abp/ng.core`.
+* Added `canActivate: [authGuard, permissionGuard]` to the route definition.
Open the `/src/app/route.provider.ts` and add `requiredPolicy: 'BookStore.Books'` to the `/books` route. The `/books` route block should be following:
diff --git a/docs/en/UI/Angular/Abp-Window-Service.md b/docs/en/UI/Angular/Abp-Window-Service.md
new file mode 100644
index 0000000000..bc060f79b5
--- /dev/null
+++ b/docs/en/UI/Angular/Abp-Window-Service.md
@@ -0,0 +1,41 @@
+# Abp Window Service
+
+
+## Download Blob as File
+AbpWindowService is an Angular service designed to provide utility methods related to window operations. The service has a `downloadBlob` function, which is used for downloading blobs as files within the context of a web application.
+
+### Usage
+
+To make use of the `AbpWindowService` in your Angular application, follow the steps below:
+
+### Injection
+Firstly, ensure that the service is injected into the component or any other Angular entity where you wish to use it.
+
+```js
+import { AbpWindowService } from '@abp/ng.core';
+
+constructor(private abpWindowService: AbpWindowService) { }
+// or
+// private abpWindowService = inject(AbpWindowService)
+```
+
+### Downloading a Blob
+
+Once you have the service injected, you can use the downloadBlob method to initiate the download of blob data as a file. For instance:
+
+```js
+someMethod() {
+ const myBlob = new Blob(["Hello, World!"], { type: "text/plain" });
+ this.abpWindowService.downloadBlob(myBlob, "hello.txt");
+}
+```
+
+### Permissions & Considerations
+
+Ensure that you have appropriate permissions and user interactions before triggering a download. Since downloadBlob initiates a download programmatically, it's best to tie this action to direct user interactions, such as button clicks, to prevent unexpected behaviors or browser restrictions.
+
+
+### DOCUMENT Token in Service
+
+Angular, being a platform-agnostic framework, is designed to support not only browser-based applications but also other environments like server-side rendering (SSR) through Angular Universal. This design philosophy introduces challenges when accessing global browser-specific objects like window or document directly. To address this, Angular provides a DOCUMENT token that can be used to inject the document object into Angular entities like components and services.
+
diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/Caps-Lock-Directive.md
similarity index 100%
rename from docs/en/UI/Angular/CapsLock.directive.md
rename to docs/en/UI/Angular/Caps-Lock-Directive.md
diff --git a/docs/en/UI/Angular/Data-Table-Column-Extensions.md b/docs/en/UI/Angular/Data-Table-Column-Extensions.md
index 6f1367d934..7660ec5550 100644
--- a/docs/en/UI/Angular/Data-Table-Column-Extensions.md
+++ b/docs/en/UI/Angular/Data-Table-Column-Extensions.md
@@ -1,6 +1,5 @@
# Data Table Column (or Entity Prop) Extensions for Angular UI
-
## Introduction
Entity prop extension system allows you to add a new column to the data table for an entity or change/remove an already existing one. A "Name" column was added to the user management page below:
@@ -196,6 +195,14 @@ type PropCallback = (data?: PropData) => R;
type PropPredicate = (data?: PropData) => boolean;
```
+### ColumnPredicate
+
+`ColumnPredicate` is the type of the predicate function that can be passed to an `EntityProp` as `columnVisible` parameter. A column predicate gets a single parameter, the `GetInjected`, you can use the `GetInjected` parameter to reach injected `Service` or `Component`. The return type must be `boolean`. Here is a simplified representation:
+
+```js
+type ColumnPredicate = (getInjected: GetInjected) => boolean;
+```
+
### EntityPropOptions\
`EntityPropOptions` is the type that defines required and optional properties you have to pass in order to create an entity prop.
@@ -212,6 +219,7 @@ type EntityPropOptions = {
columnWidth?: number;
permission?: string;
visible?: PropPredicate;
+ columnVisible?: ColumnPredicate;
};
```
@@ -224,9 +232,12 @@ As you see, passing `type` and `name` is enough to create an entity prop. Here i
- **sortable** defines if the table is sortable based on this entity prop. Sort icons are shown based on it. (_default:_ `false`)
- **columnWidth** defines a minimum width for the column. Good for horizontal scroll. (_default:_ `undefined`)
- **permission** is the permission context which will be used to decide if a column for this entity prop should be displayed to the user or not. (_default:_ `undefined`)
-- **visible** is a predicate that will be used to decide if this entity prop should be displayed on the table or not. (_default:_ `() => true`)
+- **visible** is a predicate that will be used to decide if the cell content of this entity prop should be displayed on the table or not based on the data record. (_default:_ `() => true`)
+- **columnVisible** is a predicate that will be used to decide if the column of this entity prop should be displayed on the table or not. (_default:_ `() => true`)
> Important Note: Do not use record in visibility predicates. First of all, the table header checks it too and the record will be `undefined`. Second, if some cells are displayed and others are not, the table will be broken. Use the `valueResolver` and render an empty cell when you need to hide a specific cell.
+>
+> `visible` predicate only hide the cell content, not the column. Use `columnVisible` to hide the entire column.
You may find a full example below.
@@ -257,6 +268,10 @@ const options: EntityPropOptions = {
return store.selectSnapshot(selectSensitiveDataVisibility).toLowerCase() === 'true';
}
+ columnVisible: getInjected => {
+ const sessionStateService = getInjected(SessionStateService);
+ return !sessionStateService.getTenant()?.isAvailable; // hide this column when the tenant is available.
+ },
};
const prop = new EntityProp(options);
@@ -281,19 +296,19 @@ The items in the list will be displayed according to the linked list order, i.e.
```js
export function reorderUserContributors(
- propList: EntityPropList,
+ propList: EntityPropList
) {
// drop email node
const emailPropNode = propList.dropByValue(
'AbpIdentity::EmailAddress',
- (prop, text) => prop.text === text,
+ (prop, text) => prop.text === text
);
// add it back after phoneNumber
propList.addAfter(
emailPropNode.value,
'phoneNumber',
- (value, name) => value.name === name,
+ (value, name) => value.name === name
);
}
```
@@ -304,7 +319,7 @@ export function reorderUserContributors(
```js
export function isLockedOutPropContributor(
- propList: EntityPropList,
+ propList: EntityPropList
) {
// add isLockedOutProp as 2nd column
propList.add(isLockedOutProp).byIndex(1);
diff --git a/docs/en/UI/Angular/OAuth-Module.md b/docs/en/UI/Angular/OAuth-Module.md
index e7a62d1d2e..b747c5221d 100644
--- a/docs/en/UI/Angular/OAuth-Module.md
+++ b/docs/en/UI/Angular/OAuth-Module.md
@@ -6,7 +6,6 @@ If your app is version 7.0 or higher, you should include "AbpOAuthModule.forRoot
Those abstractions can be found in the @abp/ng-core packages.
- `AuthService` (the class that implements the IAuthService interface).
- `NAVIGATE_TO_MANAGE_PROFILE` Inject token.
-- `AuthGuard` (the class that implements the IAuthGuard interface).
- `ApiInterceptor` (the class that implements the IApiInterceptor interface).
Those base classes are overridden by the "AbpOAuthModule" for oAuth. There are also three functions provided with AbpOAuthModule.
diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md
index dd373d6274..63d919f599 100644
--- a/docs/en/UI/Angular/Permission-Management.md
+++ b/docs/en/UI/Angular/Permission-Management.md
@@ -54,20 +54,20 @@ As shown above you can remove elements from DOM with `abpPermission` structural
## Permission Guard
-You can use `PermissionGuard` if you want to control authenticated user's permission to access to the route during navigation.
+You can use `permissionGuard` if you want to control authenticated user's permission to access to the route during navigation.
* Import the PermissionGuard from @abp/ng.core.
-* Add `canActivate: [PermissionGuard]` to your route object.
+* Add `canActivate: [permissionGuard]` to your route object.
* Add `requiredPolicy` to the `data` property of your route in your routing module.
```js
-import { PermissionGuard } from '@abp/ng.core';
+import { permissionGuard } from '@abp/ng.core';
// ...
const routes: Routes = [
{
path: 'path',
component: YourComponent,
- canActivate: [PermissionGuard],
+ canActivate: [permissionGuard],
data: {
requiredPolicy: 'YourProjectName.YourComponent', // policy key for your component
},
diff --git a/docs/en/UI/AspNetCore/Bundling-Minification.md b/docs/en/UI/AspNetCore/Bundling-Minification.md
index dd2282c883..6164d00c7d 100644
--- a/docs/en/UI/AspNetCore/Bundling-Minification.md
+++ b/docs/en/UI/AspNetCore/Bundling-Minification.md
@@ -382,6 +382,83 @@ Configure(options =>
````
+### External/CDN file Support
+
+The bundling system automatically recognizes the external/CDN files and adds them to the page without any change.
+
+#### Using External/CDN files in `AbpBundlingOptions`
+
+````csharp
+Configure(options =>
+{
+ options.StyleBundles
+ .Add("MyStyleBundle", configuration =>
+ {
+ configuration
+ .AddFiles("/styles/my-style1.css")
+ .AddFiles("/styles/my-style2.css")
+ .AddFiles("https://cdn.abp.io/bootstrap.css")
+ .AddFiles("/styles/my-style3.css")
+ .AddFiles("/styles/my-style4.css");
+ });
+
+ options.ScriptBundles
+ .Add("MyScriptBundle", configuration =>
+ {
+ configuration
+ .AddFiles("/scripts/my-script1.js")
+ .AddFiles("/scripts/my-script2.js")
+ .AddFiles("https://cdn.abp.io/bootstrap.js")
+ .AddFiles("/scripts/my-script3.js")
+ .AddFiles("/scripts/my-script4.js");
+ });
+});
+````
+
+**Output HTML:**
+
+````html
+
+
+
+
+
+
+
+````
+
+#### Using External/CDN files in Tag Helpers.
+
+````html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+````
+
+**Output HTML:**
+
+````html
+
+
+
+
+
+
+
+````
+
## Themes
Themes uses the standard package contributors to add library resources to page layouts. Themes may also define some standard/global bundles, so any module can contribute to these standard/global bundles. See the [theming documentation](Theming.md) for more.
diff --git a/docs/en/UI/AspNetCore/Testing.md b/docs/en/UI/AspNetCore/Testing.md
index 2c880594d3..6efc967cb0 100644
--- a/docs/en/UI/AspNetCore/Testing.md
+++ b/docs/en/UI/AspNetCore/Testing.md
@@ -198,23 +198,10 @@ ABP Framework doesn't provide any infrastructure to test your JavaScript code. Y
> Volo.Abp.AspNetCore.TestBase package is already installed in the `.Web.Tests` project.
-This package provides the `AbpAspNetCoreIntegratedTestBase` as the fundamental base class to derive the test classes from. The `MyProjectWebTestBase` base class used above inherits from the `AbpAspNetCoreIntegratedTestBase`, so we indirectly inherited the `AbpAspNetCoreIntegratedTestBase`.
+This package provides the `AbpWebApplicationFactoryIntegratedTest` as the fundamental base class to derive the test classes from. It's inherited from the [WebApplicationFactory](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests) class provided by the ASP.NET Core.
-### Base Properties
-
-The `AbpAspNetCoreIntegratedTestBase` provides the following base properties those are used in the tests:
-
-* `Server`: A `TestServer` instance that hosts the web application in tests.
-* `Client`: An `HttpClient` instance that is configured to perform requests to the test server.
-* `ServiceProvider`: The service provider that you can resolve services in case of need.
-
-### Base Methods
-
-`AbpAspNetCoreIntegratedTestBase` provides the following methods that you can override if you need to customize the test server:
-
-* `ConfigureServices` can be overridden to register/replace services only for the derived test class.
-* `CreateHostBuilder` can be used to customize building the `IHostBuilder`.
+The `MyProjectWebTestBase` base class used above inherits from the `AbpWebApplicationFactoryIntegratedTest`, so we indirectly inherited the `AbpWebApplicationFactoryIntegratedTest`.
See Also
-
+* [Integration tests in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests)
* [Overall / Server Side Testing](../../Testing.md)
\ No newline at end of file
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index afdf89657c..23180bdb06 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -178,7 +178,13 @@
},
{
"text": "Authorization",
- "path": "Authorization.md"
+ "path": "Authorization.md",
+ "items": [
+ {
+ "text": "Dynamic Claims",
+ "path": "Dynamic-Claims.md"
+ }
+ ]
},
{
"text": "Caching",
@@ -1122,6 +1128,14 @@
"text": "Loading Directive",
"path": "UI/Angular/Loading-Directive.md"
},
+ {
+ "text": "Show Password Directive",
+ "path": "UI/Angular/Show-Password-Directive.md"
+ },
+ {
+ "text": "Caps Lock Directive",
+ "path": "UI/Angular/Caps-Lock-Directive.md"
+ },
{
"text": "Toast Overlay",
"path": "UI/Angular/Toaster-Service.md"
@@ -1153,6 +1167,10 @@
{
"text": "Content Security Strategy",
"path": "UI/Angular/Content-Security-Strategy.md"
+ },
+ {
+ "text":"Abp Window Service",
+ "path":"UI/Angular/Abp-Window-Service.md"
}
]
},
@@ -1359,6 +1377,10 @@
"text": "Deployment",
"path": "Deployment/Index.md",
"items": [
+ {
+ "text": "Configuring SSL certificate(HTTPS)",
+ "path": "Deployment/SSL.md"
+ },
{
"text": "Configuring OpenIddict",
"path": "Deployment/Configuring-OpenIddict.md"
diff --git a/docs/zh-Hans/Dapr/Index.md b/docs/zh-Hans/Dapr/Index.md
index 64a9451737..a5237cbb71 100644
--- a/docs/zh-Hans/Dapr/Index.md
+++ b/docs/zh-Hans/Dapr/Index.md
@@ -60,29 +60,6 @@ Configure(options =>
}
````
-### 注入DaprClient
-
-ABP 将 `DaprClient` 类注册到 [依赖注入](../Dependency-Injection.md) 系统中.因此,你可以在需要时注入并使用它:
-
-````csharp
-public class MyService : ITransientDependency
-{
- private readonly DaprClient _daprClient;
-
- public MyService(DaprClient daprClient)
- {
- _daprClient = daprClient;
- }
-
- public async Task DoItAsync()
- {
- // TODO: Use the injected _daprClient object
- }
-}
-````
-
-注入 `DaprClient` 是在应用程序代码中使用它的推荐方法.当你注入它时,将使用 `IAbpDaprClientFactory` 服务创建它,这会在下一节中将进行说明.
-
### IAbpDaprClientFactory
`IAbpDaprClientFactory` 可用于创建 `DaprClient` 或 `HttpClient` 对象来执行对 Dapr 的操作.它使用 `AbpDaprOptions`,因此你可以配置设置.
@@ -113,15 +90,14 @@ public class MyService : ITransientDependency
});
// Create an HttpClient object
- HttpClient httpClient = await _daprClientFactory
- .CreateHttpClientAsync("target-app-id");
+ HttpClient httpClient = await _daprClientFactory.CreateHttpClientAsync("target-app-id");
}
}
````
`CreateHttpClientAsync` 方法还获取可选的 `daprEndpoint` 和 `daprApiToken` 参数.
-> ABP使用`IAbpDaprClientFactory`创建Dapr客户端.你也可以在应用程序中使用Dapr API创建客户端对象.推荐使用`IAbpDaprClientFactory`,但不是必需的.
+> 你可以在应用程序中使用Dapr API创建客户端对象.推荐使用`IAbpDaprClientFactory`,但不是必需的.
## C# API 客户端代理集成
@@ -412,7 +388,7 @@ Configure(options =>
}
````
-一旦你设置了它,它就会在你注入`DaprClient`或使用`IAbpDaprClientFactory`时使用.如果你需要在应用程序中使用该值,你可以注入`IDaprApiTokenProvider`并使用其`GetDaprApiToken()`方法.
+一旦你设置了它,它就会在使用`IAbpDaprClientFactory`时使用.如果你需要在应用程序中使用该值,你可以注入`IDaprApiTokenProvider`并使用其`GetDaprApiToken()`方法.
### App API Token
diff --git a/docs/zh-Hans/Getting-Started-Running-Solution.md b/docs/zh-Hans/Getting-Started-Running-Solution.md
index 8ecd85ec58..f0a4942d64 100644
--- a/docs/zh-Hans/Getting-Started-Running-Solution.md
+++ b/docs/zh-Hans/Getting-Started-Running-Solution.md
@@ -21,7 +21,7 @@
````json
"ConnectionStrings": {
- "Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
+ "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
diff --git a/docs/zh-Hans/Startup-Templates/Application.md b/docs/zh-Hans/Startup-Templates/Application.md
index 91d7308226..d6733b8633 100644
--- a/docs/zh-Hans/Startup-Templates/Application.md
+++ b/docs/zh-Hans/Startup-Templates/Application.md
@@ -302,7 +302,7 @@ ABP 配置模块也已经导入到 `AppModule` 中, 以满足可延迟加载 ABP
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule),
- canActivate: [AuthGuard, PermissionGuard],
+ canActivate: [authGuard, permissionGuard],
data: {
routes: {
name: 'ProjectName::Menu:Dashboard',
@@ -315,7 +315,7 @@ ABP 配置模块也已经导入到 `AppModule` 中, 以满足可延迟加载 ABP
```
在上面的例子中;
* 如果用户没有登录, AuthGuard 会阻塞访问并重定向到登录页面.
-* PermissionGuard 使用 `rotues` 对象的 `requiredPolicy` 属性检查用户的权限. 如果用户未被授权访问该页, 则显示403页.
+* permissionGuard 使用 `rotues` 对象的 `requiredPolicy` 属性检查用户的权限. 如果用户未被授权访问该页, 则显示403页.
* `routes` 的 `name` 属性是菜单链接标签. 可以定义本地化 key.
* `routes` 对象的 `iconClass` 属性是菜单链接图标类.
* `routes` 对象的 `requiredPolicy` 属性是访问页面所需的策略 key.
diff --git a/docs/zh-Hans/Timing.md b/docs/zh-Hans/Timing.md
index 71ddbb9058..1d220a7aad 100644
--- a/docs/zh-Hans/Timing.md
+++ b/docs/zh-Hans/Timing.md
@@ -102,7 +102,7 @@ var normalizedDateTime = Clock.Normalize(dateTime)
### 时区设置
-ABP框架定义了一个名为 `Abp.Timing.Timezone` 的**设置**,可用于为应用程序的用户,[租户](Multi-Tenancy.md)或全局设置和获取时区. 默认值为 `UTC`.
+ABP框架定义了一个名为 `Abp.Timing.TimeZone` 的**设置**,可用于为应用程序的用户,[租户](Multi-Tenancy.md)或全局设置和获取时区. 默认值为 `UTC`.
参阅[设置系统]了解更多关于设置系统.
@@ -110,4 +110,4 @@ ABP框架定义了一个名为 `Abp.Timing.Timezone` 的**设置**,可用于为
`ITimezoneProvider` 是一个服务,可将[Windows时区ID](https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values)值简单转换为[Iana时区名称](https://www.iana.org/time-zones)值,反之亦然. 它还提供了获取这些时区列表与获取具有给定名称的 `TimeZoneInfo` 的方法.
-它已使用[TimeZoneConverter](https://github.com/mj1856/TimeZoneConverter)库实现.
\ No newline at end of file
+它已使用[TimeZoneConverter](https://github.com/mj1856/TimeZoneConverter)库实现.
diff --git a/docs/zh-Hans/Tutorials/Part-5.md b/docs/zh-Hans/Tutorials/Part-5.md
index 5bdad55c1c..ec308f3ee7 100644
--- a/docs/zh-Hans/Tutorials/Part-5.md
+++ b/docs/zh-Hans/Tutorials/Part-5.md
@@ -389,11 +389,11 @@ UI的第一步是防止未认证用户看见"图书"菜单项并进入图书管
````js
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { AuthGuard, PermissionGuard } from '@abp/ng.core';
+import { authGuard, permissionGuard } from '@abp/ng.core';
import { BookComponent } from './book.component';
const routes: Routes = [
- { path: '', component: BookComponent, canActivate: [AuthGuard, PermissionGuard] },
+ { path: '', component: BookComponent, canActivate: [authGuard, permissionGuard] },
];
@NgModule({
@@ -403,8 +403,8 @@ const routes: Routes = [
export class BookRoutingModule {}
````
-* 从 `@abp/ng.core` 引入 `AuthGuard` 和 `PermissionGuard`.
-* 在路由定义中添加 `canActivate: [AuthGuard, PermissionGuard]`.
+* 从 `@abp/ng.core` 引入 `authGuard` 和 `permissionGuard`.
+* 在路由定义中添加 `canActivate: [authGuard, permissionGuard]`.
打开 `/src/app/route.provider.ts`, 在 `/books` 路由中添加 `requiredPolicy: 'BookStore.Books'`. `/books` 路由应该如以下配置:
diff --git a/docs/zh-Hans/UI/Angular/Permission-Management.md b/docs/zh-Hans/UI/Angular/Permission-Management.md
index 08496f03fe..05e3dacbf1 100644
--- a/docs/zh-Hans/UI/Angular/Permission-Management.md
+++ b/docs/zh-Hans/UI/Angular/Permission-Management.md
@@ -53,20 +53,20 @@ export class YourComponent {
## 权限守卫
-如果你想要在导航过程中控制经过身份验证的用户对路由的访问权限,可以使用 `PermissionGuard`.
+如果你想要在导航过程中控制经过身份验证的用户对路由的访问权限,可以使用 `permissionGuard`.
-* 从@abp/ng.core导入PermissionGuard.
-* 添加 `canActivate: [PermissionGuard]` 到你的路由对象.
+* 从@abp/ng.core导入permissionGuard.
+* 添加 `canActivate: [permissionGuard]` 到你的路由对象.
* 添加 `requiredPolicy` 到路由模块路由的 `data` 属性.
```js
-import { PermissionGuard } from '@abp/ng.core';
+import { permissionGuard } from '@abp/ng.core';
// ...
const routes: Routes = [
{
path: 'path',
component: YourComponent,
- canActivate: [PermissionGuard],
+ canActivate: [permissionGuard],
data: {
requiredPolicy: 'YourProjectName.YourComponent', // policy key for your component
},
diff --git a/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md b/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md
index 338afe8967..72bee2eedb 100644
--- a/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md
+++ b/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md
@@ -353,6 +353,83 @@ services.Configure(options =>
});
````
+### 外部/CDN文件支持
+
+捆绑系统会自动识别外部/CDN文件,并将其添加到页面中,无需进行任何更改。
+
+#### 在`AbpBundlingOptions`中添加外部/CDN文件
+
+````csharp
+Configure(options =>
+{
+ options.StyleBundles
+ .Add("MyStyleBundle", configuration =>
+ {
+ configuration
+ .AddFiles("/styles/my-style1.css")
+ .AddFiles("/styles/my-style2.css")
+ .AddFiles("https://cdn.abp.io/bootstrap.css")
+ .AddFiles("/styles/my-style3.css")
+ .AddFiles("/styles/my-style4.css");
+ });
+
+ options.ScriptBundles
+ .Add("MyScriptBundle", configuration =>
+ {
+ configuration
+ .AddFiles("/scripts/my-script1.js")
+ .AddFiles("/scripts/my-script2.js")
+ .AddFiles("https://cdn.abp.io/bootstrap.js")
+ .AddFiles("/scripts/my-script3.js")
+ .AddFiles("/scripts/my-script4.js");
+ });
+});
+````
+
+**输出HTMl:**
+
+````html
+
+
+
+
+
+
+
+````
+
+#### 在TagHelpers中添加外部/CDN文件
+
+````html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+````
+
+**输出HTMl:**
+
+````html
+
+
+
+
+
+
+
+````
+
### 主题
主题使用标准包贡献者将库资源添加到页面布局. 主题还可以定义一些标准/全局包, 因此任何模块都可以为这些标准/全局包做出贡献. 有关更多信息, 请参阅[主题文档](Theming.md).
diff --git a/docs/zh-Hans/UI/AspNetCore/Testing.md b/docs/zh-Hans/UI/AspNetCore/Testing.md
index e5b09353fb..1dfdbe367e 100644
--- a/docs/zh-Hans/UI/AspNetCore/Testing.md
+++ b/docs/zh-Hans/UI/AspNetCore/Testing.md
@@ -198,23 +198,10 @@ ABP框架不提供任何基础设施来测试JavaScript代码. 你可以使用
> Volo.Abp.AspNetCore.TestBase 已经安装在 `.Web.Tests` 项目中.
-此包提供的`AbpAspNetCoreIntegratedTestBase`作为派生测试类的基类. 上面使用的`MyProjectWebTestBase`继承自`AbpAspNetCoreIntegratedTestBase`, 因此我们间接继承了`AbpAspNetCoreIntegratedTestBase`.
-
-### 基本属性
-
-`AbpAspNetCoreIntegratedTestBase` 提供了测试中使用的以下基本属性:
-
-* `Server`: 在测试中托管web应用程序的`TestServer`实例.
-* `Client`: 为执行对测试服务器的请求配置`HttpClient`实例.
-* `ServiceProvider`: 可以在你需要时处理服务提供服务.
-
-### 基本方法
-
-`AbpAspNetCoreIntegratedTestBase` 提供了以下方法, 如果需要自定义测试服务器, 可以重写这些方法:
-
-* `ConfigureServices` 仅为派生测试类注册/替换服务时可以重写使用.
-* `CreateHostBuilder` 可用于自定义生成 `IHostBuilder`.
+此包提供的`AbpWebApplicationFactoryIntegratedTest`作为派生测试类的基类. 它继承自ASP.NET Core提供的[WebApplicationFactory](https://learn.microsoft.com/zh-cn/aspnet/core/test/integration-tests)类。
+上面使用的`MyProjectWebTestBase`继承自`AbpWebApplicationFactoryIntegratedTest`, 因此我们间接继承了`AbpWebApplicationFactoryIntegratedTest`.
另请参阅
+* [ASP.NET Core 中的集成测试](https://learn.microsoft.com/zh-cn/aspnet/core/test/integration-tests)
* [总览/服务器端测试](../../Testing.md)
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index cd003b7f07..42339a60ac 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -459,6 +459,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Imaging.AspNetCore
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Maui.Client", "src\Volo.Abp.Maui.Client\Volo.Abp.Maui.Client.csproj", "{F19A6E0C-F719-4ED9-A024-14E4B8D40883}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.SkiaSharp", "src\Volo.Abp.Imaging.SkiaSharp\Volo.Abp.Imaging.SkiaSharp.csproj", "{198683D0-7DC6-40F2-B81B-8E446E70A9DE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.SkiaSharp.Tests", "test\Volo.Abp.Imaging.SkiaSharp.Tests\Volo.Abp.Imaging.SkiaSharp.Tests.csproj", "{DFAF8763-D1D6-4EB4-B459-20E31007FE2F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1369,6 +1373,14 @@ Global
{F19A6E0C-F719-4ED9-A024-14E4B8D40883}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F19A6E0C-F719-4ED9-A024-14E4B8D40883}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F19A6E0C-F719-4ED9-A024-14E4B8D40883}.Release|Any CPU.Build.0 = Release|Any CPU
+ {198683D0-7DC6-40F2-B81B-8E446E70A9DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {198683D0-7DC6-40F2-B81B-8E446E70A9DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {198683D0-7DC6-40F2-B81B-8E446E70A9DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {198683D0-7DC6-40F2-B81B-8E446E70A9DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DFAF8763-D1D6-4EB4-B459-20E31007FE2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DFAF8763-D1D6-4EB4-B459-20E31007FE2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DFAF8763-D1D6-4EB4-B459-20E31007FE2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DFAF8763-D1D6-4EB4-B459-20E31007FE2F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1600,6 +1612,8 @@ Global
{62B2B8C9-8F24-4D31-894F-C1F0728D32AB} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{983B0136-384B-4439-B374-31111FFAA286} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{F19A6E0C-F719-4ED9-A024-14E4B8D40883} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {198683D0-7DC6-40F2-B81B-8E446E70A9DE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {DFAF8763-D1D6-4EB4-B459-20E31007FE2F} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
index 2924448609..b869a45a2e 100644
--- a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
+++ b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
@@ -4,7 +4,7 @@
- netstandard2.0;netstandard2.1;net7.0
+ netstandard2.0;netstandard2.1;net8.0enableNullableVolo.Abp.ApiVersioning.Abstractions
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
index 6deeaac7e3..a0f4b31158 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullableVolo.Abp.AspNetCore.Authentication.JwtBearer
@@ -21,7 +21,7 @@
-
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
index f8efe3c11c..b31876c3d4 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullableVolo.Abp.AspNetCore.Authentication.OAuth
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
index 9fa50a203f..12986e23a9 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullable
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj
index 3cd049965e..93497ad4be 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullable
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj
index ff80cd1fba..031ffd1ede 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullableVolo.Abp.AspNetCore.Components.MauiBlazor
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj
index 266831eba9..8fffb65f5e 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullabletrue
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
index ba542312d1..7852848e30 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
@@ -34,7 +34,7 @@ public static class CookieAuthenticationOptionsExtensions
var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
{
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority!.EnsureEndsWith('/') + "connect/introspect",
- ClientId = openIdConnectOptions.ClientId,
+ ClientId = openIdConnectOptions.ClientId!,
ClientSecret = openIdConnectOptions.ClientSecret,
Token = accessToken
});
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj
index a8cb372ddc..338a538402 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullabletrue
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj
index 1dd5b61131..03fa885d60 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullable
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj
index 7f89d1c254..f43a89e7cc 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullable
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs
index dc0a2182cb..16a0c26e6b 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs
@@ -14,12 +14,13 @@ public class AbpBlazorMessageLocalizerHelper
this.stringLocalizer = stringLocalizer;
}
- public string Localize(string message, IEnumerable? arguments)
+ public string Localize(string message, IEnumerable? arguments = null)
{
try
{
- return arguments?.Count() > 0
- ? stringLocalizer[message, LocalizeMessageArguments(arguments)?.ToArray()!]
+ var argumentsList = arguments?.ToList();
+ return argumentsList?.Count > 0
+ ? stringLocalizer[message, LocalizeMessageArguments(argumentsList)]
: stringLocalizer[message];
}
catch
@@ -28,7 +29,7 @@ public class AbpBlazorMessageLocalizerHelper
}
}
- private IEnumerable LocalizeMessageArguments(IEnumerable arguments)
+ private IEnumerable LocalizeMessageArguments(List arguments)
{
foreach (var argument in arguments)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs
index 74cbd37e29..8df1824e81 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs
@@ -1,9 +1,9 @@
using System.Security.Claims;
using System.Threading.Tasks;
-using JetBrains.Annotations;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Components.Web.Security;
@@ -12,16 +12,18 @@ public class AbpComponentsClaimsCache : IScopedDependency
public ClaimsPrincipal Principal { get; private set; } = default!;
private readonly AuthenticationStateProvider? _authenticationStateProvider;
+ private readonly IAbpClaimsPrincipalFactory _abpClaimsPrincipalFactory;
public AbpComponentsClaimsCache(
IClientScopeServiceProviderAccessor serviceProviderAccessor)
{
_authenticationStateProvider = serviceProviderAccessor.ServiceProvider.GetService();
+ _abpClaimsPrincipalFactory = serviceProviderAccessor.ServiceProvider.GetRequiredService();
if (_authenticationStateProvider != null)
{
_authenticationStateProvider.AuthenticationStateChanged += async (task) =>
{
- Principal = (await task).User;
+ Principal = await _abpClaimsPrincipalFactory.CreateDynamicAsync((await task).User);
};
}
}
@@ -32,6 +34,7 @@ public class AbpComponentsClaimsCache : IScopedDependency
{
var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync();
Principal = authenticationState.User;
+ await _abpClaimsPrincipalFactory.CreateDynamicAsync(Principal);
}
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj
index 06a5276ec0..395891fb82 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj
@@ -4,7 +4,7 @@
- net7.0
+ net8.0enableNullable
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/css/all.css b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/css/all.css
index 1ea1b1818d..27b1d0c2c7 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/css/all.css
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/css/all.css
@@ -1,5 +1,5 @@
/*!
- * Font Awesome Free 5.12.0 by @fontawesome - https://fontawesome.com
+ * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
-.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\f907"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\f913"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\f91a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\f91e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\f941"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\f949"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900}
\ No newline at end of file
+ .fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.eot b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.eot
index baf40576d2..cba6c6cce8 100644
Binary files a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.eot and b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.eot differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.svg b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.svg
index 843c1c785c..b9881a43b7 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.svg
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.svg
@@ -1,16 +1,12 @@
-
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.ttf b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.ttf
index 991632871b..8d75deddae 100644
Binary files a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.ttf and b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.ttf differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff
index f9e3bcd008..3375bef091 100644
Binary files a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff and b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff2 b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff2
index 51c07aef34..402f81c0bc 100644
Binary files a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff2 and b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-brands-400.woff2 differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.eot b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.eot
index 04e25cbaa3..a4e598936b 100644
Binary files a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.eot and b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.eot differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.svg b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.svg
index f1f7e6cb06..463af27c02 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.svg
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/wwwroot/libs/fontawesome/webfonts/fa-regular-400.svg
@@ -1,16 +1,12 @@
-