[
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\nx64/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Roslyn cache directories\n*.ide/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n#NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n#VS2015 local configuration files\n.vs/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding addin-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n## TODO: Comment the next line if you want to checkin your\n## web deploy settings but do note that will include unencrypted\n## passwords\n#*.pubxml\n\n# NuGet Packages Directory\npackages/*\n## TODO: If the tool you use requires repositories.config\n## uncomment the next line\n#!packages/repositories.config\n\n# Enable \"build/\" folder in the NuGet Packages folder since\n# NuGet packages use it for MSBuild targets.\n# This line needs to be after the ignore of the build folder\n# (and the packages folder if the line above has been uncommented)\n!packages/build/\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\nbower_packages/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# LightSwitch generated files\nGeneratedArtifacts/\n_Pvt_Extensions/\nModelManifest.xml\nGeoRoute/packages/*\nCardsReports/\nInstrReports/\n.vscode\n/GeoRoute/GR.Admin/grAdmin/FrontApp/dist/\nDemo.ClientSideApp/Properties/PublishProfiles/*.pubxml\nServiceDependencies\n"
  },
  {
    "path": "BlazorDateRangePicker/BlazorDateRangePicker.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Razor\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFrameworks>net6;net7;net8;net9;net10.0</TargetFrameworks>\r\n    <OutputType>Library</OutputType>\r\n    <GeneratePackageOnBuild>false</GeneratePackageOnBuild>\r\n    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>\r\n    <IsPackable>true</IsPackable>\r\n    <LangVersion>preview</LangVersion>\r\n    <RazorLangVersion>latest</RazorLangVersion>\r\n\r\n    <Version>6.2.0</Version>\r\n    <Authors>Sergey Zaikin</Authors>\r\n    <PackageId>BlazorDateRangePicker</PackageId>\r\n    <Title>Blazor Date Range Picker</Title>\r\n    <Description>A fully managed port of daterangepicker.js for Blazor</Description>\r\n    <PackageProjectUrl>https://github.com/jdtcn/BlazorDateRangePicker</PackageProjectUrl>\r\n    <RepositoryUrl>https://github.com/jdtcn/BlazorDateRangePicker</RepositoryUrl>\r\n    <PackageTags>blazor;daterangepicker;datepicker</PackageTags>\r\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <SupportedPlatform Include=\"browser\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup Condition=\"$(TargetFramework.StartsWith('net6'))\">\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"6.0.29\" />\r\n  </ItemGroup>\r\n  <ItemGroup Condition=\"$(TargetFramework.StartsWith('net7'))\">\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"7.0.0\" />\r\n  </ItemGroup>\r\n  <ItemGroup Condition=\"$(TargetFramework.StartsWith('net8'))\">\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"8.0.0\" />\r\n  </ItemGroup>\r\n  <ItemGroup Condition=\"$(TargetFramework.StartsWith('net9'))\">\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"9.0.0\" />\r\n  </ItemGroup>\r\n  <ItemGroup Condition=\"$(TargetFramework.StartsWith('net10.0'))\">\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"10.0.0-rc.1.25451.107\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\SourceGenerators\\SourceGenerators.csproj\"\r\n                      ReferenceOutputAssembly=\"false\"\r\n                      OutputItemType=\"Analyzer\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "BlazorDateRangePicker/Calendar.razor",
    "content": "﻿@*\n    * author: Sergey Zaikin zaikinsr@yandex.ru\n    * copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n    * license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*@\n\n<table class=\"table-condensed\">\n    <thead>\n        <tr>\n            @if (Picker.ShowWeekNumbers == true || Picker.ShowISOWeekNumbers == true)\n            {\n                <th></th>\n            }\n            <th class=\"@(PrevBtnVisible ? \"prev available\" : \"\")\" @onclick=\"@(_ => PreviousMonth(PrevBtnVisible))\"><span></span></th>\n            <th colspan=\"5\" class=\"month\">\n                @if (Picker.ShowDropdowns == true)\n                {\n                    var inMinYear = CurrentYear == MinYear;\n                    var inMaxYear = CurrentYear == MaxYear;\n                    <select class=\"monthselect\" @bind=\"@CurrentMonth\">\n                        @for (var m = 1; m < 13; m++)\n                        {\n                            var enabled = (!inMinYear || (m >= Picker.MinDate?.Month)) && (!inMaxYear || (m <= Picker.MaxDate?.Month)) && CurrentYear <= MaxYear;\n                            var selected = m == CurrentMonth;\n                            <option @key=\"m\" selected=\"@selected\" disabled=\"@(!enabled)\" value=\"@m\">\n                                @Picker.Culture.DateTimeFormat.GetMonthName(m)\n                            </option>\n                        }\n                    </select>\n\n                    <select class=\"yearselect\" @bind=\"CurrentYear\">\n                        @for (var y = MinYear; y <= MaxYear; y++)\n                        {\n                            <option @key=\"y\" value=\"@y\" selected=\"@(y == CurrentYear)\">@y</option>\n                        }\n                        @if(CurrentYear > MaxYear)\n                        {\n                            <option @key=\"CurrentYear\" value=\"@CurrentYear\" selected=\"true\">@CurrentYear</option>\n                        }\n                    </select>\n                }\n                else\n                {\n                    @Picker.Culture.DateTimeFormat.GetMonthName(CalendarData.Month.Month)<text>&nbsp;</text>@CalendarData.Month.Year\n                }\n            </th>\n            <th class=\"@(NextBtnVisible ? \"next available\" : \"\")\" @onclick=\"@(_ => NextMonth(NextBtnVisible))\"><span></span></th>\n\n        </tr>\n        <tr>\n\n            @if (Picker.ShowWeekNumbers == true || Picker.ShowISOWeekNumbers == true)\n            {\n                <th class=\"week\">@Picker.WeekAbbreviation</th>\n            }\n\n            @foreach (var dayOfWeekName in DayNames)\n            {\n                <th>@dayOfWeekName</th>\n            }\n\n        </tr>\n    </thead>\n    <tbody>\n        @foreach (var row in CalendarData.Calendar)\n        {\n            <tr>\n                @if (Picker.ShowWeekNumbers == true)\n                {\n                    <td class=\"week\">\n                        @GetWeekOfYear(row[0].Day.DateTime)\n                    </td>\n                }\n                else if (Picker.ShowISOWeekNumbers == true)\n                {\n                    <td class=\"week\">\n                        @GetIso8601WeekOfYear(row[0].Day.DateTime)\n                    </td>\n                }\n               \n                @foreach (var dt in row)\n                {\n                    if (dt.OutOfRange)\n                    {\n                        @if (Picker.DayTemplate != null)\n                        {\n                            @Picker.DayTemplate(dt)\n                        }\n                        else\n                        {\n                            <td class=\"disabled\">-</td>\n                        }\n                        continue;\n                    }\n\n                    if (dt.Hover == null) dt.Hover = () => OnMouseOverDate(dt.Day);\n                    if (dt.Click == null) dt.Click = () => ClickDate(dt);\n\n                    <td class=\"@(Picker.Loading ? \"disabled\" : dt.ClassNames)\" \n                        @onmouseover=\"@dt.Hover\" \n                        @onclick=\"@dt.Click\">\n                        @if (Picker.DayTemplate != null)\n                        {\n                            @Picker.DayTemplate(dt)\n                        }\n                        else\n                        {\n                            @dt.Day.Day\n                        }\n                    </td>\n                }\n            </tr>\n        }\n    </tbody>\n</table>\n"
  },
  {
    "path": "BlazorDateRangePicker/Calendar.razor.cs",
    "content": "﻿/**\r\n* @author: Sergey Zaikin zaikinsr@yandex.ru\r\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\r\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\r\n*/\r\n\r\nusing System;\r\nusing System.Linq;\r\nusing System.Globalization;\r\nusing System.Threading.Tasks;\r\nusing System.Collections.Generic;\r\nusing Microsoft.AspNetCore.Components;\r\n\r\nnamespace BlazorDateRangePicker\r\n{\r\n    public partial class Calendar : ComponentBase\r\n    {\r\n\r\n        [CascadingParameter] public DateRangePicker Picker { get; set; }\r\n        [Parameter] public CalendarType CalendarData { get; set; }\r\n        [Parameter] public List<string> CustomDayNames { get; set; }\r\n\r\n        [Parameter] public SideType? Side { get; set; }\r\n        [Parameter] public EventCallback<DateTimeOffset> OnMonthChanged { get; set; }\r\n        [Parameter] public EventCallback<DateTimeOffset> OnClickDate { get; set; }\r\n        [Parameter] public EventCallback<DateTimeOffset> OnHoverDate { get; set; }\r\n\r\n        private int MinYear => Picker.MinDate?.Year ?? 1950;\r\n        private int MaxYear => Picker.MaxDate?.Year ?? DateTime.Now.AddYears(50).Year;\r\n\r\n        private int CurrentMonth\r\n        {\r\n            get => CalendarData.Month.Month;\r\n            set => MonthSelected(value);\r\n        }\r\n\r\n        private int CurrentYear\r\n        {\r\n            get => CalendarData.Month.Year;\r\n            set => YearSelected(value);\r\n        }\r\n\r\n        private bool PrevBtnVisible =>\r\n            (!Picker.MinDate.HasValue || Picker.MinDate < CalendarData.FirstDay)\r\n            && CalendarData.FirstDay.Date > DateTime.MinValue.Date\r\n            && (Picker.LinkedCalendars != true || Side == SideType.Left);\r\n        private bool NextBtnVisible =>\r\n            (!Picker.MaxDate.HasValue || Picker.MaxDate > CalendarData.LastDay)\r\n            && CalendarData.LastDay.Date < DateTime.MaxValue.Date\r\n            && (Picker.LinkedCalendars != true || Side == SideType.Right || Picker.ShowOnlyOneCalendar == true);\r\n\r\n        private List<string> DayNames => GetDayNames();\r\n\r\n        private List<string> GetDayNames()\r\n        {\r\n            if (CustomDayNames?.Count == 7) return CustomDayNames;\r\n\r\n            var dayNames = Picker.Culture.DateTimeFormat.ShortestDayNames.ToList();\r\n            var firstDayNumber = (int)Picker.FirstDayOfWeek;\r\n            if (firstDayNumber > 0)\r\n            {\r\n                for (int i = 0; i < firstDayNumber; i++)\r\n                {\r\n                    var item = dayNames[0];\r\n                    dayNames.Insert(dayNames.Count, item);\r\n                    dayNames.RemoveAt(0);\r\n                }\r\n            }\r\n            return dayNames;\r\n        }\r\n\r\n        private Task PreviousMonth(bool enabled)\r\n        {\r\n            if (!enabled) return Task.CompletedTask;\r\n            return OnMonthChanged.InvokeAsync(CalendarData.Month.Subtract(CalendarData.Month.Offset).ToOffset(TimeSpan.Zero).AddMonths(-1));\r\n        }\r\n\r\n        private Task NextMonth(bool enabled)\r\n        {\r\n            if (!enabled) return Task.CompletedTask;\r\n            return OnMonthChanged.InvokeAsync(CalendarData.Month.Subtract(CalendarData.Month.Offset).ToOffset(TimeSpan.Zero).AddMonths(1));\r\n        }\r\n\r\n        private Task MonthSelected(int month)\r\n        {\r\n            var d = CalendarData.Month;\r\n            return OnMonthChanged.InvokeAsync(new DateTime(d.Year, month, 1, 12, 0, 0));\r\n        }\r\n\r\n        private Task YearSelected(int year)\r\n        {\r\n            var d = CalendarData.Month;\r\n            var newMonth = new DateTimeOffset(year, d.Month, 1, 12, 0, 0, d.Offset);\r\n            if (newMonth > Picker.MaxDate) newMonth = Picker.MaxDate.Value;\r\n            else if (newMonth < Picker.MinDate) newMonth = Picker.MinDate.Value;\r\n            return OnMonthChanged.InvokeAsync(newMonth);\r\n        }\r\n\r\n        private Task ClickDate(CalendarItem dt)\r\n        {\r\n            if (dt.Disabled) return Task.CompletedTask;\r\n            return OnClickDate.InvokeAsync(dt.Day);\r\n        }\r\n\r\n        private Task OnMouseOverDate(DateTimeOffset date)\r\n        {\r\n            if (Picker.HoverDate != date)\r\n            {\r\n                return OnHoverDate.InvokeAsync(date);\r\n            }\r\n            return Task.CompletedTask;\r\n        }\r\n\r\n        private int GetWeekOfYear(DateTime time)\r\n        {\r\n            var weekRule = Picker.Culture.DateTimeFormat.CalendarWeekRule;\r\n            var firstDayOfWeek = CalendarData.FirstDayOfWeek;\r\n            return DateTimeFormatInfo.CurrentInfo.Calendar.GetWeekOfYear(time, weekRule, firstDayOfWeek);\r\n        }\r\n\r\n        private int GetIso8601WeekOfYear(DateTime time)\r\n        {\r\n            DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);\r\n            if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)\r\n            {\r\n                time = time.AddDays(3);\r\n            }\r\n\r\n            return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "BlazorDateRangePicker/Calendar.razor.css",
    "content": "﻿.next span, .prev span {\n    color: #fff;\n    border: solid black;\n    border-width: 0 2px 2px 0;\n    border-radius: 0;\n    display: inline-block;\n    padding: 3px;\n}\n\n.next span {\n    transform: rotate(-45deg);\n    -webkit-transform: rotate(-45deg);\n}\n\n.prev span {\n    transform: rotate(135deg);\n    -webkit-transform: rotate(135deg);\n}\n\nth, td {\n    white-space: nowrap;\n    text-align: center;\n    vertical-align: middle;\n    min-width: 32px;\n    width: 32px;\n    height: 24px;\n    line-height: 24px;\n    font-size: 12px;\n    border-radius: 4px;\n    border: 1px solid transparent;\n    white-space: nowrap;\n    cursor: pointer;\n}\n\ntable {\n    width: 100%;\n    margin: 0;\n    border-spacing: 0;\n    border-collapse: collapse;\n}\n\ntd.available:hover, th.available:hover {\n    background-color: #eee;\n    border-color: transparent;\n    color: inherit;\n}\n\ntd.week, th.week {\n    font-size: 80%;\n    color: #ccc;\n}\n\ntd.disabled, option.disabled {\n    color: #999;\n    cursor: not-allowed;\n    text-decoration: line-through;\n}\n\ntd.off, td.off.in-range, td.off.start-date, td.off.end-date {\n    background-color: #fff;\n    border-color: transparent;\n    color: #999;\n}\n\ntd.in-range {\n    background-color: #ebf4f8;\n    border-color: transparent;\n    color: #000;\n    border-radius: 0;\n}\n\ntd.start-date {\n    border-radius: 4px 0 0 4px;\n}\n\ntd.end-date {\n    border-radius: 0 4px 4px 0;\n}\n\ntd.start-date.end-date {\n    border-radius: 4px;\n}\n\ntd.active, td.active:hover {\n    background-color: #357ebd;\n    border-color: transparent;\n    color: #fff;\n}\n\nth.month {\n    width: auto;\n}\n\nselect.monthselect, select.yearselect {\n    font-size: 12px;\n    padding: 1px;\n    height: auto;\n    margin: 0;\n    cursor: default;\n}\n\nselect.monthselect {\n    margin-right: 2%;\n    width: 56%;\n}\n\nselect.yearselect {\n    width: 40%;\n}\n\n.daterangepicker .drp-buttons {\n    clear: both;\n    text-align: right;\n    padding: 8px;\n    border-top: 1px solid #ddd;\n    display: none;\n    line-height: 12px;\n    vertical-align: middle;\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/CalendarType.cs",
    "content": "﻿/**\n* author: Sergey Zaikin zaikinsr@yandex.ru\n* copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace BlazorDateRangePicker\n{\n    public class CalendarType\n    {\n        private int DaysInMonth => DateTime.DaysInMonth(Month.Year, Month.Month);\n        private DayOfWeek DayOfWeek => FirstDay.DayOfWeek;\n        internal DayOfWeek FirstDayOfWeek { get; set; }\n\n        internal SideType Side { get; private set; }\n\n        internal DateTimeOffset FirstDay => new(Month.Year, Month.Month, 1, 0, 0, 0, TimeSpan.Zero);\n        internal DateTimeOffset LastDay => new DateTime(Month.Year, Month.Month, DaysInMonth);\n\n        public DateTimeOffset Month { get; private set; } = DateTime.Today;\n\n        public List<List<CalendarItem>> Calendar { get; set; } = [];\n        private DateRangePicker Picker { get; set; }\n\n        public CalendarType(DateRangePicker picker, SideType side)\n        {\n            Picker = picker;\n            Side = side;\n            FirstDayOfWeek = Picker.FirstDayOfWeek.Value;\n        }\n\n        public async Task ChangeMonth(DateTimeOffset month)\n        {\n            Month = month;\n            await CalculateCalendar();\n        }\n\n        public async Task CalculateCalendar()\n        {\n            var calendar = Calendar ?? [];\n            for (var i = calendar.Count; i < 6; i++)\n            {\n                calendar.Add([]);\n            }\n\n            var startDayOffset = (int)FirstDayOfWeek - (int)DayOfWeek;\n            if (startDayOffset > 0) startDayOffset -= 7;\n            if (DayOfWeek == FirstDayOfWeek) startDayOffset = -7;\n\n            int col = 0, row = 0;\n            for (var i = 0; i < 42; i++, col++)\n            {\n                if (i > 0 && col % 7 == 0)\n                {\n                    col = 0;\n                    row++;\n                }\n\n                if (calendar[row].Count <= col)\n                    calendar[row].Add(new CalendarItem { Side = Side });\n\n                var outOfRange =\n                    (Month.Year == 1 && Month.Month == 1 && startDayOffset + i < 0) ||\n                    (Month.Year == 9999 && Month.Month == 12 && startDayOffset + i >= DaysInMonth);\n\n                calendar[row][col].OutOfRange = outOfRange;\n\n                if (outOfRange)\n                {\n                    continue;\n                }\n\n                var day = new DateTimeOffset(Month.Year, Month.Month, 1, 12, 0, 0, TimeSpan.Zero).AddDays(startDayOffset + i);\n                if (calendar[row][col].Day != day)\n                    calendar[row][col].Day = day;\n\n                await UpdateCellClasses(calendar[row][col]);\n            }\n            Calendar = calendar;\n        }\n\n        private async Task UpdateCellClasses(CalendarItem day)\n        {\n            var classes = new List<string>();\n            var disabled = false;\n            var dt = day.Day;\n            // Highlight today's date\n            if (dt.Date == DateTime.Today)\n            { classes.Add(\"today\"); }\n\n            // Highlight weekends\n            if (dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday)\n            { classes.Add(\"weekend\"); }\n\n            // Grey out the dates in other months displayed at beginning and end of this calendar\n            if (dt.Month != Month.Month)\n            {\n                classes.Add(\"off\");\n                classes.Add(\"ends\");\n            }\n            // Don't allow selection of dates before the minimum date\n            if (Picker.MinDate.HasValue && dt.Date < Picker.MinDate.Value.Date)\n            {\n                classes.Add(\"off\");\n                classes.Add(\"disabled\");\n                disabled = true;\n            }\n            // Don't allow selection of dates after the maximum date\n            if (Picker.MaxDate.HasValue && dt.Date > Picker.MaxDate.Value.Date)\n            {\n                classes.Add(\"off\");\n                classes.Add(\"disabled\");\n                disabled = true;\n            }\n\n            if (Picker.MinSpan.HasValue && Picker.TStartDate.HasValue && Picker.TEndDate == null\n                && dt - Picker.TStartDate >= TimeSpan.Zero && dt - Picker.TStartDate < Picker.MinSpan)\n            {\n                classes.Add(\"disabled\");\n                disabled = true;\n            }\n\n            if (Picker.MaxSpan.HasValue && Picker.TStartDate.HasValue && Picker.TEndDate == null\n                && dt - Picker.TStartDate > Picker.MaxSpan)\n            {\n                classes.Add(\"off\");\n                classes.Add(\"disabled\");\n                disabled = true;\n            }\n\n            // Don't allow selection of date if a custom function decides it's invalid\n            if (await IsDayDisabled(dt))\n            {\n                classes.Add(\"disabled\");\n                disabled = true;\n            }\n\n            // Highlight the currently selected start date\n            if (dt.ToString(\"yyyy-MM-dd\") == Picker.TStartDate?.ToString(\"yyyy-MM-dd\"))\n            {\n                classes.Add(\"active\");\n                classes.Add(\"start-date\");\n            }\n\n            // Highlight the currently selected end date\n            if (Picker.TEndDate != null && dt.ToString(\"yyyy-MM-dd\") == Picker.TEndDate?.ToString(\"yyyy-MM-dd\"))\n            {\n                classes.Add(\"active\");\n                classes.Add(\"end-date\");\n            }\n\n            // Highlight dates in-between the selected dates\n            if (Picker.TEndDate != null && dt > Picker.TStartDate && dt < Picker.TEndDate)\n            {\n                classes.Add(\"in-range\");\n            }\n\n            // Apply custom classes for this date\n            if (Picker.CustomDateFunction != null)\n            {\n                classes.Add(await GetCustomDateClass(dt));\n            }\n\n            // Highlight dates in-between the selected dates when hover\n            if ((dt > Picker.TStartDate && dt < Picker.HoverDate) || dt.Date == Picker.HoverDate?.Date)\n            {\n                classes.Add(\"in-range\");\n            }\n\n            if (!disabled)\n            {\n                classes.Add(\"available\");\n            }\n\n            day.Disabled = disabled;\n            day.ClassNames = string.Join(\" \", classes.Distinct());\n        }\n\n        private async Task<bool> IsDayDisabled(DateTimeOffset date)\n        {\n            if (Picker.DaysEnabledFunction != null)\n            {\n                return !Picker.DaysEnabledFunction(date);\n            }\n            else if (Picker.DaysEnabledFunctionAsync != null)\n            {\n                return !await Picker.DaysEnabledFunctionAsync(date);\n            }\n            return false;\n        }\n\n        private async Task<string> GetCustomDateClass(DateTimeOffset date)\n        {\n            if (Picker.CustomDateFunction == null) return string.Empty;\n\n            var customFunctionResult = Picker.CustomDateFunction(date);\n            return customFunctionResult switch\n            {\n                string className => className ?? string.Empty,\n                bool addName => addName ? Picker.CustomDateClass ?? string.Empty : string.Empty,\n                Task<string> task => await task,\n                Task<bool> task => await task ? Picker.CustomDateClass ?? string.Empty : string.Empty,\n                Task<object> task => await task switch\n                {\n                    string className => className ?? string.Empty,\n                    bool addName => addName ? Picker.CustomDateClass ?? string.Empty : string.Empty,\n                    _ => string.Empty\n                },\n                _ => string.Empty\n            };\n        }\n    }\n\n    public class CalendarItem\n    {\n        public SideType Side { get; set; }\n        public DateTimeOffset Day { get; set; }\n        public Action Hover { get; set; }\n        public Action Click { get; set; }\n        public string ClassNames { get; set; }\n        public bool Disabled { get; set; }\n        public bool OutOfRange { get; set; }\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRange.cs",
    "content": "﻿/**\n* author: Sergey Zaikin zaikinsr@yandex.ru\n* copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nusing System;\n\nnamespace BlazorDateRangePicker\n{\n\n    public class DateRange\n    {\n        public DateTimeOffset Start { get; set; }\n        public DateTimeOffset End { get; set; }\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRangePicker.razor",
    "content": "﻿@*\r\n    * author: Sergey Zaikin zaikinsr@yandex.ru\r\n    * copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\r\n    * license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\r\n*@\r\n\r\n@if (PickerTemplate == null && Inline != true)\r\n{\r\n    <input id=\"@Id\" type=\"text\" @attributes=\"CombinedAttributes\" value=\"@FormattedRange\" @oninput=\"OnTextInput\" @onfocusin=\"Open\" @onfocusout=\"LostFocus\" />\r\n}\r\nelse if (PickerTemplate != null)\r\n{\r\n    @PickerTemplate(this)\r\n}\r\n\r\n@{ RenderFragment picker = \r\n@<div class=\"daterangepicker-visibility-@(Inline == true || Visible ? \"visible\" : \"hidden\")\">\r\n    <div id=\"@ContainerId\" class=\"daterangepicker @RootStyles\">\r\n\r\n        <div class=\"ranges\">\r\n            @if (Ranges != null && Ranges.Any())\r\n            {\r\n                <ul>\r\n                    @foreach (var range in Ranges)\r\n                    {\r\n                        <li class=\"@(range.Key == ChosenLabel ? \"active\" : \"\")\" @onclick=\"@(args => ClickRange(args, range.Key))\">@range.Key</li>\r\n                    }\r\n                    @if (ShowCustomRangeLabel == true)\r\n                    {\r\n                        <li class=\"@(CustomRangeLabel == ChosenLabel ? \"active\" : \"\")\" @onclick=\"@(args => ClickRange(args, CustomRangeLabel))\">@CustomRangeLabel</li>\r\n                    }\r\n                </ul>\r\n            }\r\n        </div>\r\n\r\n        <CascadingValue Value=\"this\">\r\n            <div class=\"drp-calendar left @(ShowOnlyOneCalendar == true ? \"single\" : \"\")\">\r\n                <div class=\"calendar-table\">\r\n                    <Calendar Side=\"@SideType.Left\"\r\n                              CustomDayNames=\"@CustomDayNames\"\r\n                              CalendarData=\"@LeftCalendar\"\r\n                              OnMonthChanged=\"LeftMonthChanged\"\r\n                              OnClickDate=\"ClickDate\"\r\n                              OnHoverDate=\"OnHoverDate\" />\r\n                </div>\r\n                @if (TimePicker == true)\r\n                {\r\n                    <div class=\"calendar-time\">\r\n                        <TimePicker Side=\"@SideType.Left\" Day=\"TStartDate\" TimePicker24Hour=\"TimePicker24Hour\"\r\n                                    Time=\"StartTime\" TimeChanged=\"StartTimeChanged\" />\r\n                    </div>\r\n                }\r\n            </div>\r\n            @if (ShowOnlyOneCalendar != true)\r\n            {\r\n                <div class=\"drp-calendar right\">\r\n                    <div class=\"calendar-table\">\r\n                        <Calendar Side=\"@SideType.Right\"\r\n                              CustomDayNames=\"@CustomDayNames\"\r\n                              CalendarData=\"@RightCalendar\"\r\n                              OnMonthChanged=\"RightMonthChanged\"\r\n                              OnClickDate=\"ClickDate\"\r\n                              OnHoverDate=\"OnHoverDate\" />\r\n                    </div>\r\n                    @if (TimePicker == true)\r\n                    {\r\n                        <div class=\"calendar-time\">\r\n                            <TimePicker Side=\"@SideType.Right\" Day=\"TEndDate\" TimePicker24Hour=\"TimePicker24Hour\"\r\n                                        Time=\"EndTime\" TimeChanged=\"EndTimeChanged\" />\r\n                        </div>\r\n                    }\r\n                </div>\r\n            }\r\n        </CascadingValue>\r\n\r\n        <div class=\"drp-buttons\">\r\n            @if (ButtonsTemplate == null)\r\n            {\r\n                <span class=\"drp-selected\"></span>\r\n                <button class=\"cancelBtn @ButtonClasses @CancelButtonClasses\" @onclick=\"ClickCancel\" type=\"button\">@CancelLabel</button>\r\n                <button class=\"applyBtn @ButtonClasses @ApplyButtonClasses\" @onclick=\"ClickApply\" disabled=\"@(TStartDate == null || TEndDate == null)\" type=\"button\">@ApplyLabel</button>\r\n            }\r\n            else\r\n            {\r\n                @ButtonsTemplate(this)\r\n            }\r\n        </div>\r\n\r\n    </div>\r\n</div>;\r\n}\r\n\r\n@if(Render == true) \r\n{\r\n    @if(Container == null)\r\n    {\r\n        @picker\r\n    }\r\n    else\r\n    {\r\n        Container.SetContent(picker);\r\n    }\r\n}\r\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRangePicker.razor.cs",
    "content": "/**\r\n* @author: Sergey Zaikin zaikinsr@yandex.ru\r\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\r\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\r\n*/\r\n\r\nusing Microsoft.AspNetCore.Components;\r\nusing Microsoft.AspNetCore.Components.Web;\r\nusing Microsoft.Extensions.DependencyInjection;\r\nusing Microsoft.JSInterop;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Globalization;\r\nusing System.Linq;\r\nusing System.Threading;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace BlazorDateRangePicker\r\n{\r\n    public partial class DateRangePicker : ComponentBase, IConfigurableOptions\r\n    {\r\n        [Inject]\r\n        protected IJSRuntime JSRuntime { get; set; }\r\n\r\n        [Inject]\r\n        protected IServiceProvider ServiceProvider { get; set; }\r\n\r\n        /// <summary>\r\n        /// Guid for container id used for JSInterop \r\n        /// </summary>\r\n        public string ContainerId { get; set; } = Guid.NewGuid().ToString();\r\n\r\n        /// <summary>\r\n        /// Id for input field used for JSInterop \r\n        /// </summary>\r\n        [Parameter]\r\n        public string Id { get; set; } = Guid.NewGuid().ToString();\r\n        public string ParentId => Id;\r\n\r\n        public delegate (bool startDateParsed, bool endDateParsed) DateParsingDelegate(string value, out DateTimeOffset startDate, out DateTimeOffset endDate);\r\n\r\n        /// <summary>\r\n        /// Attach a named properties config object to this instance of datepicker\r\n        /// </summary>\r\n        [Parameter]\r\n        public string Config { get; set; }\r\n\r\n        private Dictionary<string, object> ConfigAttributes { get; set; }\r\n\r\n        protected private Dictionary<string, object> CombinedAttributes\r\n        {\r\n            get\r\n            {\r\n                var combined = new Dictionary<string, object>();\r\n                if (ConfigAttributes != null)\r\n                {\r\n                    foreach (var attr in ConfigAttributes)\r\n                    {\r\n                        combined[attr.Key] = attr.Value;\r\n                    }\r\n                }\r\n\r\n                if (Attributes != null)\r\n                {\r\n                    foreach (var attr in Attributes)\r\n                    {\r\n                        combined[attr.Key] = attr.Value;\r\n                    }\r\n                }\r\n                return combined;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Picker positioning container\r\n        /// </summary>\r\n        [Parameter]\r\n        public PickerContainer Container { get; set; }\r\n\r\n        /// <summary>\r\n        /// Custom picker input template\r\n        /// </summary>\r\n        [Parameter]\r\n        public RenderFragment<DateRangePicker> PickerTemplate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Custom picker buttons template\r\n        /// </summary>\r\n        [Parameter]\r\n        public RenderFragment<DateRangePicker> ButtonsTemplate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Custom picker input template\r\n        /// </summary>\r\n        [Parameter]\r\n        public RenderFragment<CalendarItem> DayTemplate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Picker popup visibility. Use Open() instead.\r\n        /// </summary>\r\n        [Parameter]\r\n        public bool Visible { get; set; }\r\n\r\n        public DateTimeOffset? TStartDate { get; set; }\r\n\r\n        [Parameter]\r\n        public EventCallback<DateTimeOffset?> StartDateChanged { set; get; }\r\n\r\n        public DateTimeOffset? TEndDate { get; set; }\r\n\r\n        [Parameter]\r\n        public EventCallback<DateTimeOffset?> EndDateChanged { set; get; }\r\n        \r\n        /// <summary>\r\n        /// Triggered when the apply button is clicked, or when a predefined range is clicked\r\n        /// </summary>\r\n        [Parameter]\r\n        public EventCallback<DateRange> OnRangeSelect { get; set; }\r\n\r\n        /// <summary>\r\n        /// Triggered when the picker reset by user\r\n        /// </summary>\r\n        [Parameter]\r\n        public EventCallback OnReset { get; set; }\r\n\r\n        /// <summary>An event that is invoked when the DatePicker is opened.</summary>\r\n        [Parameter]\r\n        public EventCallback OnOpened { get; set; }\r\n\r\n        /// <summary>An event that is invoked when the DatePicker is closed.</summary>\r\n        [Parameter]\r\n        public EventCallback OnClosed { get; set; }\r\n\r\n        /// <summary>An event that is invoked on backdrop click (false) or cancel button click (true).</summary>\r\n        [Parameter]\r\n        public EventCallback<bool> OnCancel { get; set; }\r\n\r\n        /// <summary>An event that is invoked when left or right calendar's month changed.</summary>\r\n        [Parameter]\r\n        public EventCallback OnMonthChanged { get; set; }\r\n\r\n        /// <summary>An event that is invoked when left or right calendar's month changed.</summary>\r\n        [Parameter]\r\n        public EventCallback<CancellationToken> OnMonthChangedAsync { get; set; }\r\n\r\n        /// <summary>An event that is invoked when StartDate is selected</summary>\r\n        [Parameter]\r\n        public EventCallback<DateTimeOffset> OnSelectionStart { get; set; }\r\n\r\n        /// <summary>An event that is invoked when EndDate is selected but before apply button is clicked</summary>\r\n        [Parameter]\r\n        public EventCallback<DateTimeOffset> OnSelectionEnd { get; set; }\r\n\r\n        /// <summary>\r\n        /// An event that is invoked when the StartDate is changed when TimePicker is enabled\r\n        /// </summary>\r\n        [Parameter]\r\n        public EventCallback<TimeSpan> OnStartTimeChanged { set; get; }\r\n\r\n        /// <summary>\r\n        /// An event that is invoked when the EndDate is changed when TimePicker is enabled\r\n        /// </summary>\r\n        [Parameter]\r\n        public EventCallback<TimeSpan> OnEndTimeChanged { set; get; }\r\n\r\n        private DateParsingDelegate ParseFunction => CustomParseFunction ?? TryParseDates;\r\n\r\n        public CalendarType LeftCalendar { get; set; }\r\n        public CalendarType RightCalendar { get; set; }\r\n\r\n        public string ChosenLabel { get; private set; }\r\n        internal bool CalendarsVisible { get; set; }\r\n        internal bool Loading { get; set; }\r\n        public DateTimeOffset? HoverDate { get; set; }\r\n\r\n        private string EditText { get; set; }\r\n        private TimeSpan StartTime { get; set; }\r\n        private TimeSpan EndTime { get; set; }\r\n        public bool Render { get; set; }\r\n\r\n        private Task<IJSObjectReference> _module;\r\n        private readonly string ImportPath = $\"./_content/BlazorDateRangePicker/clickAndPositionHandler.js?v=\" +\r\n            typeof(DateRangePicker).Assembly.GetName().Version.ToString();\r\n\r\n        private Task<IJSObjectReference> Module => _module ??= JSRuntime.InvokeAsync<IJSObjectReference>(\"import\", ImportPath).AsTask();\r\n\r\n        protected override void OnInitialized()\r\n        {\r\n            var configs = ServiceProvider.GetServices<DateRangePickerConfig>();\r\n            var config = configs?.FirstOrDefault();\r\n            if (!string.IsNullOrEmpty(Config) && configs.Any(c => c.Name == Config))\r\n            {\r\n                config = configs.First(c => c.Name == Config);\r\n            }\r\n\r\n            config ??= new DateRangePickerConfig();\r\n            config.CopyProperties(this);\r\n\r\n            ConfigAttributes = config.Attributes;\r\n\r\n            if (string.IsNullOrEmpty(DateFormat))\r\n            {\r\n                DateFormat = Culture.DateTimeFormat.ShortDatePattern;\r\n            }\r\n\r\n            if (!TimePicker24Hour.HasValue)\r\n            {\r\n                TimePicker24Hour = !Culture.DateTimeFormat.LongTimePattern.EndsWith(\"tt\");\r\n            }\r\n\r\n            StartTime = TStartDate.HasValue\r\n                ? TStartDate.Value.TimeOfDay\r\n                : InitialStartTime ?? TimeSpan.Zero;\r\n\r\n            EndTime = TEndDate.HasValue\r\n                ? TEndDate.Value.TimeOfDay\r\n                : InitialEndTime ?? TimeSpan.FromDays(1).Add(TimeSpan.FromTicks(-1));\r\n\r\n            if (SingleDatePicker == true && TimePicker == false && !AutoApply.HasValue) AutoApply = true;\r\n            if (SingleDatePicker == true && !ShowOnlyOneCalendar.HasValue) ShowOnlyOneCalendar = true;\r\n\r\n            if (!FirstDayOfWeek.HasValue)\r\n            {\r\n                FirstDayOfWeek = Culture.DateTimeFormat.FirstDayOfWeek;\r\n            }\r\n\r\n            if (Inline == true) Prerender = true;\r\n            Render = Prerender == true;\r\n\r\n            LeftCalendar = new CalendarType(this, SideType.Left);\r\n            RightCalendar = new CalendarType(this, SideType.Right);\r\n\r\n            TStartDate = StartDate?.Date.Add(StartTime);\r\n            TEndDate = EndDate?.Date.Add(EndTime);\r\n        }\r\n\r\n        protected override Task OnAfterRenderAsync(bool firstRender)\r\n        {\r\n            if (firstRender && Prerender == true) return AdjustCalendars();\r\n            return Task.CompletedTask;\r\n        }\r\n\r\n        public override async Task SetParametersAsync(ParameterView parameters)\r\n        {\r\n            if (parameters.TryGetValue(nameof(EndDate), out DateTimeOffset? endDate) && endDate != EndDate)\r\n            {\r\n                TEndDate = endDate;\r\n            }\r\n\r\n            if (parameters.TryGetValue(nameof(StartDate), out DateTimeOffset? startDate) && startDate != StartDate)\r\n            {\r\n                TStartDate = startDate;\r\n                var singleDatePicker = parameters.TryGetValue(nameof(SingleDatePicker), out bool? enabled) && enabled == true;\r\n                if (SingleDatePicker == true || singleDatePicker)\r\n                {\r\n                    EndDate = TStartDate;\r\n                    TEndDate = TStartDate;\r\n                }\r\n            }\r\n\r\n            if (parameters.TryGetValue(nameof(Culture), out CultureInfo culture))\r\n            {\r\n                if (!parameters.TryGetValue(nameof(DateFormat), out string _))\r\n                    DateFormat = culture.DateTimeFormat.ShortDatePattern;\r\n                if (!parameters.TryGetValue(nameof(TimePicker24Hour), out bool? _))\r\n                    TimePicker24Hour = culture.DateTimeFormat.LongTimePattern.EndsWith(\"tt\");\r\n                if (!parameters.TryGetValue(nameof(FirstDayOfWeek), out DayOfWeek? _))\r\n                    FirstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;\r\n            }\r\n\r\n            if (LeftCalendar != null && RightCalendar != null && FirstDayOfWeek.HasValue && LeftCalendar.FirstDayOfWeek != FirstDayOfWeek)\r\n            {\r\n                LeftCalendar.FirstDayOfWeek = FirstDayOfWeek.Value;\r\n                RightCalendar.FirstDayOfWeek = FirstDayOfWeek.Value;\r\n            }\r\n\r\n            await base.SetParametersAsync(parameters);\r\n        }\r\n\r\n        protected override async Task OnParametersSetAsync()\r\n        {\r\n            if (TimePicker == true && AutoApply == true) AutoApply = false;\r\n            await LeftCalendar.CalculateCalendar();\r\n            await RightCalendar.CalculateCalendar();\r\n        }\r\n\r\n        public string FormattedRange\r\n        {\r\n            get\r\n            {\r\n                if (!string.IsNullOrEmpty(EditText))\r\n                {\r\n                    return EditText;\r\n                }\r\n\r\n                if (SingleDatePicker == true && TStartDate != null)\r\n                {\r\n                    return $\"{TStartDate.Value.ToString(DateFormat, Culture)}\";\r\n                }\r\n\r\n                if (TStartDate != null && TEndDate != null)\r\n                {\r\n                    return $\"{TStartDate.Value.ToString(DateFormat, Culture)} - \" +\r\n                           $\"{TEndDate.Value.ToString(DateFormat, Culture)}\";\r\n                }\r\n                else\r\n                {\r\n                    return string.Empty;\r\n                }\r\n            }\r\n        }\r\n\r\n        private string RootStyles\r\n        {\r\n            get\r\n            {\r\n                var result = new List<string>();\r\n                if (Ranges?.Count > 0) { result.Add(\"show-ranges\"); }\r\n                if (AutoApply == true) { result.Add(\"auto-apply\"); }\r\n                if (Loading == true) { result.Add(\"loading\"); }\r\n                if (Ranges == null || Ranges.Count == 0 || AlwaysShowCalendars == true || CalendarsVisible)\r\n                {\r\n                    result.Add(\"show-calendar\");\r\n                }\r\n\r\n                if (Inline != true)\r\n                {\r\n                    if (Drops == DropsType.Up) { result.Add(\"drop-up\"); }\r\n                    result.Add($\"opens{Enum.GetName(typeof(SideType), Opens).ToLower()}\");\r\n                }\r\n                else\r\n                {\r\n                    result.Add(\"inline\");\r\n                }\r\n\r\n                return string.Join(\" \", result);\r\n            }\r\n        }\r\n\r\n        public virtual Task OnTextInput(ChangeEventArgs e)\r\n        {\r\n            EditText = e.Value.ToString();\r\n\r\n            (bool startDateParsed, bool endDateParsed) = ParseFunction(EditText, out DateTimeOffset startDate, out DateTimeOffset endDate);\r\n\r\n            if (startDateParsed && startDate < MinDate)\r\n            {\r\n                startDate = MinDate.Value.Date;\r\n            }\r\n\r\n            var maxDate = MaxDate;\r\n            if (MaxSpan.HasValue)\r\n            {\r\n                var maxLimit = startDate.Add(MaxSpan.Value).AddTicks(-1);\r\n                if (!maxDate.HasValue || maxLimit < maxDate)\r\n                {\r\n                    maxDate = maxLimit;\r\n                }\r\n            }\r\n\r\n            var minDate = MinDate;\r\n            if (MinSpan.HasValue)\r\n            {\r\n                var minLimit = startDate.Add(MinSpan.Value);\r\n                if (!minDate.HasValue || minLimit > minDate)\r\n                {\r\n                    minDate = minLimit;\r\n                }\r\n            }\r\n\r\n            if (endDateParsed)\r\n            {\r\n                if (endDate > maxDate) endDate = maxDate.Value.Date;\r\n                if (endDate < minDate) endDate = minDate.Value.Date;\r\n            }\r\n\r\n            if (startDateParsed && SingleDatePicker == true)\r\n            {\r\n                if (startDate.TimeOfDay == TimeSpan.Zero) startDate = SafeSetStartTime(startDate);\r\n\r\n                TStartDate = startDate;\r\n                TEndDate = startDate;\r\n                EditText = null;\r\n                return ClickApply(null);\r\n            }\r\n            else if (startDateParsed && endDateParsed && startDate <= endDate\r\n                && (!minDate.HasValue || startDate >= MinDate)\r\n                && (!maxDate.HasValue || endDate <= MaxDate))\r\n            {\r\n                if (startDate.TimeOfDay == TimeSpan.Zero) startDate = SafeSetStartTime(startDate);\r\n                if (endDate.TimeOfDay == TimeSpan.Zero) endDate = SafeSetEndTime(endDate);\r\n\r\n                TStartDate = startDate;\r\n                TEndDate = endDate;\r\n                EditText = null;\r\n                return ClickApply(null);\r\n            }\r\n            else if (string.IsNullOrEmpty(EditText) && ResetOnClear == true)\r\n            {\r\n                EditText = null;\r\n                return Reset();\r\n            }\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n\r\n        private (bool startDateParsed, bool endDateParsed) TryParseDates(string value, out DateTimeOffset startDate, out DateTimeOffset endDate)\r\n        {\r\n            var dateStrings = value.Split('-').Select(s => s.Trim()).ToList();\r\n            if (dateStrings.Count != 2)\r\n            {\r\n                dateStrings = [value, string.Empty];\r\n            }\r\n\r\n            var startDateParsed = DateTimeOffset.TryParseExact(dateStrings[0], DateFormat, Culture,\r\n                System.Globalization.DateTimeStyles.AssumeUniversal, out startDate);\r\n            var endDateParsed = DateTimeOffset.TryParseExact(dateStrings[1], DateFormat, Culture,\r\n                System.Globalization.DateTimeStyles.AssumeUniversal, out endDate);\r\n\r\n            return (startDateParsed, endDateParsed);\r\n        }\r\n\r\n        public void LostFocus(FocusEventArgs _)\r\n        {\r\n            EditText = null;\r\n        }\r\n\r\n        public virtual async Task Reset()\r\n        {\r\n            TStartDate = null;\r\n            TEndDate = null;\r\n\r\n            await ClickApply(null);\r\n            await OnReset.InvokeAsync(null);\r\n        }\r\n\r\n        private Task ClickRange(MouseEventArgs e, string label)\r\n        {\r\n            ChosenLabel = label;\r\n            if (label == CustomRangeLabel)\r\n            {\r\n                CalendarsVisible = true;\r\n                return Task.CompletedTask;\r\n            }\r\n            else\r\n            {\r\n                var dates = Ranges[label];\r\n\r\n                if (TimePicker == true)\r\n                {\r\n                    StartTime = dates.Start.TimeOfDay;\r\n                    EndTime = dates.End.TimeOfDay;\r\n                }\r\n\r\n                TStartDate = SafeSetStartTime(dates.Start);\r\n                TEndDate = SafeSetEndTime(dates.End.Date);\r\n\r\n                if (AlwaysShowCalendars != true)\r\n                {\r\n                    CalendarsVisible = false;\r\n                }\r\n                return ClickApply(e);\r\n            }\r\n        }\r\n\r\n        private Task LeftMonthChanged(DateTimeOffset date)\r\n        {\r\n            var leftMonth = date;\r\n            var rightMonth = LinkedCalendars == true\r\n                ? date.AddMonths(1)\r\n                : (DateTimeOffset?)null;\r\n            return MonthChanged(leftMonth, rightMonth);\r\n        }\r\n\r\n        private Task RightMonthChanged(DateTimeOffset date)\r\n        {\r\n            var rightMonth = date;\r\n            var leftMonth = LinkedCalendars == true\r\n                ? date.AddMonths(-1)\r\n                : (DateTimeOffset?)null;\r\n\r\n            return MonthChanged(leftMonth, rightMonth);\r\n        }\r\n\r\n        private CancellationTokenSource RunningTaskToken;\r\n        private async Task MonthChanged(DateTimeOffset? leftDate, DateTimeOffset? rightDate)\r\n        {\r\n            Loading = true;\r\n\r\n            if (leftDate.HasValue)\r\n            {\r\n                await LeftCalendar.ChangeMonth(leftDate.Value);\r\n            }\r\n            if (rightDate.HasValue)\r\n            {\r\n                await RightCalendar.ChangeMonth(rightDate.Value);\r\n            }\r\n\r\n            if (RunningTaskToken != null)\r\n            {\r\n                RunningTaskToken.Cancel();\r\n                RunningTaskToken.Dispose();\r\n                RunningTaskToken = null;\r\n            }\r\n\r\n            RunningTaskToken = new CancellationTokenSource();\r\n            var cts = RunningTaskToken;\r\n            await OnMonthChanged.InvokeAsync(null);\r\n            var task = OnMonthChangedAsync.InvokeAsync(RunningTaskToken.Token);\r\n            await task;\r\n            if (!cts.IsCancellationRequested)\r\n            {\r\n                Loading = false;\r\n                StateHasChanged();\r\n            }\r\n        }\r\n\r\n        private async Task StartTimeChanged(TimeSpan start)\r\n        {\r\n            StartTime = start;\r\n            TStartDate = TStartDate.HasValue ? SafeSetStartTime(TStartDate.Value) : null;\r\n            await OnStartTimeChanged.InvokeAsync(start);\r\n        }\r\n\r\n        private async Task EndTimeChanged(TimeSpan end)\r\n        {\r\n            EndTime = end;\r\n            TEndDate = TEndDate.HasValue ? SafeSetEndTime(TEndDate.Value) : null;\r\n            await OnEndTimeChanged.InvokeAsync(end);\r\n        }\r\n\r\n        public virtual async Task ClickDate(DateTimeOffset date)\r\n        {\r\n            HoverDate = null;\r\n            if (TEndDate.HasValue || TStartDate == null || date.Date.Add(EndTime) < TStartDate)\r\n            {\r\n                // picking start\r\n                TEndDate = null;\r\n                TStartDate = SafeSetStartTime(date);\r\n                await OnSelectionStart.InvokeAsync(TStartDate.Value);\r\n            }\r\n            else\r\n            {\r\n                // picking end\r\n                TEndDate = SafeSetEndTime(date);\r\n                await OnSelectionEnd.InvokeAsync(TEndDate.Value);\r\n                if (AutoApply == true)\r\n                {\r\n                    await ClickApply(null);\r\n                }\r\n            }\r\n\r\n            if (SingleDatePicker == true)\r\n            {\r\n                TStartDate = SafeSetStartTime(date);\r\n                TEndDate = TStartDate;\r\n                if (AutoApply == true) await ClickApply(null);\r\n            }\r\n\r\n            await LeftCalendar.CalculateCalendar();\r\n            await RightCalendar.CalculateCalendar();\r\n        }\r\n\r\n        private DateTimeOffset SafeSetStartTime(DateTimeOffset date) => SafeSetTime(date, true);\r\n\r\n        private DateTimeOffset SafeSetEndTime(DateTimeOffset date) => SafeSetTime(date, false);\r\n\r\n        private DateTimeOffset SafeSetTime(DateTimeOffset date, bool startTime)\r\n        {\r\n            var time = TimePicker == true\r\n                ? startTime ? StartTime : EndTime\r\n                : startTime ? TimeSpan.Zero : TimeSpan.FromDays(1).Add(TimeSpan.FromTicks(-1));\r\n\r\n            var isFirstDay = date.Day == 1 && date.Year == 0001 && date.Month == 1;\r\n            var isLastDay = date.Day == 31 && date.Year == 9999 && date.Month == 12;\r\n\r\n            if (isFirstDay)\r\n            {\r\n                var offset = new DateTimeOffset(date.Date.AddDays(1)).Offset;\r\n                return date.Date.Add(time < offset ? time + offset : time);\r\n            }\r\n            else if (isLastDay)\r\n            {\r\n                var offset = new DateTimeOffset(date.Date.AddDays(-1)).Offset;\r\n                return date.Date.Add(time - offset > TimeSpan.FromDays(1) ? time + offset : time);\r\n            }\r\n            else\r\n            {\r\n                return date.Date.Add(time);\r\n            }\r\n        }\r\n\r\n        private async Task OnHoverDate(DateTimeOffset date)\r\n        {\r\n            if (!TEndDate.HasValue)\r\n            {\r\n                HoverDate = date;\r\n                await LeftCalendar.CalculateCalendar();\r\n                await RightCalendar.CalculateCalendar();\r\n            }\r\n        }\r\n\r\n        public async Task ClickApply(MouseEventArgs e)\r\n        {\r\n            await Close();\r\n\r\n            StartDate = TStartDate;\r\n            await StartDateChanged.InvokeAsync(TStartDate);\r\n\r\n            EndDate = TEndDate;\r\n            await EndDateChanged.InvokeAsync(TEndDate);\r\n\r\n            if (TStartDate.HasValue && TEndDate.HasValue)\r\n            {\r\n                await OnRangeSelect.InvokeAsync(new DateRange\r\n                {\r\n                    Start = TStartDate.Value,\r\n                    End = TEndDate.Value\r\n                });\r\n            }\r\n        }\r\n\r\n        public async Task ClickCancel(MouseEventArgs e)\r\n        {\r\n            TStartDate = StartDate;\r\n            TEndDate = EndDate;\r\n            HoverDate = null;\r\n\r\n            await Close();\r\n            await OnCancel.InvokeAsync(e != null);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Show picker popup\r\n        /// </summary>\r\n        public async Task Open()\r\n        {\r\n            Render = true;\r\n\r\n            await Task.Yield();\r\n\r\n            if (Visible) return;\r\n\r\n            StartTime = TStartDate.HasValue\r\n                ? TStartDate.Value.TimeOfDay\r\n                : InitialStartTime ?? TimeSpan.Zero;\r\n\r\n            EndTime = TEndDate.HasValue\r\n                ? TEndDate.Value.TimeOfDay\r\n                : InitialEndTime ?? TimeSpan.FromDays(1).Add(TimeSpan.FromTicks(-1));\r\n\r\n            var selectedRange = Ranges?.FirstOrDefault(r =>\r\n                r.Value.Start.Date == TStartDate?.Date &&\r\n                r.Value.End.Date == TEndDate?.Date);\r\n            if (selectedRange?.Value != null)\r\n            {\r\n                ChosenLabel = selectedRange.Value.Key;\r\n                if (AlwaysShowCalendars != true) CalendarsVisible = false;\r\n            }\r\n            else if (CalendarsVisible || AlwaysShowCalendars == true)\r\n            {\r\n                ChosenLabel = CustomRangeLabel;\r\n                CalendarsVisible = true;\r\n            }\r\n\r\n            var module = await Module;\r\n            await module.InvokeVoidAsync(\"addClickOutsideEvent\", ContainerId, Id, DotNetObjectReference.Create(this));\r\n            await module.InvokeVoidAsync(\"getPickerPosition\", ContainerId, Id,\r\n                Enum.GetName(typeof(DropsType), Drops).ToLower(), Enum.GetName(typeof(SideType), Opens).ToLower());\r\n\r\n            Visible = true;\r\n            await OnOpened.InvokeAsync(null);\r\n            if (AutoAdjustCalendars == true || Prerender != true) await AdjustCalendars();\r\n        }\r\n\r\n        public virtual async Task AdjustCalendars()\r\n        {\r\n            Prerender = true;\r\n\r\n            var newLeftMonth = TStartDate ?? DateTime.Today;\r\n            var newRightMonth = LinkedCalendars == true\r\n                ? newLeftMonth.AddMonths(1)\r\n                : (TEndDate ?? newLeftMonth.AddMonths(1));\r\n\r\n            if (newLeftMonth.Month == newRightMonth.Month\r\n                && newLeftMonth.Year == newRightMonth.Year)\r\n            {\r\n                if (newRightMonth < DateTime.MaxValue.AddMonths(-1))\r\n                {\r\n                    newRightMonth = newRightMonth.AddMonths(1);\r\n                }\r\n            }\r\n\r\n            var needAdjust =\r\n                LeftCalendar?.Month.Month != newLeftMonth.Month\r\n                || LeftCalendar?.Month.Year != newLeftMonth.Year\r\n                || RightCalendar?.Month.Month != newRightMonth.Month\r\n                || RightCalendar?.Month.Year != newRightMonth.Year;\r\n\r\n            if (needAdjust)\r\n            {\r\n                await MonthChanged(newLeftMonth, newRightMonth);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Toggle picker popup state\r\n        /// </summary>\r\n        public async Task Toggle()\r\n        {\r\n            if (Visible) await Close();\r\n            else await Open();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Close picker popup\r\n        /// </summary>\r\n        public async Task Close()\r\n        {\r\n            await LeftCalendar.CalculateCalendar();\r\n            await RightCalendar.CalculateCalendar();\r\n            Visible = false;\r\n            await OnClosed.InvokeAsync(null);\r\n        }\r\n\r\n        /// <summary>\r\n        /// JSInvokable callback to handle outside click\r\n        /// </summary>\r\n        [JSInvokable]\r\n        public virtual async Task InvokeClickOutside()\r\n        {\r\n            if (Visible && CloseOnOutsideClick == true)\r\n            {\r\n                await ClickCancel(null);\r\n                StateHasChanged();\r\n            }\r\n        }\r\n\r\n        public async ValueTask DisposeAsync()\r\n        {\r\n            if (_module != null)\r\n            {\r\n                var module = await _module;\r\n                await module.DisposeAsync();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRangePicker.razor.css",
    "content": "﻿.daterangepicker {\n    position: fixed;\n    color: inherit;\n    background-color: #fff;\n    border-radius: 4px;\n    border: 1px solid #ddd;\n    width: 278px;\n    max-width: none;\n    padding: 0;\n    margin-top: 7px;\n    top: 0px;\n    left: 0px;\n    right: auto;\n    z-index: 3001;\n    font-family: arial;\n    font-size: 15px;\n    line-height: 1em;\n}\n\n    .daterangepicker:before, .daterangepicker:after {\n        position: absolute;\n        display: inline-block;\n        border-bottom-color: rgba(0, 0, 0, 0.2);\n        content: '';\n    }\n\n    .daterangepicker:before {\n        top: -7px;\n        border-right: 7px solid transparent;\n        border-left: 7px solid transparent;\n        border-bottom: 7px solid #ccc;\n    }\n\n    .daterangepicker:after {\n        top: -6px;\n        border-right: 6px solid transparent;\n        border-bottom: 6px solid #fff;\n        border-left: 6px solid transparent;\n    }\n\n    .daterangepicker.inline:before, .daterangepicker.inline:after {\n        content: none;\n    }\n\n    .daterangepicker.inline {\n        position: inherit;\n        display: inline-block;\n    }\n\n    .daterangepicker.opensleft:before {\n        right: 9px;\n    }\n\n    .daterangepicker.opensleft:after {\n        right: 10px;\n    }\n\n    .daterangepicker.openscenter:before {\n        left: 0;\n        right: 0;\n        width: 0;\n        margin-left: auto;\n        margin-right: auto;\n    }\n\n    .daterangepicker.openscenter:after {\n        left: 0;\n        right: 0;\n        width: 0;\n        margin-left: auto;\n        margin-right: auto;\n    }\n\n    .daterangepicker.opensright:before {\n        left: 9px;\n    }\n\n    .daterangepicker.opensright:after {\n        left: 10px;\n    }\n\n    .daterangepicker.drop-up {\n        margin-top: -7px;\n    }\n\n        .daterangepicker.drop-up:before {\n            top: initial;\n            bottom: -7px;\n            border-bottom: initial;\n            border-top: 7px solid #ccc;\n        }\n\n        .daterangepicker.drop-up:after {\n            top: initial;\n            bottom: -6px;\n            border-bottom: initial;\n            border-top: 6px solid #fff;\n        }\n\n    .daterangepicker.single .daterangepicker .ranges, .daterangepicker.single .drp-calendar {\n        float: none;\n    }\n\n    .daterangepicker.single .drp-selected {\n        display: none;\n    }\n\n    .daterangepicker.show-calendar .drp-calendar {\n        display: block;\n    }\n\n    .daterangepicker.show-calendar .drp-buttons {\n        display: block;\n    }\n\n    .daterangepicker.auto-apply .drp-buttons {\n        display: none;\n    }\n\n    .daterangepicker .drp-calendar {\n        display: none;\n        max-width: 270px;\n    }\n\n        .daterangepicker .drp-calendar.left {\n            padding: 8px 0 8px 8px;\n        }\n\n        .daterangepicker .drp-calendar.right {\n            padding: 8px;\n        }\n\n        .daterangepicker .drp-calendar.single .calendar-table {\n            border: none;\n        }\n\n    .daterangepicker .calendar-table {\n        border: 1px solid #fff;\n        border-radius: 4px;\n        background-color: #fff;\n    }\n\n    .daterangepicker .calendar-time {\n        text-align: center;\n        margin: 4px auto 0 auto;\n        line-height: 30px;\n        position: relative;\n    }\n\n    .daterangepicker .drp-buttons {\n        clear: both;\n        text-align: right;\n        padding: 8px;\n        border-top: 1px solid #ddd;\n        display: none;\n        line-height: 12px;\n        vertical-align: middle;\n    }\n\n    .daterangepicker .drp-selected {\n        display: inline-block;\n        font-size: 12px;\n        padding-right: 8px;\n    }\n\n    .daterangepicker .drp-buttons .btn {\n        margin-left: 8px;\n        font-size: 12px;\n        font-weight: bold;\n        padding: 4px 8px;\n    }\n\n    .daterangepicker.show-ranges.single.rtl .drp-calendar.left {\n        border-right: 1px solid #ddd;\n    }\n\n    .daterangepicker.show-ranges.single.ltr .drp-calendar.left {\n        border-left: 1px solid #ddd;\n    }\n\n    .daterangepicker.show-ranges.rtl .drp-calendar.right {\n        border-right: 1px solid #ddd;\n    }\n\n    .daterangepicker.show-ranges.ltr .drp-calendar.left {\n        border-left: 1px solid #ddd;\n    }\n\n    .daterangepicker .ranges {\n        float: none;\n        text-align: left;\n        margin: 0;\n    }\n\n    .daterangepicker.show-calendar .ranges {\n        margin-top: 8px;\n    }\n\n    .daterangepicker .ranges ul {\n        list-style: none;\n        margin: 0 auto;\n        padding: 0;\n        width: 100%;\n    }\n\n    .daterangepicker .ranges li {\n        font-size: 12px;\n        padding: 8px 12px;\n        cursor: pointer;\n    }\n\n        .daterangepicker .ranges li:hover {\n            background-color: #eee;\n        }\n\n        .daterangepicker .ranges li.active {\n            background-color: #08c;\n            color: #fff;\n        }\n\n.daterangepicker-visibility-hidden {\n    visibility: hidden;\n}\n\n.daterangepicker-visibility-visible {\n    visibility: visible;\n}\n\n/*  Larger Screen Styling */\n@media (min-width: 564px) {\n    .daterangepicker {\n        width: auto;\n    }\n\n        .daterangepicker .ranges ul {\n            width: 140px;\n        }\n\n        .daterangepicker.single .ranges ul {\n            width: 100%;\n        }\n\n        .daterangepicker.single .drp-calendar.left {\n            clear: none;\n        }\n\n        .daterangepicker.single .ranges, .daterangepicker.single .drp-calendar {\n            float: left;\n        }\n\n    .daterangepicker {\n        direction: ltr;\n        text-align: left;\n    }\n\n        .daterangepicker .drp-calendar.left {\n            clear: left;\n            margin-right: 0;\n        }\n\n            .daterangepicker .drp-calendar.left .calendar-table {\n                border-right: none;\n                border-top-right-radius: 0;\n                border-bottom-right-radius: 0;\n            }\n\n        .daterangepicker .drp-calendar.right {\n            margin-left: 0;\n        }\n\n            .daterangepicker .drp-calendar.right .calendar-table {\n                border-left: none;\n                border-top-left-radius: 0;\n                border-bottom-left-radius: 0;\n            }\n\n        .daterangepicker .drp-calendar.left .calendar-table {\n            padding-right: 8px;\n        }\n\n        .daterangepicker .ranges, .daterangepicker .drp-calendar {\n            float: left;\n        }\n}\n\n@media (min-width: 730px) {\n    .daterangepicker .ranges {\n        width: auto;\n    }\n\n    .daterangepicker .ranges {\n        float: left;\n    }\n\n    .daterangepicker.rtl .ranges {\n        float: right;\n    }\n\n    .daterangepicker .drp-calendar.left {\n        clear: none !important;\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRangePickerConfig.cs",
    "content": "﻿/**\n* @author: Sergey Zaikin zaikinsr@yandex.ru\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nnamespace BlazorDateRangePicker\n{\n    public partial class DateRangePickerConfig : IConfigurableOptions\n    {\n        public DateRangePickerConfig()\n        {\n            // Set default values\n            ButtonClasses = \"btn btn-sm\";\n            ApplyButtonClasses = \"btn-primary\";\n            CancelButtonClasses = \"btn-default\";\n            ApplyLabel = \"Apply\";\n            CancelLabel = \"Cancel\";\n            CustomRangeLabel = \"Custom Range\";\n            WeekAbbreviation = string.Empty;\n\n            ShowDropdowns = true;\n            ShowCustomRangeLabel = true;\n            Inline = false;\n            CloseOnOutsideClick = true;\n            AutoAdjustCalendars = true;\n            ResetOnClear = true;\n            TimePicker = false;\n            TimePickerSeconds = false;\n            Prerender = true;\n            TimePickerIncrement = 1;\n\n            Culture = System.Globalization.CultureInfo.CurrentCulture;\n            Opens = SideType.Right;\n            Drops = DropsType.Down;\n\n            CustomDateFunction = _ => false;\n        }\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/DateRangePickerExtensions.cs",
    "content": "﻿/**\n* @author: Sergey Zaikin zaikinsr@yandex.ru\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nusing System;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace BlazorDateRangePicker\n{\n    public static class DateRangePickerExtensions\n    {\n        /// <summary>\n        /// Adds a singleton <see cref=\"DateRangePickerConfig\"/> instance to the DI\n        /// </summary>\n        public static IServiceCollection AddDateRangePicker(this IServiceCollection services,\n            DateRangePickerConfig configuration,\n            string configName = null)\n        {\n            ArgumentNullException.ThrowIfNull(configuration);\n\n            configuration.Name = configName;\n            services.AddSingleton(configuration);\n            return services;\n        }\n\n        /// <summary>\n        /// Adds a singleton <see cref=\"DateRangePickerConfig\"/> instance to the DI\n        /// </summary>\n        public static IServiceCollection AddDateRangePicker(this IServiceCollection services,\n            Action<DateRangePickerConfig> configure,\n            string configName = null)\n        {\n            ArgumentNullException.ThrowIfNull(configure);\n\n            var options = new DateRangePickerConfig();\n            configure(options);\n\n            return AddDateRangePicker(services, options, configName);\n        }\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/Enums.cs",
    "content": "﻿/**\n* author: Sergey Zaikin zaikinsr@yandex.ru\n* copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nnamespace BlazorDateRangePicker\n{\n    public enum SideType\n    {\n        Right,\n        Left,\n        Center\n    }\n\n    public enum DropsType\n    {\n        Down,\n        Up\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/IConfigurableOptions.cs",
    "content": "﻿/**\n* @author: Sergey Zaikin zaikinsr@yandex.ru\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Threading.Tasks;\nusing static BlazorDateRangePicker.DateRangePicker;\n\nnamespace BlazorDateRangePicker\n{\n    internal interface IConfigurableOptions\n    {\n        /// <summary>\n        /// Unique name of the configuration\n        /// </summary>\n        public string Name { get; set; }\n\n        /// <summary>\n        /// All unmatched parameters will be passed to parent element\n        /// </summary>\n        public Dictionary<string, object> Attributes { get; set; }\n\n        /// <summary>\n        /// Set predefined date ranges the user can select from. Each RangeItem.Name is the label for the range, and its Start and End value representing the bounds of the range.\n        /// </summary>\n        public Dictionary<string, DateRange> Ranges { get; set; }\n\n        /// <summary>\n        /// Hide the apply and cancel buttons, and automatically apply a new date range as soon as two dates are clicked.\n        /// </summary>\n        public bool? AutoApply { get; set; }\n\n        /// <summary>\n        /// Show only a single calendar to choose one date, instead of a range picker with two calendars. The start and end dates provided to your callback will be the same single date chosen. \n        /// </summary>\n        public bool? SingleDatePicker { get; set; }\n\n        /// <summary>\n        /// Show only one calendar in the picker instead of two calendars.\n        /// </summary>\n        public bool? ShowOnlyOneCalendar { get; set; }\n\n        /// <summary>\n        /// Normally, if you use the ranges option to specify pre-defined date ranges, calendars for choosing a custom date range are not shown until the user clicks \"Custom Range\". When this option is set to true, the calendars for choosing a custom date range are always shown instead. \n        /// </summary>\n        public bool? AlwaysShowCalendars { get; set; }\n\n        /// <summary>\n        /// CSS class names that will be added to both the apply and cancel buttons.\n        /// </summary>\n        public string ButtonClasses { get; set; }\n\n        /// <summary>\n        /// CSS class names that will be added only to the apply button. \n        /// </summary>\n        public string ApplyButtonClasses { get; set; }\n\n        /// <summary>\n        /// CSS class names that will be added only to the cancel button. \n        /// </summary>\n        public string CancelButtonClasses { get; set; }\n\n        public string ApplyLabel { get; set; }\n\n        public string CancelLabel { get; set; }\n\n        public string CustomRangeLabel { get; set; }\n\n        /// <summary>\n        /// The beginning date of the initially selected date range.\n        /// </summary>\n        public DateTimeOffset? StartDate { get; set; }\n\n        /// <summary>\n        /// The end date of the initially selected date range\n        /// </summary>\n        public DateTimeOffset? EndDate { get; set; }\n\n        /// <summary>\n        /// Specify the format string to display dates, default is Culture.DateTimeFormat.ShortDatePattern\n        /// </summary>\n        public string DateFormat { get; set; }\n\n        /// <summary>\n        /// Show localized week numbers at the start of each week on the calendars.\n        /// </summary>\n        public bool? ShowWeekNumbers { get; set; }\n\n        /// <summary>\n        /// Show ISO week numbers at the start of each week on the calendars.\n        /// </summary>\n        public bool? ShowISOWeekNumbers { get; set; }\n\n        /// <summary>\n        /// When enabled, the two calendars displayed will always be for two sequential months (i.e. January and February), and both will be advanced when clicking the left or right arrows above the calendars. When disabled, the two calendars can be individually advanced and display any month/year.\n        /// </summary>\n        public bool? LinkedCalendars { get; set; }\n\n        /// <summary>\n        /// Show year and month select boxes above calendars to jump to a specific month and year.\n        /// </summary>\n        public bool? ShowDropdowns { get; set; }\n\n        /// <summary>\n        /// Displays \"Custom Range\" at the end of the list of predefined ranges, when the ranges option is used. This option will be highlighted whenever the current date range selection does not match one of the predefined ranges. Clicking it will display the calendars to select a new range.\n        /// </summary>\n        public bool? ShowCustomRangeLabel { get; set; }\n\n        /// <summary>\n        /// Inline mode\n        /// </summary>\n        public bool? Inline { get; set; }\n\n        /// <summary>\n        /// Whether the picker should close on outside click\n        /// </summary>\n        public bool? CloseOnOutsideClick { get; set; }\n\n        /// <summary>\n        /// Whether the picker should pick months based on selected range\n        /// </summary>\n        public bool? AutoAdjustCalendars { get; set; }\n\n        /// <summary> Specify the culture to display dates and text in. Default is CultureInfo.CurrentCulture.</summary>\n        public CultureInfo Culture { get; set; }\n\n        /// <summary>The text to display on the Week number heading</summary>\n        public string WeekAbbreviation { get; set; }\n\n        /// <summary>The day of the week to start from</summary>\n        public DayOfWeek? FirstDayOfWeek { get; set; }\n\n        /// <summary>The earliest date that can be selected, inclusive. A value of null indicates that there is no minimum date.</summary>\n        public DateTimeOffset? MinDate { get; set; }\n\n        /// <summary>The latest date that can be selected, inclusive. A value of null indicates that there is no maximum date.</summary>\n        public DateTimeOffset? MaxDate { get; set; }\n\n        /// <summary>\n        /// The maximum TimeSpan between the selected start and end dates. A value of null indicates that there is no limit.\n        /// </summary>\n        public TimeSpan? MaxSpan { get; set; }\n\n        /// <summary>\n        /// The minimum TimeSpan between the selected start and end dates. A value of null indicates that there is no limit.\n        /// </summary>\n        public TimeSpan? MinSpan { get; set; }\n\n        /// <summary>\n        /// Whether the picker appears aligned to the left, to the right, or centered under the HTML element it's attached to.\n        /// </summary>\n        public SideType? Opens { get; set; }\n\n        /// <summary>\n        /// Whether the picker appears below (default) or above the HTML element it's attached to.\n        /// </summary>\n        public DropsType? Drops { get; set; }\n\n        /// <summary>\n        /// A function that is passed each date in the two calendars before they are displayed, and may return true or false to indicate whether that date should be available for selection or not. \n        /// </summary>\n        public Func<DateTimeOffset, bool> DaysEnabledFunction { get; set; }\n\n        /// <summary>\n        /// A function that is passed each date in the two calendars before they are displayed, and may return true or false to indicate whether that date should be available for selection or not. \n        /// </summary>\n        public Func<DateTimeOffset, Task<bool>> DaysEnabledFunctionAsync { get; set; }\n\n        /// <summary>\n        /// String of CSS class name to apply to calendar cell when <seealso cref=\"CustomDateFunction\"/> returns true\n        /// </summary>\n        public string CustomDateClass { get; set; }\n\n        /// <summary>\n        /// A function to which each date from the calendars is passed before they are displayed, \n        /// may return a bool value indicates whether <seealso cref=\"CustomDateClass\"/> will be added to the cell, \n        /// or a string with CSS class name to add to that date's calendar cell.\n        /// </summary>\n        public Func<DateTimeOffset, object> CustomDateFunction { get; set; }\n\n        /// <summary>\n        /// Whether the picker should set dates to null when the user cleans the input\n        /// </summary>\n        public bool? ResetOnClear { get; set; }\n\n        /// <summary>\n        /// Adds select boxes to choose times in addition to dates.\n        /// </summary>\n        public bool? TimePicker { get; set; }\n\n        /// <summary>\n        /// Use 24-hour instead of 12-hour times, removing the AM/PM selection.\n        /// </summary>\n        public bool? TimePicker24Hour { get; set; }\n\n        /// <summary>\n        /// Increment of the minutes selection list for times (i.e. 30 to allow only selection of times ending in 0 or 30).\n        /// </summary>\n        public int? TimePickerIncrement { get; set; }\n\n        /// <summary>\n        /// Show seconds in the timePicker.\n        /// </summary>\n        public bool? TimePickerSeconds { get; set; }\n\n        /// <summary>\n        /// Initial time value to show in the picker before any date selected\n        /// </summary>\n        public TimeSpan? InitialStartTime { get; set; }\n\n        /// <summary>\n        /// Initial time value to show in the picker before any date selected\n        /// </summary>\n        public TimeSpan? InitialEndTime { get; set; }\n\n        /// <summary>\n        /// Prerender component html before picker opening.\n        /// </summary>\n        public bool? Prerender { get; set; }\n\n        /// <summary>List of day names to be displayed instead of those defined in the Culture</summary>\n        public List<string> CustomDayNames { get; set; }\n\n        /// <summary>Custom date parsing function</summary>\n        public DateParsingDelegate CustomParseFunction { get; set; }\n\n        /// <summary>\n        /// Returns time available for selection. \n        /// </summary>\n        public Func<DateTimeOffset?, Task<TimeSettings>> TimeEnabledFunction { get; set; }\n    }\n}"
  },
  {
    "path": "BlazorDateRangePicker/PickerContainer.razor",
    "content": "﻿@Content\n\n@code{\n    RenderFragment Content { get; set; }\n\n    public void SetContent(RenderFragment content)\n    {\n        Content = content;\n        StateHasChanged();\n    }\n}"
  },
  {
    "path": "BlazorDateRangePicker/TimePicker.razor",
    "content": "﻿<select class=\"hourselect\" @bind=\"Hour\">\n    @foreach (var hour in HoursRange)\n    {\n        <option value=\"@hour\" selected=\"@(Hour == hour)\">@hour.ToString().PadLeft(2, '0')</option>\n    }\n</select>\n<span> : </span>\n<select class=\"minuteselect\" @bind=\"Minute\">\n    @foreach (var minute in MinutesRange)\n    {\n        if (minute % Picker.TimePickerIncrement != 0) continue;\n        <option value=\"@minute\" selected=\"@(Minute == minute)\">@minute.ToString().PadLeft(2, '0')</option>\n    }\n</select>\n\n@if (Picker.TimePickerSeconds == true)\n{\n    <span> : </span>\n    <select class=\"minuteselect\" @bind=\"Second\">\n        @foreach (var sec in SecondsRange)\n        {\n            <option value=\"@sec\" selected=\"@(Second == sec)\">@sec.ToString().PadLeft(2, '0')</option>\n        }\n    </select>\n}\n\n@if (Picker.TimePicker24Hour == false)\n{\n    <span>&nbsp;</span>\n    <select class=\"ampmselect\" @bind=\"AmPm\">\n        <option value=\"@(AmPmEnum.AM)\">AM</option>\n        <option value=\"@(AmPmEnum.PM)\">PM</option>\n    </select>\n}"
  },
  {
    "path": "BlazorDateRangePicker/TimePicker.razor.cs",
    "content": "﻿/**\r\n* @author: Sergey Zaikin zaikinsr@yandex.ru\r\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\r\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\r\n*/\r\n\r\nusing System;\r\nusing System.Linq;\r\nusing System.Collections.Generic;\r\nusing Microsoft.AspNetCore.Components;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace BlazorDateRangePicker\r\n{\r\n    public partial class TimePicker\r\n    {\r\n        [CascadingParameter] public DateRangePicker Picker { get; set; }\r\n        [Parameter] public SideType Side { get; set; }\r\n        [Parameter] public TimeSpan Time { get; set; }\r\n        [Parameter] public EventCallback<TimeSpan> TimeChanged { get; set; }\r\n        [Parameter] public DateTimeOffset? Day { get; set; }\r\n        [Parameter] public bool? TimePicker24Hour { get; set; }\r\n\r\n        private readonly IEnumerable<int> HoursRange24 = Enumerable.Range(0, 24);\r\n        private readonly IEnumerable<int> HoursRange12 = Enumerable.Range(1, 12);\r\n        private IEnumerable<int> CustomHoursRange;\r\n\r\n        protected override void OnInitialized()\r\n        {\r\n            MinutesRange = Enumerable.Range(0, 60);\r\n            SecondsRange = Enumerable.Range(0, 60);\r\n        }\r\n\r\n        protected override async Task OnParametersSetAsync()\r\n        {\r\n            if (Picker.TimeEnabledFunction != null)\r\n            {\r\n                var timeEnabled = await Picker.TimeEnabledFunction(Day);\r\n                CustomHoursRange = timeEnabled.Hours;\r\n                MinutesRange = timeEnabled.Minutes;\r\n                SecondsRange = timeEnabled.Seconds;\r\n            }\r\n            else\r\n            {\r\n                CustomHoursRange = null;\r\n                MinutesRange = Enumerable.Range(0, 60);\r\n                SecondsRange = Enumerable.Range(0, 60);\r\n            }\r\n        }\r\n\r\n        private IEnumerable<int> HoursRange => CustomHoursRange ?? (TimePicker24Hour != false ? HoursRange24 : HoursRange12);\r\n        private IEnumerable<int> MinutesRange { get; set; }\r\n        private IEnumerable<int> SecondsRange { get; set; }\r\n\r\n        private AmPmEnum AmPm\r\n        {\r\n            get => Time.Hours >= 12 ? AmPmEnum.PM : AmPmEnum.AM;\r\n            set\r\n            {\r\n                Set(h: value switch\r\n                {\r\n                    AmPmEnum.AM when Time.Hours >= 12 => Time.Hours - 12,\r\n                    AmPmEnum.PM when Time.Hours < 12 => Time.Hours + 12,\r\n                    _ => Time.Hours\r\n                });\r\n            }\r\n        }\r\n\r\n        private int Hour\r\n        {\r\n            get\r\n            {\r\n                if (Picker.TimePicker24Hour == true) return Time.Hours;\r\n                return int.Parse(DateTime.Today.Add(Time).ToString(\"hh\"));\r\n            }\r\n            set\r\n            {\r\n                Set(h: AmPm switch\r\n                {\r\n                    AmPmEnum.AM when TimePicker24Hour == false && value >= 12 => value - 12,\r\n                    AmPmEnum.PM when TimePicker24Hour == false && value < 12 => value + 12,\r\n                    _ => value\r\n                });\r\n            }\r\n        }\r\n\r\n        private int Minute { get => Time.Minutes; set => Set(m: value); }\r\n        private int Second { get => Time.Seconds; set => Set(s: value); }\r\n\r\n        private void Set(int? h = null, int? m = null, int? s = null)\r\n        {\r\n            Time = TimeSpan.FromHours(h ?? Time.Hours)\r\n                 + TimeSpan.FromMinutes(m ?? Minute)\r\n                 + TimeSpan.FromSeconds(s ?? Second);\r\n\r\n            TimeChanged.InvokeAsync(Time);\r\n        }\r\n    }\r\n\r\n    public enum AmPmEnum\r\n    {\r\n        AM, PM\r\n    }\r\n}"
  },
  {
    "path": "BlazorDateRangePicker/TimePicker.razor.css",
    "content": "﻿select.hourselect, select.minuteselect, select.secondselect, select.ampmselect {\n    width: 50px;\n    margin: 0 auto;\n    background: #eee;\n    border: 1px solid #eee;\n    padding: 2px;\n    outline: 0;\n    font-size: 12px;\n}\n\nselect.disabled {\n    color: #ccc;\n    cursor: not-allowed;\n}"
  },
  {
    "path": "BlazorDateRangePicker/TimeSettings.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace BlazorDateRangePicker\n{\n    public class TimeSettings\n    {\n        public IEnumerable<int> Hours { get; set; }\n        public IEnumerable<int> Minutes { get; set; }\n        public IEnumerable<int> Seconds { get; set; }\n    }\n}\n"
  },
  {
    "path": "BlazorDateRangePicker/_Imports.razor",
    "content": "﻿@using Microsoft.AspNetCore.Components\n@using Microsoft.AspNetCore.Components.Web"
  },
  {
    "path": "BlazorDateRangePicker/wwwroot/clickAndPositionHandler.js",
    "content": "/**\n* @author: Sergey Zaikin zaikinsr@yandex.ru\n* @copyright: Copyright (c) 2019 Sergey Zaikin. All rights reserved.\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n*/\nvar clickAndPositionHandler = {\n    listeners: []\n};\n\nexport function addClickOutsideEvent(elementId, parentId, dotnetHelper) {\n    if (clickAndPositionHandler.listeners.indexOf(elementId) > -1) return;\n    window.addEventListener(\"click\", function (e) {\n        if ((document.getElementById(elementId) != null && !document.getElementById(elementId).contains(e.target)) &&\n            (document.getElementById(parentId) != null && !document.getElementById(parentId).contains(e.target)) &&\n            (document.getElementById(elementId).parentElement == null ||\n                document.getElementById(elementId).parentElement.style == null ||\n                window.getComputedStyle(document.getElementById(elementId).parentElement).visibility == \"visible\")) {\n            dotnetHelper.invokeMethodAsync(\"InvokeClickOutside\");\n        }\n    });\n    clickAndPositionHandler.listeners.push(elementId);\n};\n\nexport function getPickerPosition(elementId, parentId, drops, opens, skipAddListener) {\n    var resizeFunction = function () {\n        getPickerPosition(elementId, parentId, drops, opens, true);\n    };\n    var parentOffset = { top: 0, left: 0 },\n        containerTop;\n    var parentRightEdge = window.innerWidth;\n    var container = document.getElementById(elementId);\n    var parentEl = document.getElementById(parentId);\n    var element = parentEl;\n    if (element == null || container == null) {\n        window.removeEventListener('resize', resizeFunction, true);\n        window.removeEventListener('onwheel', resizeFunction, true);\n        window.removeEventListener('onmousewheel', resizeFunction, true);\n        window.removeEventListener('scroll', resizeFunction, true);\n        return;\n    }\n\n    if (parentEl === document.body) {\n        var rect = parentEl.getBoundingClientRect();\n        parentOffset = {\n            top: rect.top,\n            left: rect.left\n        };\n\n        parentRightEdge = parentEl[0].clientWidth + rect.left;\n    }\n\n    var elementRect = element.getBoundingClientRect();\n\n    var outerHeight = function (el) {\n        return el.offsetHeight;\n    }\n\n    var outerWidth = function (el) {\n        return el.offsetWidth;\n    }\n\n    var setStylesOnElement = function (styles, element) {\n        for (var prop in styles) {\n            element.style[prop] = styles[prop];\n        }\n    }\n\n    if (drops == 'up')\n        containerTop = elementRect.top - outerHeight(container) - parentOffset.top;\n    else\n        containerTop = elementRect.top + outerHeight(element) - parentOffset.top;\n\n    var containerWidth = outerWidth(container);\n\n    if (opens == 'left') {\n        var containerRight = parentRightEdge - elementRect.left - outerWidth(element);\n        if (containerWidth + containerRight > window.innerWidth) {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                right: 'auto',\n                left: 9 + 'px'\n            }, container);\n        } else {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                right: containerRight + 'px',\n                left: 'auto'\n            }, container);\n        }\n    } else if (opens == 'center') {\n        var containerLeft = elementRect.left - parentOffset.left + outerWidth(element) / 2 - containerWidth / 2;\n        if (containerLeft < 0) {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                right: 'auto',\n                left: 9 + 'px'\n            }, container);\n        } else if (containerLeft + containerWidth > window.innerWidth) {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                left: 'auto',\n                right: 0 + 'px'\n            }, container);\n        } else {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                left: containerLeft + 'px',\n                right: 'auto'\n            }, container);\n        }\n    } else {\n        var containerLeft = elementRect.left - parentOffset.left;\n        if (containerLeft + containerWidth > window.innerWidth) {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                left: 'auto',\n                right: 0 + 'px'\n            }, container);\n        } else {\n            setStylesOnElement({\n                position: 'fixed',\n                top: containerTop + 'px',\n                left: containerLeft + 'px',\n                right: 'auto'\n            }, container);\n        }\n    }\n\n    if (skipAddListener !== true) {\n        window.addEventListener('resize', resizeFunction, true);\n        window.addEventListener('onwheel', resizeFunction, true);\n        window.addEventListener('onmousewheel', resizeFunction, true);\n        window.addEventListener('scroll', resizeFunction, true);\n    };\n}\n"
  },
  {
    "path": "BlazorDateRangePicker.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.13.35716.79\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"BlazorDateRangePicker\", \"BlazorDateRangePicker\\BlazorDateRangePicker.csproj\", \"{C463A3EB-E515-46C2-B520-18E964A69E32}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Demo.ClientSideApp\", \"Demo.ClientSideApp\\Demo.ClientSideApp.csproj\", \"{901603F4-C51B-4B98-9E98-F85DAE6E8A2F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Demo.ServerSideApp\", \"Demo.ServerSideApp\\Demo.ServerSideApp.csproj\", \"{94594133-2735-40F5-B336-9019A60E873D}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Demo.Shared\", \"Demo.Shared\\Demo.Shared.csproj\", \"{C643FA35-336A-4620-9153-8D4A3DBFE92C}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SourceGenerators\", \"SourceGenerators\\SourceGenerators.csproj\", \"{2655151C-2184-C7B9-CAB3-727E2FA0BBFC}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C463A3EB-E515-46C2-B520-18E964A69E32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C463A3EB-E515-46C2-B520-18E964A69E32}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C463A3EB-E515-46C2-B520-18E964A69E32}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C463A3EB-E515-46C2-B520-18E964A69E32}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{901603F4-C51B-4B98-9E98-F85DAE6E8A2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{901603F4-C51B-4B98-9E98-F85DAE6E8A2F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{901603F4-C51B-4B98-9E98-F85DAE6E8A2F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{901603F4-C51B-4B98-9E98-F85DAE6E8A2F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{94594133-2735-40F5-B336-9019A60E873D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{94594133-2735-40F5-B336-9019A60E873D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{94594133-2735-40F5-B336-9019A60E873D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{94594133-2735-40F5-B336-9019A60E873D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C643FA35-336A-4620-9153-8D4A3DBFE92C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C643FA35-336A-4620-9153-8D4A3DBFE92C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C643FA35-336A-4620-9153-8D4A3DBFE92C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C643FA35-336A-4620-9153-8D4A3DBFE92C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2655151C-2184-C7B9-CAB3-727E2FA0BBFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2655151C-2184-C7B9-CAB3-727E2FA0BBFC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2655151C-2184-C7B9-CAB3-727E2FA0BBFC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2655151C-2184-C7B9-CAB3-727E2FA0BBFC}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {D897D349-9D43-44E6-A9F8-8D10BBA2DBFD}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Demo.ClientSideApp/App.razor",
    "content": "﻿<Router AppAssembly=\"typeof(Program).Assembly\" AdditionalAssemblies=\"new[] { typeof(CustomDate).Assembly }\">\n    <Found Context=\"routeData\">\n        <RouteView RouteData=\"routeData\" DefaultLayout=\"typeof(MainLayout)\" />\n    </Found>\n    <NotFound>\n        <LayoutView Layout=\"typeof(MainLayout)\">\n            <h1>Page not found</h1>\n            <p>Sorry, but there's nothing here!</p>\n        </LayoutView>\n    </NotFound>\n</Router>\n"
  },
  {
    "path": "Demo.ClientSideApp/Demo.ClientSideApp.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.BlazorWebAssembly\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net9</TargetFramework>\r\n    <UseBlazorWebAssembly>true</UseBlazorWebAssembly>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.WebAssembly\" Version=\"9.0.1\" />\r\n    <PackageReference Include=\"Microsoft.AspNetCore.Components.WebAssembly.DevServer\" Version=\"9.0.1\" PrivateAssets=\"all\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\BlazorDateRangePicker\\BlazorDateRangePicker.csproj\" />\r\n    <ProjectReference Include=\"..\\Demo.Shared\\Demo.Shared.csproj\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "Demo.ClientSideApp/Program.cs",
    "content": "﻿using BlazorDateRangePicker;\nusing Demo.ClientSideApp;\nusing Microsoft.AspNetCore.Components.WebAssembly.Hosting;\nusing Microsoft.Extensions.DependencyInjection;\nusing System.Collections.Generic;\n\nvar builder = WebAssemblyHostBuilder.CreateDefault(args);\nbuilder.RootComponents.Add<App>(\"app\");\n\nbuilder.Services.AddScoped<Demo.Shared.IClipboard, Demo.Shared.BlazorClipboard>();\n\nbuilder.Services.AddDateRangePicker(config =>\n{\n    config.Attributes = new Dictionary<string, object>\n    {\n        { \"class\", \"form-control form-control-sm\" }\n    };\n});\n\nawait builder.Build().RunAsync();\n"
  },
  {
    "path": "Demo.ClientSideApp/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:51104/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"Demo.ClientSideApp\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:5110/\"\n    }\n  }\n}"
  },
  {
    "path": "Demo.ClientSideApp/_Imports.razor",
    "content": "@using System.Net.Http\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.JSInterop\n@using Demo.ClientSideApp\n@using Demo.Shared.Shared\n@using Demo.Shared.Pages\n@using BlazorDateRangePicker"
  },
  {
    "path": "Demo.ClientSideApp/wwwroot/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width\" />\n    <title>BlazorDateRangePicker</title>\n    <base href=\"/\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/bootstrap/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/bootstrap/docs.min.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/highlight/vs.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/site.css\" />\n    <link rel=\"stylesheet\" href=\"Demo.ClientSideApp.styles.css\" />\n</head>\n<body>\n    <app>\n        <style>\n            body {\n                background: #eff3f8;\n            }\n\n            .preloader {\n                margin: 200px auto;\n            }\n\n                .preloader img {\n                    display: block;\n                    margin-left: auto;\n                    margin-right: auto;\n                }\n\n            h1 {\n                color: #FFF;\n                font-size: 16px;\n                letter-spacing: 1px;\n                font-weight: 200;\n                text-align: center;\n            }\n\n            .loader span {\n                width: 16px;\n                height: 16px;\n                border-radius: 50% !important;\n                display: inline-block;\n                position: absolute;\n                left: 50%;\n                margin-left: -10px;\n                animation: 3s infinite linear;\n                -webkit-animation: 3s infinite linear;\n                -moz-animation: 3s infinite linear;\n                -o-animation: 3s infinite linear;\n            }\n\n\n                .loader span:nth-child(2) {\n                    background: #E84C3D;\n                    animation: kiri 1.2s infinite linear;\n                    -webkit-animation: kiri 1.2s infinite linear;\n                    -moz-animation: kiri 1.2s infinite linear;\n                    -o-animation: kiri 1.2s infinite linear;\n                }\n\n                .loader span:nth-child(3) {\n                    background: #F1C40F;\n                    z-index: 100;\n                }\n\n                .loader span:nth-child(4) {\n                    background: #2FCC71;\n                    animation: kanan 1.2s infinite linear;\n                    -webkit-animation: kanan 1.2s infinite linear;\n                    -moz-animation: kanan 1.2s infinite linear;\n                    -o-animation: kanan 1.2s infinite linear;\n                }\n\n            @keyframes kanan {\n                0% {\n                    -webkit-transform: translateX(20px);\n                }\n\n                50% {\n                    -webkit-transform: translateX(-20px);\n                }\n\n                100% {\n                    -webkit-transform: translateX(20px);\n                }\n            }\n\n            @-webkit-keyframes kanan {\n                0% {\n                    -webkit-transform: translateX(20px);\n                }\n\n                50% {\n                    -webkit-transform: translateX(-20px);\n                }\n\n                100% {\n                    -webkit-transform: translateX(20px);\n                }\n            }\n\n            @-moz-keyframes kanan {\n                0% {\n                    -moz-transform: translateX(20px);\n                }\n\n                50% {\n                    -moz-transform: translateX(-20px);\n                }\n\n                100% {\n                    -moz-transform: translateX(20px);\n                    z-index: 200;\n                }\n            }\n\n            @-o-keyframes kanan {\n                0% {\n                    -o-transform: translateX(20px);\n                }\n\n                50% {\n                    -o-transform: translateX(-20px);\n                }\n\n                100% {\n                    -o-transform: translateX(20px);\n                    z-index: 200;\n                }\n            }\n\n            @keyframes kiri {\n                0% {\n                    -webkit-transform: translateX(-20px);\n                }\n\n                50% {\n                    -webkit-transform: translateX(20px);\n                }\n\n                100% {\n                    -webkit-transform: translateX(-20px);\n                }\n            }\n\n            @-webkit-keyframes kiri {\n                0% {\n                    -webkit-transform: translateX(-20px);\n                }\n\n                50% {\n                    -webkit-transform: translateX(20px);\n                }\n\n                100% {\n                    -webkit-transform: translateX(-20px);\n                }\n            }\n\n            @-moz-keyframes kiri {\n                0% {\n                    -moz-transform: translateX(-20px);\n                    z-index: 200;\n                }\n\n                50% {\n                    -moz-transform: translateX(20px);\n                }\n\n                100% {\n                    -moz-transform: translateX(-20px);\n                }\n            }\n\n            @-o-keyframes kiri {\n                0% {\n                    -o-transform: translateX(-20px);\n                    z-index: 200;\n                }\n\n                50% {\n                    -o-transform: translateX(20px);\n                }\n\n                100% {\n                    -o-transform: translateX(-20px);\n                }\n            }\n        </style>\n        <div class=\"preloader\">\n            <blockquote class=\"blockquote text-center\">\n                <p>Loading WebAssembly application...</p>\n            </blockquote>\n            <div class=\"loader\">\n                <h1></h1>\n                <span></span>\n                <span></span>\n                <span></span>\n            </div>\n        </div>\n    </app>\n    <script src=\"_framework/blazor.webassembly.js\" integrity=\"\"></script>\n    <script src=\"_content/Demo.Shared/highlight/highlight.pack.js\"></script>\n    <script src=\"_content/Demo.Shared/highlight/cshtml-razor.js\"></script>\n    <script src=\"_content/Demo.Shared/highlight/highlightInterop.js\"></script>\n    <script>\n        hljs.registerLanguage('cshtml-razor', window.hljsDefineCshtmlRazor);\n        hljs.initHighlightingOnLoad();\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "Demo.ServerSideApp/App.razor",
    "content": "﻿<Router AppAssembly=\"typeof(Program).Assembly\" AdditionalAssemblies=\"new[] { typeof(CustomDate).Assembly }\">\n    <Found Context=\"routeData\">\n        <RouteView RouteData=\"routeData\" DefaultLayout=\"typeof(MainLayout)\" />\n    </Found>\n    <NotFound>\n        <LayoutView Layout=\"typeof(MainLayout)\">\n            <h1>Page not found</h1>\n            <p>Sorry, but there's nothing here!</p>\n        </LayoutView>\n    </NotFound>\n</Router>\n"
  },
  {
    "path": "Demo.ServerSideApp/Demo.ServerSideApp.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net9</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BlazorDateRangePicker\\BlazorDateRangePicker.csproj\" />\n    <ProjectReference Include=\"..\\Demo.Shared\\Demo.Shared.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Demo.ServerSideApp/Pages/_Host.cshtml",
    "content": "﻿@page \"/\"\n@namespace Demo.ServerSideApp.Pages\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>BlazorDateRangePicker</title>\n    <base href=\"~/\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/bootstrap/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/bootstrap/docs.min.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/highlight/vs.css\" />\n    <link rel=\"stylesheet\" href=\"_content/Demo.Shared/css/site.css\" />\n    <link rel=\"stylesheet\" href=\"Demo.ServerSideApp.styles.css\" />\n</head>\n<body>\n    <component type=\"typeof(App)\" render-mode=\"Server\" />\n\n    <script src=\"_framework/blazor.server.js\"></script>\n    <script src=\"_content/Demo.Shared/highlight/highlight.pack.js\"></script>\n    <script src=\"_content/Demo.Shared/highlight/cshtml-razor.js\"></script>\n    <script src=\"_content/Demo.Shared/highlight/highlightInterop.js\"></script>\n    <script>\n        hljs.registerLanguage('cshtml-razor', window.hljsDefineCshtmlRazor);\n        hljs.initHighlightingOnLoad();\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "Demo.ServerSideApp/Program.cs",
    "content": "using BlazorDateRangePicker;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing System.Collections.Generic;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddRazorPages();\nbuilder.Services.AddServerSideBlazor();\nbuilder.Services.AddScoped<Demo.Shared.IClipboard, Demo.Shared.BlazorClipboard>();\n\nbuilder.Services.AddDateRangePicker(config =>\n{\n    config.Attributes = new Dictionary<string, object>\n    {\n        { \"class\", \"form-control form-control-sm\" }\n    };\n});\n\nvar app = builder.Build();\n\nif (app.Environment.IsDevelopment())\n{\n    app.UseDeveloperExceptionPage();\n}\nelse\n{\n    app.UseExceptionHandler(\"/Home/Error\");\n    app.UseHsts();\n}\n\napp.UseHttpsRedirection();\napp.UseStaticFiles();\n\napp.UseRouting();\n\napp.MapBlazorHub();\napp.MapFallbackToPage(\"/_Host\");\n\napp.Run();\n"
  },
  {
    "path": "Demo.ServerSideApp/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:3888\",\n      \"sslPort\": 44313\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"Demo.ServerSideApp\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001;http://localhost:5000\"\n    }\n  }\n}"
  },
  {
    "path": "Demo.ServerSideApp/_Imports.razor",
    "content": "﻿@using System.Net.Http\n@using Microsoft.AspNetCore.Authorization\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.JSInterop\n@using Demo.Shared\n@using Demo.Shared.Shared\n@using Demo.Shared.Pages\n@using Demo.ServerSideApp\n@using BlazorDateRangePicker"
  },
  {
    "path": "Demo.ServerSideApp/appsettings.Development.json",
    "content": "{\n  \"DetailedErrors\": true,\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "Demo.ServerSideApp/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "Demo.Shared/BlazorClipboard.cs",
    "content": "﻿using Microsoft.JSInterop;\nusing System.Threading;\nusing System.Threading.Tasks;\n\n#nullable enable\n\nnamespace Demo.Shared\n{\n    /// <summary>\n    /// Provides methods to place text on and retrieve text from the system Clipboard.\n    /// </summary>\n    public interface IClipboard\n    {\n        /// <summary>\n        /// Retrieves text data from the Clipboard.\n        /// </summary>\n        public Task<string?> GetTextAsync(CancellationToken cancellation = default);\n\n        /// <summary>\n        /// Retrieves text data from the Clipboard.\n        /// </summary>\n        public string? GetText();\n\n        /// <summary>\n        /// Clears the Clipboard and then adds text data to it.\n        /// </summary>\n        public Task SetTextAsync(string text, CancellationToken cancellation = default);\n\n        /// <summary>\n        /// Clears the Clipboard and then adds text data to it.\n        /// </summary>\n        public void SetText(string text);\n    }\n\n    /// <summary>\n    /// Construct a new instance.\n    /// </summary>\n    public class BlazorClipboard(IJSRuntime jsRuntime) : IClipboard\n    {\n        protected readonly IJSRuntime jsRuntime = jsRuntime;\n\n        /// <inheritdoc />\n        public virtual async Task<string?> GetTextAsync(CancellationToken cancellation = default)\n        {\n            return await jsRuntime.InvokeAsync<string>(\"navigator.clipboard.readText\", cancellation, []);\n        }\n\n        /// <inheritdoc />\n        public virtual string? GetText()\n        {\n            return GetTextAsync().GetAwaiter().GetResult();\n        }\n\n        /// <inheritdoc />\n        public virtual async Task SetTextAsync(string text, CancellationToken cancellation = default)\n        {\n            await jsRuntime.InvokeAsync<string>(\"navigator.clipboard.writeText\", cancellation, [text]);\n        }\n\n        /// <inheritdoc />\n        public virtual void SetText(string text)\n        {\n            SetTextAsync(text).GetAwaiter().GetResult();\n        }\n    }\n}\n\n#nullable disable"
  },
  {
    "path": "Demo.Shared/Demo.Shared.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Razor\">\n\n\t<PropertyGroup>\n\t\t<TargetFramework>net9</TargetFramework>\n\t\t<AddRazorSupportForMvc>true</AddRazorSupportForMvc>\n\t</PropertyGroup>\n\n\t<ItemGroup>\n\t\t<ProjectReference Include=\"..\\BlazorDateRangePicker\\BlazorDateRangePicker.csproj\" />\n\t</ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Demo.Shared/Pages/BothSidesSelection.razor",
    "content": "﻿@page \"/bothSidesSelection\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/BothSidesSelection.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Both sides selection</h3>\n</div>\n\n<p>\n    This example demonstrates how to enable both sides range selection by overring day click function.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\" OnMonthChanged=\"MonthChanged\" CustomDateFunction=\"CustomHover\" />\n</Example>\n\n@code {\n    DateRangePicker Picker { get; set; }\n\n    private void MonthChanged()\n    {\n        UpdateClickHandlers();\n    }\n\n    private string CustomHover(DateTimeOffset dt)\n    {\n        if (dt >= Picker?.HoverDate && dt < Picker?.TStartDate)\n        {\n            return \"in-range\";\n        }\n        return string.Empty;\n    }\n\n    private void UpdateClickHandlers()\n    {\n        var days = Enumerable\n            .Concat(Picker.LeftCalendar.Calendar, Picker.RightCalendar.Calendar)\n            .SelectMany(d => d);\n\n        foreach (var day in days)\n        {\n            var dayClick = day.Click;\n\n            day.Click = async () =>\n            {\n                if (Picker.TStartDate.HasValue && !Picker.TEndDate.HasValue && day.Day < Picker.TStartDate)\n                {\n                    Picker.TEndDate = Picker.TStartDate;\n                    Picker.TStartDate = day.Day;\n                    await Picker.LeftCalendar.CalculateCalendar();\n                    await Picker.RightCalendar.CalculateCalendar();\n                    StateHasChanged();\n                }\n                else\n                {\n                    dayClick.Invoke();\n                }\n            };\n        }\n    }\n    private string ExampleText = \"<DateRangePicker @ref=\\\"Picker\\\" OnMonthChanged=\\\"MonthChanged\\\" CustomDateFunction=\\\"CustomHover\\\" />\" +\n@\"\n\nDateRangePicker Picker { get; set; }\n\nprivate void MonthChanged()\n{\n    UpdateClickHandlers();\n}\n\nprivate string CustomHover(DateTimeOffset dt)\n{\n    if (dt >= Picker?.HoverDate && dt < Picker?.TStartDate)\n    {\n\t\t\" + \"return \\\"in-range\\\";\" + @\"\n    }\n    return string.Empty;\n}\n\nprivate void UpdateClickHandlers()\n{\n    var days = Enumerable\n        .Concat(Picker.LeftCalendar.Calendar, Picker.RightCalendar.Calendar)\n        .SelectMany(d => d);\n\n    foreach (var day in days)\n    {\n        var dayClick = day.Click;\n\n        day.Click = async () =>\n        {\n            if (Picker.TStartDate.HasValue && !Picker.TEndDate.HasValue && day.Day < Picker.TStartDate)\n            {\n                Picker.TEndDate = Picker.TStartDate;\n                Picker.TStartDate = day.Day;\n                await Picker.LeftCalendar.CalculateCalendar();\n                await Picker.RightCalendar.CalculateCalendar();\n                StateHasChanged();\n            }\n            else\n            {\n                dayClick.Invoke();\n            }\n        };\n    }\n}\n\";\n\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/Container.razor",
    "content": "﻿@page \"/container\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Container.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Resolving positioning issues</h3>\n</div>\n\n<Example Text=\"@ExampleText\">\n\n    <p>When the picker is placed inside absolutely positioned container position calculations may be incorrect.</p>\n    <p>In that case you should use <b>PickerContainer</b> component placed outside promblem node</p>\n\n    <div class=\"popover fade show bs-popover-right\" role=\"tooltip\" x-placement=\"right\"\n         style=\"position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(120px, 330px, 0px);\">\n        <div class=\"arrow\" style=\"top: 34px;\"></div>\n        <h3 class=\"popover-header\">Popover title</h3>\n        <div class=\"popover-body\">\n            <DateRangePicker Container=\"CustomContainer\" Drops=\"DropsType.Up\" class=\"form-control form-control-sm\" SingleDatePicker=\"true\" />\n            And here's some amazing content. It's very engaging. Right?\n        </div>\n    </div>\n\n</Example>\n\n<PickerContainer @ref=\"CustomContainer\" />\n\n@code {\n    PickerContainer CustomContainer { get; set; }\n\n    private string ExampleText =\n        \"<div class=\\\"popover\\\">\\n    <DateRangePicker Container=\\\"CustomContainer\\\" />\\n</div>\\n\\n\" +\n        \"<PickerContainer @ref=\\\"CustomContainer\\\" />\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/CustomButtons.razor",
    "content": "﻿@page \"/customButtons\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/CustomButtons.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Custom buttons template</h3>\n</div>\n\n<p>\n    Override\n    <code class=\"language-plaintext highlighter-rouge\">ButtonsTemplate</code>\n    template if you want to add additional buttons.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\" @bind-StartDate=\"StartDate\" @bind-EndDate=\"EndDate\">\n        <ButtonsTemplate>\n            <button class=\"btn btn-sm btn-outline-success\" type=\"button\">\n                Some button\n            </button>\n            <button class=\"cancelBtn btn btn-sm btn-default\"\n                    @onclick=\"@context.ClickCancel\" type=\"button\">\n                Cancel\n            </button>\n            <button class=\"cancelBtn btn btn-sm btn-default\"\n                    @onclick=\"@(e => ResetClick(e, context))\" type=\"button\">\n                Reset\n            </button>\n            <button class=\"applyBtn btn btn-sm btn-primary\" @onclick=\"@context.ClickApply\"\n                    disabled=\"@(context.TStartDate == null || context.TEndDate == null)\"\n                    type=\"button\">\n                Apply\n            </button>\n        </ButtonsTemplate>\n    </DateRangePicker>\n</Example>\n\n@code {\n    DateRangePicker Picker;\n\n    DateTimeOffset? StartDate { get; set; }\n    DateTimeOffset? EndDate { get; set; }\n\n    async Task ResetClick(MouseEventArgs e, DateRangePicker picker)\n    {\n        StartDate = null;\n        EndDate = null;\n        // Close the picker\n        await Picker.Close();\n        // Fire OnRangeSelectEvent\n        await Picker.OnRangeSelect.InvokeAsync(new DateRange());\n    }\n\n    private string ExampleText =\n        \"<DateRangePicker @ref=\\\"Picker\\\" @bind-StartDate=\\\"StartDate\\\" @bind-EndDate=\\\"EndDate\\\">\\n\" +\n        \"    <ButtonsTemplate>\\n\" +\n        \"        <button class=\\\"btn btn-sm btn-outline-success\\\" type=\\\"button\\\">\\n\" +\n        \"            Some button\\n\" +\n        \"        </button>\\n\" +\n        \"        <button class=\\\"cancelBtn btn btn-sm btn-default\\\"\\n\" +\n        \"                @onclick=\\\"@context.ClickCancel\\\" type=\\\"button\\\">\\n\" +\n        \"            Cancel\\n\" +\n        \"        </button>\\n\" +\n        \"        <button class=\\\"cancelBtn btn btn-sm btn-default\\\"\\n\" +\n        \"                @onclick=\\\"@(e => ResetClick(e, context))\\\" type=\\\"button\\\">\\n\" +\n        \"            Reset\\n\" +\n        \"        </button>\\n\" +\n        \"        <button class=\\\"applyBtn btn btn-sm btn-primary\\\" @onclick=\\\"@context.ClickApply\\\"\\n\" +\n        \"                disabled=\\\"@(context.TStartDate == null || context.TEndDate == null)\\\"\\n\" +\n        \"                type=\\\"button\\\">\\n\" +\n        \"            Apply\\n\" +\n        \"        </button>\\n\" +\n        \"    </ButtonsTemplate>\\n\" +\n        \"</DateRangePicker>\\n\\n\" +\n        \"@code {\\n\" +\n        \"    DateRangePicker Picker;\\n\\n\" +\n        \"    DateTimeOffset? StartDate { get; set; }\\n\" +\n        \"    DateTimeOffset? EndDate { get; set; }\\n\\n\" +\n        \"    async Task ResetClick(MouseEventArgs e, DateRangePicker picker)\\n\" +\n        \"    {\\n\" +\n        \"        StartDate = null;\\n\" +\n        \"        EndDate = null;\\n\" +\n        \"        // Close the picker\\n\" +\n        \"        await Picker.Close();\\n\" +\n        \"        // Fire OnRangeSelectEvent\\n\" +\n        \"        await Picker.OnRangeSelect.InvokeAsync(new DateRange());\\n\" +\n        \"    }\\n\" +\n        \"}\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/CustomClickHandler.razor",
    "content": "﻿@page \"/customClickHandler\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/CustomClickHandler.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>CustomClickHandler</h3>\n</div>\n\n<p>\n    This example demonstrates how to override day click function to build custom functionality.\n</p>\n\n<p>\n    In this example the start date can only be selected in the left calendar and the end date can only be selected in the right calendar.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\" OnMonthChanged=\"MonthChanged\" />\n</Example>\n\n@code {\n    DateRangePicker Picker { get; set; }\n\n    private void MonthChanged()\n    {\n        UpdateClickHandlers();\n    }\n\n    private void UpdateClickHandlers()\n    {\n        var days = Enumerable\n            .Concat(Picker.LeftCalendar.Calendar, Picker.RightCalendar.Calendar)\n            .SelectMany(d => d);\n\n        foreach (var day in days)\n        {\n            var dayClick = day.Click;\n            day.Click = () =>\n            {\n                if (day.Side == SideType.Right && !Picker.TEndDate.HasValue)\n                {\n                    if (day.Day > Picker.TStartDate) dayClick.Invoke();\n                }\n                else if (day.Side == SideType.Left)\n                {\n                    Picker.TStartDate = null;\n                    Picker.TEndDate = null;\n                    dayClick.Invoke();\n                }\n            };\n        }\n    }\n\n    private string ExampleText = \"<DateRangePicker @ref=\\\"Picker\\\" OnMonthChanged=\\\"MonthChanged\\\" />\" +\n@\"\n\n@code {\n\nDateRangePicker Picker { get; set; }\n\nprivate void MonthChanged()\n{\n    UpdateClickHandlers();\n}\n\nprivate void UpdateClickHandlers()\n{\n    var days = Enumerable\n        .Concat(Picker.LeftCalendar.Calendar, Picker.RightCalendar.Calendar)\n        .SelectMany(d => d);\n\n    foreach (var day in days)\n    {\n        var dayClick = day.Click;\n        day.Click = () =>\n        {\n            if (day.Side == SideType.Right && !Picker.TEndDate.HasValue)\n            {\n                if (day.Day > Picker.TStartDate) dayClick.Invoke();\n            }\n            else if (day.Side == SideType.Left)\n            {\n                Picker.TStartDate = null;\n                Picker.TEndDate = null;\n                dayClick.Invoke();\n            }\n        };\n    }\n}\n\";\n\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/CustomDate.razor",
    "content": "﻿@page \"/customDate\"\n\n@using System.Threading\n\n<style>\n    .dthighlight {\n        background-color: aquamarine !important;\n    }\n</style>\n\n<DateRangePicker @ref=\"Picker\" style=\"width: 300px;\"\n                 LinkedCalendars=\"true\"\n                 AutoAdjustCalendars=\"false\"\n                 MinDate=\"DateTime.Now.AddYears(-1)\"\n                 MaxDate=\"DateTime.Now.AddYears(1)\"\n                 ShowDropdowns=\"true\"\n                 ShowWeekNumbers=\"true\"\n                 WeekAbbreviation=\"НE\"\n                 MinSpan=\"TimeSpan.FromDays(5)\"\n                 MaxSpan=\"TimeSpan.FromDays(15)\"\n                 DaysEnabledFunction=\"DaysEnabledFunction\"\n                 OnMonthChangedAsync=\"OnMonthChanged\"\n                 CustomDateFunction=\"CustomDateFunction\"\n                 OnSelectionStart=\"OnSelectionStart\"\n                 OnRangeSelect=\"OnRangeSelect\"\n                 @bind-StartDate=\"StartDate\"\n                 @bind-EndDate=\"EndDate\">\n    <DayTemplate Context=\"dt\">\n        D-@(dt.Day.Day)\n        <br/>\n        $ 200\n    </DayTemplate>\n</DateRangePicker>\n<hr />\n<p>Start: @StartDate</p>\n<p>End: @EndDate</p>\n\n<p>Events:</p>\n<ul>\n    @foreach (var ev in Events)\n    {\n        <li>@ev</li>\n    }\n</ul>\n\n<button @onclick=\"SetDates\">set</button>\n\n@code {\n    DateRangePicker Picker;\n\n    DateTimeOffset? StartDate { get; set; }\n    DateTimeOffset? EndDate { get; set; }\n\n    List<string> Events { get; set; } = new List<string>();\n\n    List<DateTimeOffset> DisabledDays { get; set; } = new List<DateTimeOffset>();\n\n    private bool DaysEnabledFunction(DateTimeOffset day)\n    {\n        return !DisabledDays.Any(d => d.Day == day.Day);\n    }\n\n    private object CustomDateFunction(DateTimeOffset day)\n    {\n        //await Task.Delay(1);\n\n        if (DisabledDays.Any(d => d.Day == day.Day - 1)) return \"dthighlight\";\n        return string.Empty;\n    }\n\n    private async Task OnMonthChanged(CancellationToken ct)\n    {\n        var leftMonth = Picker.LeftCalendar.Month;\n        var rightMonth = Picker.RightCalendar.Month;\n        Events.Add($\"OnMonthChanged: {leftMonth:MM.yyyy} & {rightMonth:MM.yyyy}\");\n\n        await Task.Delay(500, ct);\n\n        Events.Add($\"Completed OnMonthChanged: {leftMonth:MM.yyyy} & {rightMonth:MM.yyyy}\");\n\n        DisabledDays = new List<DateTimeOffset> {\n            new DateTime(leftMonth.Year, leftMonth.Month, leftMonth.Month),\n            new DateTime(rightMonth.Year, rightMonth.Month, rightMonth.Month)\n        };\n    }\n\n    private void OnSelectionStart(DateTimeOffset date)\n    {\n        Events.Add($\"On selection start = {date}\");\n    }\n\n    private void OnRangeSelect(DateRange range)\n    {\n        Events.Add($\"On range select\");\n    }\n\n    private void SetDates()\n    {\n        StartDate = DateTime.Now;\n        EndDate = DateTime.Now.AddDays(10);\n    }\n}"
  },
  {
    "path": "Demo.Shared/Pages/CustomDay.razor",
    "content": "﻿@page \"/customDay\"\n\n<style>\n    .daterangepicker .drp-calendar {\n        max-width: 298px;\n    }\n\n    .daterangepicker .calendar-table td {\n        width: 40px;\n    }\n</style>\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/CustomDay.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Custom day template</h3>\n</div>\n\n<p>\n    Override\n    <code class=\"language-plaintext highlighter-rouge\">DayTemplate</code>\n    template to display additional information in the day cells.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker>\n        <DayTemplate Context=\"dt\">\n            D-<b>@(dt.Day.Day)</b>\n            <br />\n            $@(dt.Day.Day + dt.Day.Month * 10)\n        </DayTemplate>\n    </DateRangePicker>\n</Example>\n\n@code {\n    private string ExampleText =\n        \"<DateRangePicker>\\n\" +\n        \"   <DayTemplate Context=\\\"dt\\\">\\n\" +\n        \"       D-<b>@(dt.Day.Day)</b>\\n\" +\n        \"       <br />\\n\" +\n        \"       $@(dt.Day.Day + dt.Day.Month * 10)\\n\" +\n        \"   </DayTemplate>\\n\" +\n        \"</DateRangePicker>\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/CustomInput.razor",
    "content": "﻿@page \"/customInput\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/CustomInput.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Custom input markup</h3>\n</div>\n\n<Example Text=\"@ExampleSource\">\n    <DateRangePicker>\n        <PickerTemplate>\n            <div id=\"@context.Id\" @onclick=\"context.Toggle\" style=\"background: #fff; cursor: pointer; padding: .45rem 10px; border: 1px solid #ccc; border-radius: 5px;\">\n                <i class=\"oi oi-calendar\"></i>&nbsp;\n                <span>\n                    @if (context.TStartDate == null && context.TEndDate == null)\n                    {\n                        <span>Select dates...</span>\n                    }\n                    else if (context.TStartDate != null && context.TEndDate == null)\n                    {\n                        if (context.HoverDate > context.TStartDate)\n                        {\n                            @($\"{context.TStartDate.Value.ToString(context.DateFormat)} - {context.HoverDate.Value.ToString(context.DateFormat)}\")\n                            @($\" - ({(context.HoverDate.Value.Subtract(context.TStartDate.Value).Days).ToString()} nights)\")\n                        }\n                        else\n                        {\n                            <span>@context.TStartDate.Value.ToString(\"dd/MM/yyyy\")</span>\n                        }\n                    }\n                    else\n                    {\n                        <span>\n                            @context.FormattedRange @($\" - ({(context.TEndDate.Value.Subtract(context.TStartDate.Value).Days).ToString()} nights)\")\n                        </span>\n                    }\n                </span>\n                <i class=\"oi oi-chevron-bottom float-right\"></i>\n            </div>\n        </PickerTemplate>\n    </DateRangePicker>\n</Example>\n\n@code {\n    private string ExampleSource =\n        \"<DateRangePicker>\\n\" +\n        \"    <PickerTemplate>\\n\" +\n        \"        <div id=\\\"@context.Id\\\" @onclick=\\\"context.Toggle\\\" style=\\\"background: #fff; cursor: pointer; padding: .45rem 10px; border: 1px solid #ccc; border-radius: 5px;\\\">\\n\" +\n        \"            <i class=\\\"oi oi-calendar\\\"></i>&nbsp;\\n\" +\n        \"            <span>\\n\" +\n        \"                @if (context.TStartDate == null && context.TEndDate == null)\\n\" +\n        \"                {\\n\" +\n        \"                    <span>Select dates...</span>\\n\" +\n        \"                }\\n\" +\n        \"                else if (context.TStartDate != null && context.TEndDate == null)\\n\" +\n        \"                {\\n\" +\n        \"                    if (context.HoverDate > context.TStartDate)\\n\" +\n        \"                    {\\n\" +\n        \"                        @($\\\"{context.TStartDate.Value.ToString(context.DateFormat)} - {context.HoverDate.Value.ToString(context.DateFormat)}\\\")\\n\" +\n        \"                        @($\\\" - ({(context.HoverDate.Value.Subtract(context.TStartDate.Value).Days).ToString()} nights)\\\")\\n\" +\n        \"                    }\\n\" +\n        \"                    else\\n\" +\n        \"                    {\\n\" +\n        \"                        <span>@context.TStartDate.Value.ToString(\\\"dd/MM/yyyy\\\")</span>\\n\" +\n        \"                    }\\n\" +\n        \"                }\\n\" +\n        \"                else\\n\" +\n        \"                {\\n\" +\n        \"                    <span>\\n\" +\n        \"                        @context.FormattedRange @($\\\" - ({(context.TEndDate.Value.Subtract(context.TStartDate.Value).Days).ToString()} nights)\\\")\\n\" +\n        \"                    </span>\\n\" +\n        \"                }\\n\" +\n        \"            </span>\\n\" +\n        \"            <i class=\\\"oi oi-chevron-bottom float-right\\\"></i>\\n\" +\n        \"        </div>\\n\" +\n        \"    </PickerTemplate>\\n\" +\n        \"</DateRangePicker>\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/DateInput.razor",
    "content": "﻿@inherits InputBase<DateRange>\n\n<DateRangePicker class=\"@(\"is-\" + CssClass + \" form-control\")\" \n                 StartDate=\"Value?.Start\" EndDate=\"Value?.End\"\n                 OnRangeSelect=\"OnRangeSelect\" OnReset=\"OnReset\" />\n\n@code {\n    private Task OnReset()\n    {\n        Value = null;\n        return ValueChanged.InvokeAsync(Value);\n    }\n\n    private Task OnRangeSelect(DateRange range)\n    {\n        if (Value == null) Value = new DateRange();\n        Value.Start = range.Start;\n        Value.End = range.End;\n        return ValueChanged.InvokeAsync(Value);\n    }\n\n    protected override bool TryParseValueFromString(string value, out DateRange result, out string validationErrorMessage)\n    {\n        result = new DateRange();\n        validationErrorMessage = string.Empty;\n        return false;\n    }\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/Disable.razor",
    "content": "﻿@page \"/disable\"\n\n@using System.Threading\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Disable.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Disable some days</h3>\n</div>\n\n<p>\n    There is a function \n    <code class=\"language-plaintext highlighter-rouge\">DaysEnabledFunction</code>\n    (and <code class=\"language-plaintext highlighter-rouge\">DaysEnabledFunctionAsync</code>) \n    that is passed each date in the two calendars before they are displayed, \n    and it may return true or false to indicate whether that date should be available for selection or not.\n</p>\n\n<p>\n    <code class=\"language-plaintext highlighter-rouge\">OnMonthChanged</code>\n    event is used to prepare data for \n    <code class=\"language-plaintext highlighter-rouge\">DaysEnabledFunction</code>\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\"\n                     DaysEnabledFunction=\"DaysEnabledFunction\"\n                     OnMonthChangedAsync=\"OnMonthChangedAsync\" />\n</Example>\n\n@code {\n    DateRangePicker Picker;\n\n    List<DateTimeOffset> DisabledDays { get; set; } = new List<DateTimeOffset>();\n\n    private bool DaysEnabledFunction(DateTimeOffset day)\n    {\n        return !DisabledDays.Any(d => d.Day == day.Day);\n    }\n\n    private async Task OnMonthChangedAsync(CancellationToken ct)\n    {\n        var leftMonth = Picker.LeftCalendar.Month;\n        var rightMonth = Picker.RightCalendar.Month;\n\n        // Simulate hard work (db request, etc)\n        await Task.Delay(500, ct);\n\n        // For example, disable the dates that matching with selected month numbers\n        DisabledDays = new List<DateTimeOffset> {\n            new DateTime(leftMonth.Year, leftMonth.Month, leftMonth.Month),\n            new DateTime(rightMonth.Year, rightMonth.Month, rightMonth.Month)\n        };\n    }\n\n    private string ExampleText = \n        \"<DateRangePicker @ref=\\\"Picker\\\"\\n\" +\n        \"                 DaysEnabledFunction=\\\"DaysEnabledFunction\\\"\\n\" +\n        \"                 OnMonthChangedAsync=\\\"OnMonthChangedAsync\\\" />\\n\\n\" +\n        \"@code {\\n\" +\n        \"    DateRangePicker Picker;\\n\\n\" +\n        \"    List<DateTimeOffset> DisabledDays { get; set; } = new List<DateTimeOffset>();\\n\\n\" +\n        \"    private bool DaysEnabledFunction(DateTimeOffset day)\\n\" +\n        \"    {\\n\" +\n        \"        return !DisabledDays.Any(d => d.Day == day.Day);\\n\" +\n        \"    }\\n\\n\" +\n        \"    private async Task OnMonthChangedAsync(CancellationToken ct)\\n\" +\n        \"    {\\n\" +\n        \"        var leftMonth = Picker.LeftCalendar.Month;\\n\" +\n        \"        var rightMonth = Picker.RightCalendar.Month;\\n\\n\" +\n        \"        // Simulate hard work (db request, etc)\\n\" +\n        \"        await Task.Delay(500, ct);\\n\\n\" +\n        \"        // For example, disable the dates that matching with selected month numbers\\n\" +\n        \"        DisabledDays = new List<DateTimeOffset> {\\n\" +\n        \"            new DateTime(leftMonth.Year, leftMonth.Month, leftMonth.Month),\\n\" +\n        \"            new DateTime(rightMonth.Year, rightMonth.Month, rightMonth.Month)\\n\" +\n        \"        };\\n\" +\n        \"    }\\n\" +\n        \"}\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Example.razor",
    "content": "﻿@inject IClipboard Clipboard\n\n@if (ChildContent != null)\n{\n    <div class=\"bd-example\">\n        @ChildContent\n    </div>\n}\n\n<div class=\"bd-clipboard\">\n    <button type=\"button\" class=\"btn-clipboard\" title=\"Copy to clipboard\" @onclick=\"CopyText\">Copy</button>\n</div>\n\n@if (!string.IsNullOrEmpty(Text))\n{\n    <figure class=\"highlight\">\n        <pre><code lang=\"html\">@Text</code></pre>\n    </figure>\n}\n\n@code{\n    [Parameter]\n    public RenderFragment ChildContent { get; set; }\n\n    [Parameter]\n    public string Text { get; set; }\n\n    private Task CopyText()\n    {\n        return Clipboard.SetTextAsync(Text);\n    }\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/Form.razor",
    "content": "﻿@page \"/form\"\n@using System.ComponentModel.DataAnnotations;\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Form.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Example of DateRangePicker usage as a form control</h3>\n</div>\n\n<Example Text=\"@ExampleText\">\n\n    <EditForm Model=\"@exampleModel\" OnValidSubmit=\"@HandleValidSubmit\">\n        <DataAnnotationsValidator />\n\n        <DateInput @bind-Value=\"@exampleModel.Range\" />\n        <div class=\"invalid-feedback\">\n            <ValidationMessage For=\"@(()=>exampleModel.Range)\" />\n        </div>\n\n        <button class=\"btn btn-primary mt-2 mb-2\" type=\"submit\">Submit</button>\n    </EditForm>\n\n    <p>Form value:</p>\n    <pre>@System.Text.Json.JsonSerializer.Serialize(exampleModel)</pre>\n\n</Example>\n\n@code {\n    private ExampleModel exampleModel = new ExampleModel();\n\n    private void HandleValidSubmit()\n    {\n        // Do stuff...\n    }\n\n    public class ExampleModel\n    {\n        [Required]\n        public DateRange Range { get; set; }\n    }\n\n    private string ExampleText = \"<DateInput @bind-Value=\\\"@exampleModel.Range\\\" />\";\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/HandleEvents.razor",
    "content": "﻿@page \"/handleEvents\"\n\n<style>\n    .bd-example > .alert + .alert {\n        margin-top: 0.3rem;\n    }\n\n    .alert {\n        padding: 0.15rem 0.65rem;\n        margin-bottom: 0.2rem;\n    }\n</style>\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/HandleEvents.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Subscribe to events</h3>\n</div>\n\n<p>You can get notified when the user interacts with picker by subscribing to events.</p>\n\n<table>\n    <thead>\n        <tr>\n            <th>Event</th>\n            <th>Type</th>\n            <th>Description</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnRangeSelect</code></td>\n            <td>DateRange</td>\n            <td>Triggered when the apply button is clicked, or when a predefined range is clicked.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnReset</code></td>\n            <td>void</td>\n            <td>Triggered when the apply button is clicked, or when a predefined range is clicked.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnOpened</code></td>\n            <td>void</td>\n            <td>An event that is invoked when the DatePicker is opened.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnClosed</code></td>\n            <td>void</td>\n            <td>An event that is invoked when the DatePicker is closed.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnCancel</code></td>\n            <td>bool</td>\n            <td>An event that is invoked when user cancels the selection (true if by pressing \"Cancel\" button, false if by backdrop click).</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnMonthChanged</code></td>\n            <td>void</td>\n            <td>An event that is invoked when left or right calendar's month changed.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnMonthChangedAsync</code></td>\n            <td>Task</td>\n            <td>\n                An event that is invoked when left or right calendar's month changed and supports CancellationToken.\n                Use this event handler to prepare the data for CustomDateFunction because it's supports loading indication.\n            </td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnSelectionStart</code></td>\n            <td>DateTimeOffset</td>\n            <td>An event that is invoked when StartDate is selected.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">OnSelectionEnd</code></td>\n            <td>DateTimeOffset</td>\n            <td>An event that is invoked when EndDate is selected but before the user clicks apply button.</td>\n        </tr>\n    </tbody>\n</table>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\"\n                     OnRangeSelect=\"OnRangeSelect\"\n                     OnMonthChanged=\"OnMonthChanged\"\n                     OnSelectionStart=\"OnSelectionStart\"\n                     OnSelectionEnd=\"OnSelectionEnd\"\n                     OnReset=\"OnReset\"\n                     OnOpened=\"OnOpened\"\n                     OnClosed=\"OnClosed\"\n                     OnCancel=\"OnCancel\" />\n\n    @if (events.Count > 0)\n    {\n        <h6 class=\"pt-2\">Events:</h6>\n    }\n    @foreach (var e in events)\n    {\n        <div class=\"alert alert-secondary\" role=\"alert\"><small>@e.Item2</small><small class=\"float-right\">@e.Item1</small></div>\n    }\n</Example>\n\n@code {\n    DateRangePicker Picker;\n\n    List<(DateTime, string)> events { get; set; } = new List<(DateTime, string)>();\n\n    private void OnOpened()\n    {\n        events.Add((DateTime.Now, $\"OnOpened\"));\n    }\n\n    private void OnClosed()\n    {\n        events.Add((DateTime.Now, $\"OnClosed\"));\n    }\n\n    private void OnReset()\n    {\n        events.Add((DateTime.Now, $\"OnReset\"));\n    }\n\n    private void OnCancel(bool byButton)\n    {\n        events.Add((DateTime.Now, $\"OnCancel: {(byButton ? \"by 'cancel' button\" : \"by backdrop click\")}\"));\n    }\n\n    private void OnMonthChanged()\n    {\n        var leftMonth = Picker.LeftCalendar.Month;\n        var rightMonth = Picker.RightCalendar.Month;\n        events.Add((DateTime.Now, $\"OnMonthChanged: LeftMonth = {leftMonth:MM.yyyy}, RightMonth = {rightMonth:MM.yyyy}\"));\n    }\n\n    private void OnSelectionStart(DateTimeOffset date)\n    {\n        events.Add((DateTime.Now, $\"OnSelectionStart: {date}\"));\n    }\n\n    private void OnSelectionEnd(DateTimeOffset date)\n    {\n        events.Add((DateTime.Now, $\"OnSelectionEnd: {date}\"));\n    }\n\n    public void OnRangeSelect(DateRange range)\n    {\n        events.Add((DateTime.Now, $\"OnRangeSelect: {range.Start} - {range.End}\"));\n    }\n\n    private string ExampleText =\n        \"<DateRangePicker @ref=\\\"Picker\\\"\\n\" +\n        \"             OnRangeSelect=\\\"OnRangeSelect\\\"\\n\" +\n        \"             OnMonthChanged=\\\"OnMonthChanged\\\"\\n\" +\n        \"             OnSelectionStart=\\\"OnSelectionStart\\\"\\n\" +\n        \"             OnReset=\\\"OnReset\\\"\\n\" +\n        \"             OnOpened=\\\"OnOpened\\\"\\n\" +\n        \"             OnClosed=\\\"OnClosed\\\"\\n\" +\n        \"             OnCancel=\\\"OnCancel\\\" />\\n\\n\" +\n        \"@code {\\n\" +\n        \"    DateRangePicker Picker;\\n\\n\" +\n        \"    List<(DateTime, string)> events { get; set; } = new List<(DateTime, string)>();\\n\\n\" +\n        \"    private void OnOpened()\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnOpened\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    private void OnReset()\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnReset\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    private void OnClosed()\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnClosed\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    private void OnCancel(bool byButton)\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnCancel: {(byButton ? \\\"by 'cancel' button\\\" : \\\"by backdrop click\\\")}\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    private void OnMonthChanged()\\n\" +\n        \"    {\\n\" +\n        \"        var leftMonth = Picker.LeftCalendar.Month;\\n\" +\n        \"        var rightMonth = Picker.RightCalendar.Month;\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnMonthChanged: LeftMonth = {leftMonth:MM.yyyy}, RightMonth = {rightMonth:MM.yyyy}\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    private void OnSelectionStart(DateTimeOffset date)\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnSelectionStart: {date}\\\"));\\n\" +\n        \"    }\\n\\n\" +\n        \"    public void OnRangeSelect(DateRange range)\\n\" +\n        \"    {\\n\" +\n        \"        events.Add((DateTime.Now, $\\\"OnRangeSelect: {range.Start} - {range.End}\\\"));\\n\" +\n        \"    }\\n\" +\n        \"}\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Highlight.razor",
    "content": "﻿@page \"/highlight\"\n\n@using System.Threading\n\n<style>\n    .dthighlight {\n        background-color: aquamarine !important;\n    }\n</style>\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Highlight.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Highlight some days</h3>\n</div>\n\n<p>\n    You can add any css classes to dates with\n    <code class=\"language-plaintext highlighter-rouge\">CustomDateFunction</code>\n    function, it uses same approach as <a href=\"disable\">disable function</a>.\n</p>\n\n<p>\n    Define custom css classes somewhere in your stylesheets.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker @ref=\"Picker\"\n                     CustomDateFunction=\"CustomDateFunction\"\n                     OnMonthChangedAsync=\"OnMonthChangedAsync\" />\n</Example>\n\n@code {\n    DateRangePicker Picker;\n\n    List<DateTimeOffset> HighlightDays { get; set; } = new List<DateTimeOffset>();\n\n    private object CustomDateFunction(DateTimeOffset day)\n    {\n        if (HighlightDays.Any(d => d.Day == day.Day)) return \"dthighlight\";\n        return string.Empty;\n    }\n\n    private async Task OnMonthChangedAsync(CancellationToken ct)\n    {\n        var leftMonth = Picker.LeftCalendar.Month;\n        var rightMonth = Picker.RightCalendar.Month;\n\n        // Simulate hard work (db request, etc)\n        await Task.Delay(500, ct);\n\n        // For example, highlight the dates that matching with selected month numbers\n        HighlightDays = new List<DateTimeOffset> {\n            new DateTime(leftMonth.Year, leftMonth.Month, leftMonth.Month),\n            new DateTime(rightMonth.Year, rightMonth.Month, rightMonth.Month)\n        };\n    }\n\n    private string ExampleText =\n        \"<style>\\n\" +\n        \"   .dthighlight {\\n\" +\n        \"       background-color: aquamarine !important;\\n\" +\n        \"   }\\n\" +\n        \"</style>\\n\\n\" +\n        \"<DateRangePicker @ref=\\\"Picker\\\"\\n\" +\n        \"                 CustomDateFunction=\\\"CustomDateFunction\\\"\\n\" +\n        \"                 OnMonthChangedAsync=\\\"OnMonthChangedAsync\\\" />\\n\\n\" +\n        \"@code {\\n\" +\n        \"    DateRangePicker Picker;\\n\\n\" +\n        \"    List<DateTimeOffset> HighlightDays { get; set; } = new List<DateTimeOffset>();\\n\\n\" +\n        \"    private object CustomDateFunction(DateTimeOffset day)\\n\" +\n        \"    {\\n\" +\n        \"        if (HighlightDays.Any(d => d.Day == day.Day - 1)) return \\\"dthighlight\\\";\\n\" +\n        \"        return string.Empty;\\n\" +\n        \"    }\\n\\n\" +\n        \"    private async Task OnMonthChangedAsync(CancellationToken ct)\\n\" +\n        \"    {\\n\" +\n        \"        var leftMonth = Picker.LeftCalendar.Month;\\n\" +\n        \"        var rightMonth = Picker.RightCalendar.Month;\\n\\n\" +\n        \"        // Simulate hard work (db request, etc)\\n\" +\n        \"        await Task.Delay(500, ct);\\n\\n\" +\n        \"        // For example, highlight the dates that matching with selected month numbers\\n\" +\n        \"        HighlightDays = new List<DateTimeOffset> {\\n\" +\n        \"            new DateTime(leftMonth.Year, leftMonth.Month, leftMonth.Month),\\n\" +\n        \"            new DateTime(rightMonth.Year, rightMonth.Month, rightMonth.Month)\\n\" +\n        \"        };\\n\" +\n        \"    }\\n\" +\n        \"}\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Index.razor",
    "content": "﻿@page \"/\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Index.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h1 class=\"bd-title\">Date Range Picker</h1>\n</div>\n\n<p class=\"bd-lead\">\n    Features include limiting the selectable date range, localizable strings and date formats, a single date picker mode, an inline mode, customizable picker layout, and predefined date ranges.\n</p>\n\n<h2><span class=\"bd-content-title\">Quick start</span></h2>\n\n<p>To add the picker to your project download library from NuGet in the NuGet Package Manager, or by executing the following command in the Package Manager Console:</p>\n\n<Example Text=\"Install-Package BlazorDateRangePicker\" />\n\n<h3><span class=\"bd-content-title\">CSS</span></h3>\n\n<p>\n    Then Copy-paste the stylesheet\n    <code class=\"language-plaintext highlighter-rouge\">&lt;link&gt;</code>\n    into your <code class=\"language-plaintext highlighter-rouge\">&lt;head&gt;</code>\n    to load CSS. For complex implementations, custom CSS may be necessary.\n</p>\n\n<Example Text=\"@Css\" />\n\n<h3><span class=\"bd-content-title\">JS</span></h3>\n\n<p>\n    This library require the use of JavaScript for popup positioning and outside click handling. Place the following\n    <code class=\"language-plaintext highlighter-rouge\">&lt;script&gt;</code>\n    near the end of your _Host.cshtml (or index.html for Blazor WebAssembly) pages, right before the closing\n    <code class=\"language-plaintext highlighter-rouge\">&lt;/body&gt;</code>.\n</p>\n\n<Example Text=\"@Js\" />\n\n<h3>Using directive</h3>\n\n<p>Add this line to the page where you want to use the picker. If you're using the picker on many pages add this line to <code class=\"language-plaintext highlighter-rouge\">_Imports.razor</code>.</p>\n\n<Example Text=\"@Import\" />\n\n<h3>Use the component</h3>\n\n<p>Then attach a date range picker to whatever page you want.</p>\n\n<Example Text=\"<DateRangePicker />\">\n    <DateRangePicker Drops=\"DropsType.Up\" />\n</Example>\n\n<p>\n    You can customize Date Range Picker with <a target=\"_blank\" href=\"https://github.com/jdtcn/BlazorDateRangePicker#properties\">options</a>, \n    and get notified when the user interacts with picker by subscribing to <a href=\"/handleEvents\">events</a>.\n</p>\n\n@code {\n    private string Css = \"<link rel=\\\"stylesheet\\\" href=\\\"_content/BlazorDateRangePicker/daterangepicker.min.css\\\" />\";\n    private string Js = \"<script src=\\\"_content/BlazorDateRangePicker/clickAndPositionHandler.js\\\"></script>\";\n    private string Import = \"@using BlazorDateRangePicker\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Inline.razor",
    "content": "﻿@page \"/inline\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Inline.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Inline mode</h3>\n</div>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker Inline=\"true\" AutoApply=\"true\" ShowOnlyOneCalendar=\"true\" />\n</Example>\n\n@code {\n    private string ExampleText = \"<DateRangePicker Inline=\\\"true\\\" AutoApply=\\\"true\\\" ShowOnlyOneCalendar=\\\"true\\\" />\";\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/Licence.razor",
    "content": "﻿<h4>Licence</h4>\n\n<p>The MIT License (MIT)</p>\n\n<p>Copyright (c) @DateTime.Now.Year Sergey Zaikin</p>\n\n<p>\n    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n</p>\n<p>\n    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n</p>\n<p>\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n</p>"
  },
  {
    "path": "Demo.Shared/Pages/Limits.razor",
    "content": "﻿@page \"/limits\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Limits.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Limiting the selectable date range</h3>\n</div>\n\n<p>Use these properties to limit selectable date range</p>\n\n<table>\n    <thead>\n        <tr>\n            <th>Property</th>\n            <th>Type</th>\n            <th>Description</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">MinDate</code></td>\n            <td>DateTimeOffset?</td>\n            <td>The earliest date a user may select.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">MaxDate</code></td>\n            <td>DateTimeOffset?</td>\n            <td>The latest date a user may select.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">MinSpan</code></td>\n            <td>TimeSpan?</td>\n            <td>The minimum span between the selected start and end dates.</td>\n        </tr>\n        <tr>\n            <td><code class=\"language-plaintext highlighter-rouge\">MaxSpan</code></td>\n            <td>TimeSpan?</td>\n            <td>The maximum span between the selected start and end dates.</td>\n        </tr>\n    </tbody>\n</table>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker MinDate=\"DateTime.Now.AddYears(-1)\"\n                     MaxDate=\"DateTime.Now.AddYears(1)\"\n                     MinSpan=\"TimeSpan.FromDays(5)\"\n                     MaxSpan=\"TimeSpan.FromDays(15)\" />\n</Example>\n\n@code {\n    private string ExampleText = \n        \"<DateRangePicker MinDate=\\\"DateTime.Now.AddYears(-1)\\\"\\n\" +\n        \"                 MaxDate=\\\"DateTime.Now.AddYears(1)\\\"\\n\" +\n        \"                 MinSpan=\\\"TimeSpan.FromDays(5)\\\"\\n\" +\n        \"                 MaxSpan=\\\"TimeSpan.FromDays(15)\\\" />\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Localization.razor",
    "content": "﻿@page \"/localization\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Localization.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Localization</h3>\n</div>\n\n<p>\n    Use\n    <code class=\"language-plaintext highlighter-rouge\">ApplyLabel</code>,\n    <code class=\"language-plaintext highlighter-rouge\">CancelLabel</code> and\n    <code class=\"language-plaintext highlighter-rouge\">CustomRangeLabel</code>\n    to change picker labels. Alternatively one can use custom\n    <code class=\"language-plaintext highlighter-rouge\">ButtonsTemplate</code>.\n</p>\n\n<p>\n    Use\n    <code class=\"language-plaintext highlighter-rouge\">Culture</code>\n    property to set picker culture other than CurrentUICulture.\n</p>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker Culture=\"@(System.Globalization.CultureInfo.GetCultureInfo(\"fr-FR\"))\"\n                     ApplyLabel=\"Appliquer\"\n                     CancelLabel=\"Annuler\"\n                     CustomRangeLabel=\"Ma gamme personnalisée\" />\n</Example>\n\n<p>It's convenient to set these properties application-wide in one place:</p>\n\n<Example Text=\"@ExampleConfig\" />\n\n@code {\n    private string ExampleText =\n        \"<DateRangePicker Culture=\\\"@(System.Globalization.CultureInfo.GetCultureInfo(\\\"fr-FR\\\"))\\\">\\n\" +\n        \"                 ApplyLabel=\\\"Appliquer\\\"\\n\" +\n        \"                 CancelLabel=\\\"Annuler\\\"\\n\" +\n        \"                 CustomRangeLabel=\\\"Ma gamme personnalisée\\\" />\";\n\n    private string ExampleConfig =\n        \"#Startup.cs\\n\\n\" +\n        \"using BlazorDateRangePicker;\\n\\n\" +\n        \"//ConfigureServices\\n\" +\n        \"services.AddDateRangePicker(config =>\\n\" +\n        \"{\\n\" +\n        \"    config.ApplyLabel = \\\"My Apply Label\\\";\\n\" +\n        \"    ...\\n\" +\n        \"});\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Positioning.razor",
    "content": "﻿@page \"/positioning\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Positioning.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Popup alignment</h3>\n</div>\n\n<p>The picker can be aligned to the left, to the right (default), or centered under the HTML element it's attached to</p>\n\n<Example Text=\"@ExampleTextLeft\">\n    <DateRangePicker Opens=\"SideType.Left\" />\n</Example>\n\n<Example Text=\"@ExampleTextCenter\">\n    <DateRangePicker Opens=\"SideType.Center\" />\n</Example>\n\n<Example Text=\"@ExampleTextRight\">\n    <DateRangePicker Opens=\"SideType.Right\" />\n</Example>\n\n<h4>Popup direction</h4>\n\n<p>Whether the picker appears below (default) or above the HTML element it's attached to</p>\n\n<Example Text=\"@ExampleTextUp\">\n    <DateRangePicker Drops=\"DropsType.Up\" />\n</Example>\n\n@code {\n    private string ExampleTextLeft = \"<DateRangePicker Opens=\\\"SideType.Left\\\" />\";\n    private string ExampleTextCenter = \"<DateRangePicker Opens=\\\"SideType.Center\\\" />\";\n    private string ExampleTextRight = \"<DateRangePicker Opens=\\\"SideType.Right\\\" />\";\n    private string ExampleTextUp = \"<DateRangePicker Drops=\\\"DropsType.Up\\\" />\";\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/PredefinedRanges.razor",
    "content": "﻿@page \"/predefinedRanges\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/PredefinedRanges.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Predefined Date Ranges</h3>\n</div>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker Ranges=\"DateRanges\" />\n</Example>\n\n@code{\n    Dictionary<string, DateRange> DateRanges => new Dictionary<string, DateRange> {\n            { \"This month\", new DateRange\n                {\n                    Start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),\n                    End = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddTicks(-1)\n                }\n            } ,\n            { \"Previous month\" , new DateRange\n                {\n                    Start = new DateTime(DateTime.Now.AddMonths(-1).Year, DateTime.Now.AddMonths(-1).Month, 1),\n                    End = new DateTime(DateTime.Now.AddMonths(-1).Year, DateTime.Now.AddMonths(-1).Month, 1).AddMonths(1).AddTicks(-1)\n                }\n            }\n     };\n\n    private string ExampleText = \n        \"<DateRangePicker Ranges=\\\"DateRanges\\\" />\\n\\n\" +\n        \"@code { \\n    Dictionary<string, DateRange> DateRanges => new Dictionary<string, DateRange> {\\n\" +\n        \"        { \\\"This month\\\", new DateRange\\n\" +\n        \"                {\\n\" +\n        \"                    Start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),\\n\" +\n        \"                    End = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddTicks(-1)\\n\" +\n        \"                }\\n\" +\n        \"            }, ...\\n\" +\n        \"        };\\n    }\\n}\";\n}\n"
  },
  {
    "path": "Demo.Shared/Pages/Single.razor",
    "content": "﻿@page \"/single\"\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Single.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Single Date Picker</h3>\n</div>\n\n<Example Text=\"@ExampleText\">\n    <DateRangePicker SingleDatePicker=\"true\" />\n</Example>\n\n@code {\n    private string ExampleText = \"<DateRangePicker SingleDatePicker=\\\"true\\\" />\";\n}"
  },
  {
    "path": "Demo.Shared/Pages/Time.razor",
    "content": "﻿@page \"/time\"\n\n@using System.Globalization\n\n<div class=\"d-md-flex flex-md-row-reverse align-items-center justify-content-between\">\n    <a class=\"btn btn-sm btn-bd-light my-2 my-md-0\" href=\"https://github.com/jdtcn/BlazorDateRangePicker/blob/master/Demo.Shared/Pages/Time.razor\"\n       title=\"View this file on GitHub\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n    <h3>Time picker</h3>\n</div>\n\n<p>TimePicker 12 Hour</p>\n\n<Example Text=\"@ExampleText1\">\n    <DateRangePicker Culture=\"@CultureInfo.GetCultureInfo(\"en-US\")\" TimePicker=\"true\" TimePicker24Hour=\"false\"\n                     DateFormat=\"@($\"{DateFormat} hh:mm tt\")\" />\n</Example>\n\n<p>TimePicker 24 Hour</p>\n\n<Example Text=\"@ExampleText2\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\" DateFormat=\"@($\"{DateFormat} HH:mm\")\" />\n</Example>\n\n<p>TimePicker minutes increment</p>\n\n<Example Text=\"@ExampleText3\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\" TimePickerIncrement=\"15\"\n                     InitialStartTime=\"RundStartTime\" InitialEndTime=\"RoundEndTime\"\n                     StartDate=\"RoundStartDate\" EndDate=\"RoundEndDate\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm\")\" OnRangeSelect=\"RoundOnRangeSelect\" />\n</Example>\n\n<p>TimePicker with seconds</p>\n\n<Example Text=\"@ExampleText4\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\" TimePickerSeconds=\"true\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm:ss\")\" />\n</Example>\n\n<p>Initial StartTime & EndTime</p>\n\n<Example Text=\"@ExampleText5\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\"\n                     InitialStartTime=\"StartTime\" InitialEndTime=\"EndTime\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm\")\" />\n</Example>\n\n<p>Initial StartTime & EndTime set by StartDate & EndDate</p>\n\n<Example Text=\"@ExampleText6\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\"\n                     @bind-StartDate=\"InitialStartDate\" @bind-EndDate=\"InitialEndDate\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm\")\" />\n</Example>\n\n<p>Single picker with time</p>\n\n<Example Text=\"@ExampleText7\">\n    <DateRangePicker SingleDatePicker=\"true\" TimePicker=\"true\" TimePicker24Hour=\"true\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm\")\" />\n</Example>\n\n<p>TimeEnabled function</p>\n\n<Example Text=\"@ExampleText8\">\n    <DateRangePicker TimePicker=\"true\" TimePicker24Hour=\"true\" TimeEnabledFunction=\"TimeEnabledFunction\"\n                     InitialStartTime=\"StartTime\" InitialEndTime=\"EndTime\"\n                     DateFormat=\"@($\"{DateFormat} HH:mm\")\" Drops=\"DropsType.Up\" />\n</Example>\n\n@code {\n    private string DateFormat => CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;\n\n    private TimeSpan RundStartTime = TimeSpan.FromHours(2).Add(TimeSpan.FromMinutes(15));\n    private TimeSpan RoundEndTime = TimeSpan.FromHours(15).Add(TimeSpan.FromMinutes(45));\n\n    private TimeSpan StartTime = TimeSpan.FromHours(8);\n    private TimeSpan EndTime = TimeSpan.FromHours(11);\n\n    private DateTimeOffset? InitialStartDate { get; set; } = DateTime.Now.AddDays(-1).Date.Add(TimeSpan.FromHours(2));\n    private DateTimeOffset? InitialEndDate { get; set; } = DateTime.Now.AddDays(1).Date.Add(TimeSpan.FromHours(15));\n\n    private DateTimeOffset? RoundStartDate { get; set; }\n    private DateTimeOffset? RoundEndDate { get; set; }\n\n    private void RoundOnRangeSelect(DateRange range)\n    {\n        RoundStartDate = range.Start.Date.Add(TimeSpan.FromHours(range.Start.Hour).Add(TimeSpan.FromMinutes((range.Start.Minute / 15) * 15)));\n        RoundEndDate = range.End.Date.Add(TimeSpan.FromHours(range.End.Hour).Add(TimeSpan.FromMinutes((range.End.Minute / 15) * 15)));\n    }\n\n    private Task<TimeSettings> TimeEnabledFunction(DateTimeOffset? day)\n    {\n        var res = new TimeSettings\n        {\n            Hours = day?.Day % 2 == 0\n                ? new int[] { 7, 8, 9, 10, 11, 12 }\n                : new int[] { 8, 9, 10, 11 },\n            Minutes = new int[] { 0, 15, 30, 45 },\n            Seconds = new int[] { 0, 60 }\n        };\n        return Task.FromResult(res);\n    }\n\n    private string ExampleText1 = \"<DateRangePicker Culture=\\\"@CultureInfo.GetCultureInfo(\\\"en-US\\\")\\\" \\n    TimePicker=\\\"true\\\" TimePicker24Hour=\\\"false\\\" \\n    DateFormat=\\\"@($\\\"{DateFormat} hh:mm tt\\\")\\\" />\";\n    private string ExampleText2 = \"<DateRangePicker TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" \\n    DateFormat=\\\"@($\\\"{DateFormat} HH:mm\\\")\\\" />\";\n    private string ExampleText3 = \"<DateRangePicker TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" TimePickerIncrement=\\\"15\\\"\\n\" +\n                    \"    InitialStartTime=\\\"RundStartTime\\\" InitialEndTime=\\\"RoundEndTime\\\"\\n\" +\n                    \"    StartDate=\\\"RoundStartDate\\\" EndDate=\\\"RoundEndDate\\\"\\n\" +\n                    \"    DateFormat=\\\"@($\\\"{DateFormat} HH:mm\\\")\\\" OnRangeSelect=\\\"RoundOnRangeSelect\\\" />\";\n    private string ExampleText4 = \"<DateRangePicker TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" \\n    TimePickerSeconds=\\\"true\\\" DateFormat=\\\"@($\\\"{DateFormat} HH:mm:ss\\\")\\\" />\";\n    private string ExampleText5 = \"<DateRangePicker TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" \\n    InitialStartTime=\\\"StartTime\\\" InitialEndTime=\\\"EndTime\\\" DateFormat=\\\"@($\\\"{DateFormat} HH:mm\\\")\\\" />\";\n    private string ExampleText6 = \"<DateRangePicker TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" \\n    @bind-StartDate=\\\"InitialStartDate\\\" @bind-EndDate=\\\"InitialEndDate\\\" \\n    DateFormat=\\\"@($\\\"{DateFormat} HH:mm\\\")\\\" />\";\n    private string ExampleText7 = \"<DateRangePicker SingleDatePicker=\\\"true\\\" TimePicker=\\\"true\\\" TimePicker24Hour=\\\"true\\\" \\n    DateFormat=\\\"@($\\\"{DateFormat} HH:mm\\\")\\\" />\";\n    private string ExampleText8 = \"<DateRangePicker TimeEnabledFunction=\\\"TimeEnabledFunction\\\" />\\n\" +\n    @\"private Task<TimeSettings> TimeEnabledFunction(DateTimeOffset? day)\\n\n{\n    var res = new TimeSettings\n    {\n        Hours = day?.Day % 2 == 0\n                ? new int[] { 8, 9, 10, 11 },\n                : new int[] { 7, 8, 9, 10, 11, 12 }\n        Minutes = new int[] { 0, 15, 30, 45 },\n        Seconds = new int[] { 0, 60 }\n    };\n    return Task.FromResult(res);\n}\";\n}\n"
  },
  {
    "path": "Demo.Shared/Shared/MainLayout.razor",
    "content": "﻿@inherits LayoutComponentBase\n@inject IJSRuntime JSRuntime\n\n<header class=\"navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar\">\n    <a class=\"navbar-brand\" href=\"/\">DateRangePicker</a>\n    <ul class=\"navbar-nav ml-md-auto\">\n        <li class=\"nav-item\">\n            <a class=\"nav-link pl-2 pr-1 mx-1 py-3 my-n2\" href=\"https://github.com/jdtcn/BlazorDateRangePicker\" target=\"_blank\" rel=\"noopener\" aria-label=\"GitHub\">\n                <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"navbar-nav-svg\" viewBox=\"0 0 512 499.36\" role=\"img\" focusable=\"false\"><title>GitHub</title><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z\"></path></svg>\n            </a>\n        </li>\n    </ul>\n</header>\n\n<div class=\"container-fluid\">\n\n    <div class=\"row flex-xl-nowrap\">\n\n        <Sidebar />\n\n        <main class=\"col-md-9 col-xl-8 py-md-3 pl-md-5 bd-content\" role=\"main\">\n            @Body\n        </main>\n    </div>\n\n</div>\n\n@code {\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        await JSRuntime.InvokeAsync<object>(\"highlightInterop.highlight\");\n        await base.OnAfterRenderAsync(firstRender);\n    }\n}"
  },
  {
    "path": "Demo.Shared/Shared/Sidebar.razor",
    "content": "﻿<div class=\"col-md-3 col-xl-2 bd-sidebar\">\n\n    <button class=\"btn bd-search-docs-toggle d-md-none p-0 mt-3 mb-3 collapsed\" type=\"button\" data-toggle=\"collapse\" @onclick=\"@(_ => Collased = !Collased)\"\n            data-target=\"#bd-docs-nav\" aria-controls=\"bd-docs-nav\" aria-expanded=\"false\" aria-label=\"Toggle docs navigation\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"30\" height=\"30\" viewBox=\"0 0 30 30\" role=\"img\" focusable=\"false\">\n            <title>Menu</title>\n            <path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"2\" d=\"M4 7h22M4 15h22M4 23h22\"></path>\n        </svg>\n    </button>\n\n    <nav class=\"collapse bd-links @(Collased ? \"\" : \"show\")\" aria-label=\"Main navigation\">\n        <div class=\"bd-toc-item active\">\n            <a class=\"bd-toc-link\" href=\"/\">\n                Examples\n            </a>\n\n            <ul class=\"nav bd-sidenav\">\n                <NavLink href=\"/\" Match=\"NavLinkMatch.All\">Quick start</NavLink>\n                <NavLink href=\"/positioning\">Positioning</NavLink>\n                <NavLink href=\"/handleEvents\">Handle events</NavLink>\n                <NavLink href=\"/single\">Single date picker</NavLink>\n                <NavLink href=\"/predefinedRanges\">Predefined date ranges</NavLink>\n                <NavLink href=\"/localization\">Localization</NavLink>\n                <NavLink href=\"/inline\">Inline mode</NavLink>\n                <NavLink href=\"/limits\">Limits</NavLink>\n                <NavLink href=\"/disable\">Disable dates</NavLink>\n                <NavLink href=\"/highlight\">Highlight dates</NavLink>\n                <NavLink href=\"/customInput\">Custom input layout</NavLink>\n                <NavLink href=\"/customDay\">Custom day layout</NavLink>\n                <NavLink href=\"/customButtons\">Custom buttons layout</NavLink>\n                <NavLink href=\"/customClickHandler\">Custom click handler</NavLink>\n                <NavLink href=\"/bothSidesSelection\">Both sides selection</NavLink>\n                <NavLink href=\"/form\">Form</NavLink>\n                <NavLink href=\"/time\">Time</NavLink>\n                <NavLink href=\"/container\">DOM Container</NavLink>\n            </ul>\n        </div>\n    </nav>\n\n</div>\n\n@code{\n    private bool Collased { get; set; } = true;\n}"
  },
  {
    "path": "Demo.Shared/_Imports.razor",
    "content": "﻿@using System.Net.Http\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.JSInterop\n@using Demo.Shared\n@using Demo.Shared.Pages\n@using BlazorDateRangePicker\n"
  },
  {
    "path": "Demo.Shared/wwwroot/css/open-iconic/FONT-LICENSE",
    "content": "SIL OPEN FONT LICENSE Version 1.1\n\nCopyright (c) 2014 Waybury\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded,\nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "Demo.Shared/wwwroot/css/open-iconic/ICON-LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Waybury\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "Demo.Shared/wwwroot/css/open-iconic/README.md",
    "content": "[Open Iconic v1.1.1](http://useiconic.com/open)\n===========\n\n### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint&mdash;ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons)\n\n\n\n## What's in Open Iconic?\n\n* 223 icons designed to be legible down to 8 pixels\n* Super-light SVG files - 61.8 for the entire set \n* SVG sprite&mdash;the modern replacement for icon fonts\n* Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats\n* Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats\n* PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.\n\n\n## Getting Started\n\n#### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections.\n\n### General Usage\n\n#### Using Open Iconic's SVGs\n\nWe like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).\n\n```\n<img src=\"/open-iconic/svg/icon-name.svg\" alt=\"icon name\">\n```\n\n#### Using Open Iconic's SVG Sprite\n\nOpen Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.\n\nAdding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `<svg>` *tag and a unique class name for each different icon in the* `<use>` *tag.*  \n\n```\n<svg class=\"icon\">\n  <use xlink:href=\"open-iconic.svg#account-login\" class=\"icon-account-login\"></use>\n</svg>\n```\n\nSizing icons only needs basic CSS. All the icons are in a square format, so just set the `<svg>` tag with equal width and height dimensions.\n\n```\n.icon {\n  width: 16px;\n  height: 16px;\n}\n```\n\nColoring icons is even easier. All you need to do is set the `fill` rule on the `<use>` tag.\n\n```\n.icon-account-login {\n  fill: #f00;\n}\n```\n\nTo learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/).\n\n#### Using Open Iconic's Icon Font...\n\n\n##### …with Bootstrap\n\nYou can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}`\n\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-bootstrap.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"oi oi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …with Foundation\n\nYou can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-foundation.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"fi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …on its own\n\nYou can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic.css\" rel=\"stylesheet\">\n```\n\n```\n<span class=\"oi\" data-glyph=\"icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n\n## License\n\n### Icons\n\nAll code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT).\n\n### Fonts\n\nAll fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web).\n"
  },
  {
    "path": "Demo.Shared/wwwroot/css/site.css",
    "content": "@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');\n\n.bd-navbar {\n    background-color: #336fb0;\n    z-index: 990;\n}\n\n    .bd-navbar .navbar-nav-svg {\n        width: 24px;\n        height: 24px;\n    }\n\n\n.bd-sidebar .nav > .active:hover > a, .bd-sidebar .nav > a.active {\n    font-weight: 600;\n    color: rgba(0,0,0,.85);\n    background-color: transparent;\n}\n\n.bd-sidebar .nav > a:hover {\n    color: rgba(0,0,0,.85);\n    text-decoration: none;\n    background-color: transparent;\n}\n\n.bd-sidebar .nav > a {\n    display: block;\n    padding: .25rem 1.5rem;\n    font-size: 90%;\n    color: rgba(0,0,0,.65);\n}\n\n.btn-bd-light:active, .btn-bd-light:hover, .show > .btn-bd-light {\n    color: #336fb0;\n    background-color: #fff;\n    border-color: #336fb0;\n}\n\n.hljs {\n    padding: 0;\n    background: transparent;\n}\n"
  },
  {
    "path": "Demo.Shared/wwwroot/highlight/cshtml-razor.js",
    "content": "/*\n * Language: cshtml-razor\n * Requires: xml.js, cs.js, css.js, javascript.js\n * Author: Roman Resh <romanresh@live.com>\n*/\n\nvar module = module ? module : {};\n\nfunction getXmlBlocks(hljs, additional_blocks) {\n    var xml_comment = hljs.COMMENT(\n        '<!--',\n        '-->',\n        {\n            relevance: 10\n        }\n    );\n    var string = {\n        className: 'string',\n        variants: [\n            { begin: /\"/, end: /\"/ },\n            { begin: /'/, end: /'/ },\n            { begin: /[^\\s\"'=<>`]+/ }\n        ],\n        contains: additional_blocks\n    };\n    var xml_tag_internal = {\n        endsWithParent: true,\n        illegal: /</,\n        relevance: 0,\n        contains: [\n            {\n                className: 'attr',\n                begin: '[A-Za-z0-9\\\\._:-]+',\n                relevance: 0\n            },\n            {\n                begin: /=\\s*/,\n                relevance: 0,\n                contains: [string]\n            }\n        ]\n    };\n    return [\n        {\n            className: 'meta',\n            begin: '<!DOCTYPE', end: '>',\n            relevance: 10,\n            contains: [{ begin: '\\\\[', end: '\\\\]' }]\n        },\n        xml_comment,\n        {\n            begin: '<\\\\!\\\\[CDATA\\\\[', end: '\\\\]\\\\]>',\n            relevance: 10\n        },\n        {\n            className: 'meta',\n            begin: /<\\?xml/, end: /\\?>/, relevance: 10\n        },\n        {\n            className: 'tag',\n            begin: '<style(?=\\\\s|>|$)', end: '>',\n            keywords: { name: 'style' },\n            contains: [xml_tag_internal],\n            starts: {\n                end: '</style>', returnEnd: true,\n                subLanguage: ['css', 'xml']\n            }\n        },\n        {\n            className: 'tag',\n            begin: '<script(?=\\\\s|>|$)', end: '>',\n            keywords: { name: 'script' },\n            contains: [xml_tag_internal],\n            starts: {\n                end: '\\<\\/script\\>', returnEnd: true,\n                subLanguage: ['actionscript', 'javascript', 'handlebars', 'xml']\n            }\n        },\n        {\n            className: 'tag',\n            begin: '</?', end: '/?>',\n            contains: [\n                {\n                    className: 'name', begin: /[^\\/><\\s]+/, relevance: 0\n                },\n                xml_tag_internal\n            ]\n        }\n    ].concat(additional_blocks);\n}\nfunction hljsDefineCshtmlRazor(hljs) {\n    var SPECIAL_SYMBOL_CLASSNAME = \"built_in\";\n    var CONTENT_REPLACER = {};\n    var closed_brace = {\n        begin: \"}\",\n        className: SPECIAL_SYMBOL_CLASSNAME,\n        endsParent: true\n    };\n    var braces = {\n        begin: \"{\",\n        end: \"}\",\n        contains: [hljs.QUOTE_STRING_MODE, 'self']\n    };\n    var razor_comment = hljs.COMMENT(\n        '@\\\\*',\n        '\\\\*@',\n        {\n            relevance: 10\n        }\n    );\n    var razor_inline_expresion = {\n        begin: \"@[a-zA-Z]+\",\n        returnBegin: true,\n        subLanguage: 'csharp',\n        end: \"(\\\\r|\\\\n|<|\\\\s|\\\"|')\",\n        contains: [\n            {\n                begin: '@',\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            {\n                begin: '\".*(?!$)\"',\n                skip: true\n            },\n            {\n                begin: '\"',\n                endsParent: true\n            }\n        ],\n        returnEnd: true\n    };\n    var razor_text_block = {\n        begin: \"[@]{0,1}<text>\",\n        returnBegin: true,\n        end: \"</text>\",\n        returnEnd: true,\n        subLanguage: \"cshtml-razor\",\n        contains: [\n            {\n                begin: \"[@]{0,1}<text>\",\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            {\n                begin: \"</text>\",\n                className: SPECIAL_SYMBOL_CLASSNAME,\n                endsParent: true\n            }\n        ]\n    };\n    var razor_escape_at = {\n        variants: [\n            { begin: \"@@\" },\n            { begin: \"[a-zA-Z]+@\" }\n        ],\n        skip: true\n    };\n\n    var razor_parentheses_block = {\n        begin: \"@\\\\(\",\n        end: \"\\\\)\",\n        returnBegin: true,\n        returnEnd: true,\n        subLanguage: \"csharp\",\n        contains: [\n            {\n                begin: \"@\\\\(\",\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            {\n                begin: \"\\\\(\",\n                end: \"\\\\)\",\n                subLanguage: 'csharp',\n                contains: [hljs.QUOTE_STRING_MODE, 'self', razor_text_block]\n            },\n            razor_text_block,\n            {\n                begin: \"\\\\)\",\n                className: SPECIAL_SYMBOL_CLASSNAME,\n                endsParent: true\n            }\n        ]\n    };\n    var xml_blocks = getXmlBlocks(hljs, [razor_inline_expresion, razor_parentheses_block]);\n    var razor_directives = {\n        begin: \"^\\\\s*@(page|model|using|inherits|inject)[^\\\\r\\\\n{\\\\(]*$\",\n        end: \"$\",\n        returnBegin: true,\n        returnEnd: true,\n        contains: [\n            {\n                begin: \"^\\\\s*@(page|model|using|inherits|inject)\",\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            {\n                variants: [\n                    { begin: \"\\\\r|\\\\n\", endsParent: true},\n                    { begin: \"\\\\s[^\\\\r\\\\n]+\", end: \"$\" },\n                    { begin: \"$\" }\n                ],\n                className: \"type\",\n                endsParent: true\n            }\n        ]\n    };\n    var razor_block = {\n        begin: \"@\\\\{\",\n        returnBegin: true,\n        returnEnd: true,\n        end: \"\\\\}\",\n        subLanguage: 'csharp',\n        contains: [\n            {\n                begin: \"@\\\\{\",\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            CONTENT_REPLACER,\n            closed_brace\n        ]\n    };\n    var razor_helper_block = {\n        begin: \"^\\\\s*@helper[\\\\s]*[^{]+[\\\\s]*{\",\n        returnBegin: true,\n        returnEnd: true,\n        end: \"}\",\n        subLanguage: \"cshtml-razor\",\n        contains: [\n            { begin: \"@helper\", className: SPECIAL_SYMBOL_CLASSNAME },\n            { begin: \"{\", className: SPECIAL_SYMBOL_CLASSNAME },\n            closed_brace\n        ]\n    };\n    var razor_code_block_variants = [\n        { begin: \"@for[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@if[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@switch[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@while[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@using[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@lock[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" },\n        { begin: \"@foreach[\\\\s]*\\\\([^{]+[\\\\s]*{\", end: \"}\" }\n    ];\n    var razor_code_block = {\n        variants: razor_code_block_variants,\n        returnBegin: true,\n        returnEnd: true,\n        end: \"}\",\n        subLanguage: 'csharp',\n        contains: [\n            {\n                variants: razor_code_block_variants.map(function (v) { return { begin: v.begin }; }),\n                returnBegin: true,\n                contains: [\n                    { begin: \"@\", className: SPECIAL_SYMBOL_CLASSNAME },\n                    {\n                        variants: razor_code_block_variants.map(function (v) { return { begin: v.begin.substr(1, v.begin.length - 2) }; }),\n                        subLanguage: \"csharp\"\n                    },\n                    { begin: \"{\", className: SPECIAL_SYMBOL_CLASSNAME }\n                ]\n            },\n            CONTENT_REPLACER,\n            {\n                variants: [\n                    { begin: \"}[\\\\s]*else\\\\sif[\\\\s]*\\\\([^{]+[\\\\s]*{\" },\n                    { begin: \"}[\\\\s]*else[\\\\s]*{\" }\n                ],\n                returnBegin: true,\n                contains: [\n                    { begin: \"}\", className: SPECIAL_SYMBOL_CLASSNAME },\n                    {\n                        variants: [\n                            { begin: \"[\\\\s]*else\\\\sif[\\\\s]*\\\\([^{]+[\\\\s]*{\" },\n                            { begin: \"[\\\\s]*else[\\\\s]*\" }\n                        ],\n                        subLanguage: \"csharp\"\n                    },\n                    {\n                        begin: \"{\",\n                        className: SPECIAL_SYMBOL_CLASSNAME\n                    }\n                ]\n            },\n            braces,\n            closed_brace\n        ]\n    };\n    var section_begin = \"@section[\\\\s]+[a-zA-Z0-9]+[\\\\s]*{\";\n    var razor_try_block = {\n        begin: \"@try[\\\\s]*{\",\n        end: \"}\",\n        returnBegin: true,\n        returnEnd: true,\n        subLanguage: \"csharp\",\n        contains: [\n            { begin: \"@\", className: SPECIAL_SYMBOL_CLASSNAME },\n            { begin: \"try[\\\\s]*{\", subLanguage: \"csharp\" },\n            {\n                variants: [\n                    { begin: \"}[\\\\s]*catch[\\\\s]*\\\\([^\\\\)]+\\\\)[\\\\s]*{\" },\n                    { begin: \"}[\\\\s]*finally[\\\\s]*{\" }\n                ],\n                returnBegin: true,\n                contains: [\n                    { begin: \"}\", className: SPECIAL_SYMBOL_CLASSNAME },\n                    {\n                        variants: [\n                            { begin: \"[\\\\s]*catch[\\\\s]*\\\\([^\\\\)]+\\\\)[\\\\s]*\", },\n                            { begin: \"[\\\\s]*finally[\\\\s]*\", },\n                        ],\n                        subLanguage: \"csharp\"\n                    },\n                    { begin: \"{\", className: SPECIAL_SYMBOL_CLASSNAME }\n                ]\n            },\n            CONTENT_REPLACER,\n            braces,\n            closed_brace\n        ]\n    };\n    var razor_section_block = {\n        begin: section_begin,\n        returnBegin: true,\n        returnEnd: true,\n        end: \"}\",\n        subLanguage: 'cshtml-razor',\n        contains: [\n            {\n                begin: section_begin,\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            braces,\n            closed_brace\n        ]\n    };\n    var rasor_await = {\n        begin: \"@await \",\n        returnBegin: true,\n        subLanguage: 'csharp',\n        end: \"(\\\\r|\\\\n|<|\\\\s)\",\n        contains: [\n            {\n                begin: \"@await \",\n                className: SPECIAL_SYMBOL_CLASSNAME\n            },\n            {\n                begin: \"[<\\\\r\\\\n]\",\n                endsParent: true\n            }\n        ]\n    };\n\n    var result = {\n        aliases: ['cshtml', 'razor', 'razor-cshtml'],\n        contains: [\n            razor_directives,\n            razor_helper_block,\n            razor_block,\n            razor_code_block,\n            razor_section_block,\n            rasor_await,\n            razor_try_block,\n            razor_escape_at,\n            razor_text_block,\n            razor_comment,\n            razor_parentheses_block,\n            {\n                className: 'meta',\n                begin: '<!DOCTYPE', end: '>',\n                relevance: 10,\n                contains: [{ begin: '\\\\[', end: '\\\\]' }]\n            },\n            {\n                begin: '<\\\\!\\\\[CDATA\\\\[', end: '\\\\]\\\\]>',\n                relevance: 10\n            }\n        ]\n    };\n    result.contains = result.contains.concat(xml_blocks);\n\n    [razor_block, razor_code_block, razor_try_block]\n        .forEach(function (mode) {\n            var razorModes = result.contains.filter(function (c) { return c !== mode; });\n            var replacerIndex = mode.contains.indexOf(CONTENT_REPLACER);\n            mode.contains.splice.apply(mode.contains, [replacerIndex, 1].concat(razorModes));\n        });\n\n    return result;\n}\n\nmodule.exports = function (hljs) {\n    hljs.registerLanguage('cshtml-razor', hljsDefineCshtmlRazor);\n};\n\nmodule.exports.definer = hljsDefineCshtmlRazor;\n"
  },
  {
    "path": "Demo.Shared/wwwroot/highlight/default.css",
    "content": "/*\n\nOriginal highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>\n\n*/\n\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  background: #F0F0F0;\n}\n\n\n/* Base color: saturation 0; */\n\n.hljs,\n.hljs-subst {\n  color: #444;\n}\n\n.hljs-comment {\n  color: #888888;\n}\n\n.hljs-keyword,\n.hljs-attribute,\n.hljs-selector-tag,\n.hljs-meta-keyword,\n.hljs-doctag,\n.hljs-name {\n  font-weight: bold;\n}\n\n\n/* User color: hue: 0 */\n\n.hljs-type,\n.hljs-string,\n.hljs-number,\n.hljs-selector-id,\n.hljs-selector-class,\n.hljs-quote,\n.hljs-template-tag,\n.hljs-deletion {\n  color: #880000;\n}\n\n.hljs-title,\n.hljs-section {\n  color: #880000;\n  font-weight: bold;\n}\n\n.hljs-regexp,\n.hljs-symbol,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-link,\n.hljs-selector-attr,\n.hljs-selector-pseudo {\n  color: #BC6060;\n}\n\n\n/* Language color: hue: 90; */\n\n.hljs-literal {\n  color: #78A960;\n}\n\n.hljs-built_in,\n.hljs-bullet,\n.hljs-code,\n.hljs-addition {\n  color: #397300;\n}\n\n\n/* Meta color: hue: 200 */\n\n.hljs-meta {\n  color: #1f7199;\n}\n\n.hljs-meta-string {\n  color: #4d99bf;\n}\n\n\n/* Misc effects */\n\n.hljs-emphasis {\n  font-style: italic;\n}\n\n.hljs-strong {\n  font-weight: bold;\n}\n"
  },
  {
    "path": "Demo.Shared/wwwroot/highlight/highlight.pack.js",
    "content": "/*\n  Highlight.js 10.2.0 (da7d149b)\n  License: BSD-3-Clause\n  Copyright (c) 2006-2020, Ivan Sagalaev\n*/\nvar hljs=function(){\"use strict\";function e(n){Object.freeze(n);var t=\"function\"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||\"object\"!=typeof n[r]&&\"function\"!=typeof n[r]||t&&(\"caller\"===r||\"callee\"===r||\"arguments\"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:\"start\",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:\"stop\",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s=\"\",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:\"start\"===n[0].event?e:n:e.length?e:n}function c(e){s+=\"<\"+a(e)+[].map.call(e.attributes,(function(e){return\" \"+e.nodeName+'=\"'+t(e.value)+'\"'})).join(\"\")+\">\"}function u(e){s+=\"</\"+a(e)+\">\"}function g(e){(\"start\"===e.event?c:u)(e.node)}for(;e.length||n.length;){var d=l();if(s+=t(r.substring(i,d[0].offset)),i=d[0].offset,d===e){o.reverse().forEach(u);do{g(d.splice(0,1)[0]),d=l()}while(d===e&&d.length&&d[0].offset===i);o.reverse().forEach(c)}else\"start\"===d[0].event?o.push(d[0].node):o.pop(),g(d.splice(0,1)[0])}return s+t(r.substr(i))}});const s=\"</span>\",o=e=>!!e.kind;class l{constructor(e,n){this.buffer=\"\",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=`<span class=\"${e}\">`}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return\"string\"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){\"string\"!=typeof e&&e.children&&(e.children.every(e=>\"string\"==typeof e)?e.children=[e.children.join(\"\")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){\"\"!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){\"\"!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function g(e){return e?\"string\"==typeof e?e:e.source:null}const d=\"(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",h={begin:\"\\\\\\\\[\\\\s\\\\S]\",relevance:0},f={className:\"string\",begin:\"'\",end:\"'\",illegal:\"\\\\n\",contains:[h]},p={className:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\",contains:[h]},m={begin:/\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/},b=function(e,n,t={}){var a=r({className:\"comment\",begin:e,end:n,contains:[]},t);return a.contains.push(m),a.contains.push({className:\"doctag\",begin:\"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):\",relevance:0}),a},v=b(\"//\",\"$\"),x=b(\"/\\\\*\",\"\\\\*/\"),E=b(\"#\",\"$\");var _=Object.freeze({__proto__:null,IDENT_RE:\"[a-zA-Z]\\\\w*\",UNDERSCORE_IDENT_RE:\"[a-zA-Z_]\\\\w*\",NUMBER_RE:\"\\\\b\\\\d+(\\\\.\\\\d+)?\",C_NUMBER_RE:d,BINARY_NUMBER_RE:\"\\\\b(0b[01]+)\",RE_STARTERS_RE:\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",SHEBANG:(e={})=>{const n=/^#![ ]*\\//;return e.binary&&(e.begin=function(...e){return e.map(e=>g(e)).join(\"\")}(n,/.*\\b/,e.binary,/\\b.*/)),r({className:\"meta\",begin:n,end:/$/,relevance:0,\"on:begin\":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:m,COMMENT:b,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:\"number\",begin:\"\\\\b\\\\d+(\\\\.\\\\d+)?\",relevance:0},C_NUMBER_MODE:{className:\"number\",begin:d,relevance:0},BINARY_NUMBER_MODE:{className:\"number\",begin:\"\\\\b(0b[01]+)\",relevance:0},CSS_NUMBER_MODE:{className:\"number\",begin:\"\\\\b\\\\d+(\\\\.\\\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",relevance:0},REGEXP_MODE:{begin:/(?=\\/[^/\\n]*\\/)/,contains:[{className:\"regexp\",begin:/\\//,end:/\\/[gimuy]*/,illegal:/\\n/,contains:[h,{begin:/\\[/,end:/\\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:\"title\",begin:\"[a-zA-Z]\\\\w*\",relevance:0},UNDERSCORE_TITLE_MODE:{className:\"title\",begin:\"[a-zA-Z_]\\\\w*\",relevance:0},METHOD_GUARD:{begin:\"\\\\.\\\\s*[a-zA-Z_]\\\\w*\",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{\"on:begin\":(e,n)=>{n.data._beginMatch=e[1]},\"on:end\":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),w=\"of and for in not or if then\".split(\" \");function N(e,n){return n?+n:function(e){return w.includes(e.toLowerCase())}(e)?0:1}const y={props:[\"language\",\"code\",\"autodetect\"],data:function(){return{detectedLanguage:\"\",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?\"\":\"hljs \"+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!hljs.getLanguage(this.language))return console.warn(`The language \"${this.language}\" you specified could not be found.`),this.unknownLanguage=!0,t(this.code);let e;return this.autoDetect?(e=hljs.highlightAuto(this.code),this.detectedLanguage=e.language):(e=hljs.highlight(this.language,this.code,this.ignoreIllegals),this.detectectLanguage=this.language),e.value},autoDetect(){return!(this.language&&(e=this.autodetect,!e&&\"\"!==e));var e},ignoreIllegals:()=>!0},render(e){return e(\"pre\",{},[e(\"code\",{class:this.className,domProps:{innerHTML:this.highlighted}})])}},R={install(e){e.component(\"highlightjs\",y)}},k=t,O=r,{nodeStream:M,mergeStreams:L}=i,T=Symbol(\"nomatch\");return function(t){var a=[],i=Object.create(null),s=Object.create(null),o=[],l=!0,c=/(^(<[^>]+>|\\t|)+|\\n)/gm,d=\"Could not find the language '{}', did you forget to load/include a language module?\";const h={disableAutodetect:!0,name:\"Plain text\",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\\blang(?:uage)?-([\\w-]+)\\b/i,classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function m(e,n,t,r){var a={code:n,language:e};S(\"before:highlight\",a);var i=a.result?a.result:b(a.language,a.code,t,r);return i.code=a.code,S(\"after:highlight\",i),i}function b(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=R.subLanguage?function(){if(\"\"!==L){var e=null;if(\"string\"==typeof R.subLanguage){if(!i[R.subLanguage])return void M.addText(L);e=b(R.subLanguage,L,!0,O[R.subLanguage]),O[R.subLanguage]=e.top}else e=v(L,R.subLanguage.length?R.subLanguage:null);R.relevance>0&&(j+=e.relevance),M.addSublanguage(e.emitter,e.language)}}():function(){if(!R.keywords)return void M.addText(L);let e=0;R.keywordPatternRe.lastIndex=0;let n=R.keywordPatternRe.exec(L),t=\"\";for(;n;){t+=L.substring(e,n.index);const r=c(R,n);if(r){const[e,a]=r;M.addText(t),t=\"\",j+=a,M.addKeyword(n[0],e)}else t+=n[0];e=R.keywordPatternRe.lastIndex,n=R.keywordPatternRe.exec(L)}t+=L.substr(e),M.addText(t)}(),L=\"\"}function h(e){return e.className&&M.openNode(e.className),R=Object.create(e,{parent:{value:R}})}function p(e){return 0===R.matcher.regexIndex?(L+=e[0],1):(I=!0,0)}var m={};function x(t,r){var i=r&&r[0];if(L+=t,null==i)return u(),0;if(\"begin\"===m.type&&\"end\"===r.type&&m.index===r.index&&\"\"===i){if(L+=o.slice(r.index,r.index+1),!l){const n=Error(\"0 width match regex\");throw n.languageName=e,n.badRule=m.rule,n}return 1}if(m=r,\"begin\"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r[\"on:begin\"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\"),\"m\")),r.skip?L+=t:(r.excludeBegin&&(L+=t),u(),r.returnBegin||r.excludeBegin||(L=t)),h(r),r.returnBegin?0:t.length}(r);if(\"illegal\"===r.type&&!a){const e=Error('Illegal lexeme \"'+i+'\" for mode \"'+(R.className||\"<unnamed>\")+'\"');throw e.mode=R,e}if(\"end\"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t[\"on:end\"]){const e=new n(t);t[\"on:end\"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(R,e,r);if(!a)return T;var i=R;i.skip?L+=t:(i.returnEnd||i.excludeEnd||(L+=t),u(),i.excludeEnd&&(L=t));do{R.className&&M.closeNode(),R.skip||R.subLanguage||(j+=R.relevance),R=R.parent}while(R!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==T)return s}if(\"illegal\"===r.type&&\"\"===i)return 1;if(S>1e5&&S>3*r.index)throw Error(\"potential infinite loop, way more iterations than matches\");return L+=i,i.length}var E=y(e);if(!E)throw console.error(d.replace(\"{}\",e)),Error('Unknown language: \"'+e+'\"');var _=function(e){function n(n,t){return RegExp(g(n),\"m\"+(e.case_insensitive?\"i\":\"\")+(t?\"g\":\"\"))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+\"|\").exec(\"\").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n=\"|\"){for(var t=/\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./,r=0,a=\"\",i=0;i<e.length;i++){var s=r+=1,o=g(e[i]);for(i>0&&(a+=n),a+=\"(\";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),\"\\\\\"===l[0][0]&&l[1]?a+=\"\\\\\"+(+l[1]+s):(a+=l[0],\"(\"===l[0]&&r++)}a+=\")\"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){return 0!=this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),\"begin\"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];\".\"!==t&&\".\"!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes(\"self\"))throw Error(\"ERR: contains `self` is not supported at the top-level of a language.  See documentation.\");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if(\"object\"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return\"string\"==typeof e?r(\"keyword\",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(\" \").forEach((function(n){var r=n.split(\"|\");t[r[0]]=[e,N(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error(\"ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) \");return l.keywordPatternRe=n(s.lexemes||c||/\\w+/,!0),o&&(s.beginKeywords&&(s.begin=\"\\\\b(\"+s.beginKeywords.split(\" \").join(\"|\")+\")(?=\\\\b|\\\\s)\",s.__beforeBegin=i),s.begin||(s.begin=/\\B|\\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\\B|\\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=g(s.end)||\"\",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?\"|\":\"\")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}(\"self\"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:\"begin\"})),e.terminator_end&&n.addRule(e.terminator_end,{type:\"end\"}),e.illegal&&n.addRule(e.illegal,{type:\"illegal\"}),n}(l),l}(e)}(E),w=\"\",R=s||_,O={},M=new f.__emitter(f);!function(){for(var e=[],n=R;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>M.openNode(e))}();var L=\"\",j=0,A=0,S=0,I=!1;try{for(R.matcher.considerAll();;){S++,I?I=!1:(R.matcher.lastIndex=A,R.matcher.considerAll());const e=R.matcher.exec(o);if(!e&&R.matcher.resumingScanAtSamePosition()){L+=o[A],A+=1;continue}if(!e)break;const n=x(o.substring(A,e.index),e);A=e.index+n}return x(o.substr(A)),M.closeAllNodes(),M.finalize(),w=M.toHTML(),{relevance:j,value:w,language:e,illegal:!1,emitter:M,top:R}}catch(n){if(n.message&&n.message.includes(\"Illegal\"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(A-100,A+100),mode:n.mode},sofar:w,relevance:0,value:k(o),emitter:M};if(l)return{illegal:!1,relevance:0,value:k(o),emitter:M,language:e,top:R,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:k(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(y).filter(A).forEach((function(n){var a=b(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>\"\\n\"===e?f.useBR?\"<br>\":e:f.tabReplace?e.replace(/\\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+\" \";n+=e.parentNode?e.parentNode.className:\"\";const t=f.languageDetectRe.exec(n);if(t){var r=y(t[1]);return r||(console.warn(d.replace(\"{}\",t[1])),console.warn(\"Falling back to no-highlight mode for this block.\",e)),r?t[1]:\"no-highlight\"}return n.split(/\\s+/).find(e=>p(e)||y(e))}(e);if(p(t))return;S(\"before:highlightBlock\",{block:e,language:t}),f.useBR?(n=document.createElement(\"div\")).innerHTML=e.innerHTML.replace(/\\n/g,\"\").replace(/<br[ /]*>/g,\"\\n\"):n=e;const r=n.textContent,a=t?m(t,r,!0):v(r),i=M(n);if(i.length){const e=document.createElement(\"div\");e.innerHTML=a.value,a.value=L(i,M(e),r)}a.value=x(a.value),S(\"after:highlightBlock\",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\\bhljs\\b/)||a.push(\"hljs\"),e.includes(r)||a.push(r),a.join(\" \").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const w=()=>{if(!w.called){w.called=!0;var e=document.querySelectorAll(\"pre code\");a.forEach.call(e,E)}};function y(e){return e=(e||\"\").toLowerCase(),i[e]||i[s[e]]}function j(e,{languageName:n}){\"string\"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function A(e){var n=y(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:m,highlightAuto:v,fixMarkup:function(e){return console.warn(\"fixMarkup is deprecated and will be removed entirely in v11.0\"),console.warn(\"Please see https://github.com/highlightjs/highlight.js/issues/2534\"),x(e)},highlightBlock:E,configure:function(e){f=O(f,e)},initHighlighting:w,initHighlightingOnLoad:function(){window.addEventListener(\"DOMContentLoaded\",w,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error(\"Language definition for '{}' could not be registered.\".replace(\"{}\",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&j(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:y,registerAliases:j,requireLanguage:function(e){var n=y(e);if(n)return n;throw Error(\"The '{}' language is required, but not loaded.\".replace(\"{}\",e))},autoDetection:A,inherit:O,addPlugin:function(e){o.push(e)},vuePlugin:R}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString=\"10.2.0\";for(const n in _)\"object\"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();\"object\"==typeof exports&&\"undefined\"!=typeof module&&(module.exports=hljs);hljs.registerLanguage(\"python\",function(){\"use strict\";return function(e){var n={keyword:\"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10\",built_in:\"Ellipsis NotImplemented\",literal:\"False None True\"},a={className:\"meta\",begin:/^(>>>|\\.\\.\\.) /},i={className:\"subst\",begin:/\\{/,end:/\\}/,keywords:n,illegal:/#/},s={begin:/\\{\\{/,relevance:0},r={className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?\"\"\"/,end:/\"\"\"/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(fr|rf|f)\"\"\"/,end:/\"\"\"/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)\"/,end:/\"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)\"/,end:/\"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,s,i]},{begin:/(fr|rf|f)\"/,end:/\"/,contains:[e.BACKSLASH_ESCAPE,s,i]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},l={className:\"number\",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+\"[lLjJ]?\"},{begin:\"\\\\b(0o[0-7]+)[lLjJ]?\"},{begin:e.C_NUMBER_RE+\"[lLjJ]?\"}]},t={className:\"params\",variants:[{begin:/\\(\\s*\\)/,skip:!0,className:null},{begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,contains:[\"self\",a,l,r,e.HASH_COMMENT_MODE]}]};return i.contains=[r,l,a],{name:\"Python\",aliases:[\"py\",\"gyp\",\"ipython\"],keywords:n,illegal:/(<\\/|->|\\?)|=>/,contains:[a,l,{beginKeywords:\"if\",relevance:0},r,e.HASH_COMMENT_MODE,{variants:[{className:\"function\",beginKeywords:\"def\"},{className:\"class\",beginKeywords:\"class\"}],end:/:/,illegal:/[${=;\\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,t,{begin:/->/,endsWithParent:!0,keywords:\"None\"}]},{className:\"meta\",begin:/^[\\t ]*@/,end:/$/},{begin:/\\b(print|exec)\\(/}]}}}());hljs.registerLanguage(\"python-repl\",function(){\"use strict\";return function(n){return{aliases:[\"pycon\"],contains:[{className:\"meta\",starts:{end:/ |$/,starts:{end:\"$\",subLanguage:\"python\"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\\.\\.\\.(?=[ ]|$)/}]}]}}}());hljs.registerLanguage(\"xml\",function(){\"use strict\";return function(e){var n={className:\"symbol\",begin:\"&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;\"},a={begin:\"\\\\s\",contains:[{className:\"meta-keyword\",begin:\"#?[a-z_][a-z1-9_-]+\",illegal:\"\\\\n\"}]},s=e.inherit(a,{begin:\"\\\\(\",end:\"\\\\)\"}),t=e.inherit(e.APOS_STRING_MODE,{className:\"meta-string\"}),i=e.inherit(e.QUOTE_STRING_MODE,{className:\"meta-string\"}),c={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:\"attr\",begin:\"[A-Za-z0-9\\\\._:-]+\",relevance:0},{begin:/=\\s*/,relevance:0,contains:[{className:\"string\",endsParent:!0,variants:[{begin:/\"/,end:/\"/,contains:[n]},{begin:/'/,end:/'/,contains:[n]},{begin:/[^\\s\"'=<>`]+/}]}]}]};return{name:\"HTML, XML\",aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xjb\",\"xsd\",\"xsl\",\"plist\",\"wsf\",\"svg\"],case_insensitive:!0,contains:[{className:\"meta\",begin:\"<![a-z]\",end:\">\",relevance:10,contains:[a,i,t,s,{begin:\"\\\\[\",end:\"\\\\]\",contains:[{className:\"meta\",begin:\"<![a-z]\",end:\">\",contains:[a,s,i,t]}]}]},e.COMMENT(\"\\x3c!--\",\"--\\x3e\",{relevance:10}),{begin:\"<\\\\!\\\\[CDATA\\\\[\",end:\"\\\\]\\\\]>\",relevance:10},n,{className:\"meta\",begin:/<\\?xml/,end:/\\?>/,relevance:10},{className:\"tag\",begin:\"<style(?=\\\\s|>)\",end:\">\",keywords:{name:\"style\"},contains:[c],starts:{end:\"</style>\",returnEnd:!0,subLanguage:[\"css\",\"xml\"]}},{className:\"tag\",begin:\"<script(?=\\\\s|>)\",end:\">\",keywords:{name:\"script\"},contains:[c],starts:{end:\"<\\/script>\",returnEnd:!0,subLanguage:[\"javascript\",\"handlebars\",\"xml\"]}},{className:\"tag\",begin:\"</?\",end:\"/?>\",contains:[{className:\"name\",begin:/[^\\/><\\s]+/,relevance:0},c]}]}}}());hljs.registerLanguage(\"php\",function(){\"use strict\";return function(e){var r={begin:\"\\\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\"},t={className:\"meta\",variants:[{begin:/<\\?php/,relevance:10},{begin:/<\\?[=]?/},{begin:/\\?>/}]},a={className:\"subst\",variants:[{begin:/\\$\\w+/},{begin:/\\{\\$/,end:/\\}/}]},n=e.inherit(e.APOS_STRING_MODE,{illegal:null}),i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(a)}),o=e.END_SAME_AS_BEGIN({begin:/<<<[ \\t]*(\\w+)\\n/,end:/[ \\t]*(\\w+)\\b/,contains:e.QUOTE_STRING_MODE.contains.concat(a)}),l={className:\"string\",contains:[e.BACKSLASH_ESCAPE,t],variants:[e.inherit(n,{begin:\"b'\",end:\"'\"}),e.inherit(i,{begin:'b\"',end:'\"'}),i,n,o]},s={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]},c={keyword:\"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list new object or private protected public real return string switch throw trait try unset use var void while xor yield\",literal:\"false null true\",built_in:\"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Throwable Traversable WeakReference Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass\"};return{aliases:[\"php\",\"php3\",\"php4\",\"php5\",\"php6\",\"php7\"],case_insensitive:!0,keywords:c,contains:[e.HASH_COMMENT_MODE,e.COMMENT(\"//\",\"$\",{contains:[t]}),e.COMMENT(\"/\\\\*\",\"\\\\*/\",{contains:[{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.COMMENT(\"__halt_compiler.+?;\",!1,{endsWithParent:!0,keywords:\"__halt_compiler\"}),t,{className:\"keyword\",begin:/\\$this\\b/},r,{begin:/(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/},{className:\"function\",beginKeywords:\"fn function\",end:/[;{]/,excludeEnd:!0,illegal:\"[$%\\\\[]\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",excludeBegin:!0,excludeEnd:!0,keywords:c,contains:[\"self\",r,e.C_BLOCK_COMMENT_MODE,l,s]}]},{className:\"class\",beginKeywords:\"class interface\",end:\"{\",excludeEnd:!0,illegal:/[:\\(\\$\"]/,contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"namespace\",end:\";\",illegal:/[\\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"use\",end:\";\",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:\"=>\"},l,s]}}}());hljs.registerLanguage(\"php-template\",function(){\"use strict\";return function(n){return{name:\"PHP template\",subLanguage:\"xml\",contains:[{begin:/<\\?(php|=)?/,end:/\\?>/,subLanguage:\"php\",contains:[{begin:\"/\\\\*\",end:\"\\\\*/\",skip:!0},{begin:'b\"',end:'\"',skip:!0},{begin:\"b'\",end:\"'\",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}}}());"
  },
  {
    "path": "Demo.Shared/wwwroot/highlight/highlightInterop.js",
    "content": "﻿window.highlightInterop = {\n    highlight: function () {\n        document.querySelectorAll('pre code').forEach((block) => {\n            hljs.highlightBlock(block);\n        });\n    }\n}"
  },
  {
    "path": "Demo.Shared/wwwroot/highlight/vs.css",
    "content": "/*\n\nVisual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name>\n\n*/\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  background: white;\n  color: black;\n}\n\n.hljs-comment,\n.hljs-quote,\n.hljs-variable {\n  color: #008000;\n}\n\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-built_in,\n.hljs-name,\n.hljs-tag {\n  color: #00f;\n}\n\n.hljs-string,\n.hljs-title,\n.hljs-section,\n.hljs-attribute,\n.hljs-literal,\n.hljs-template-tag,\n.hljs-template-variable,\n.hljs-type,\n.hljs-addition {\n  color: #a31515;\n}\n\n.hljs-deletion,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-meta {\n  color: #2b91af;\n}\n\n.hljs-doctag {\n  color: #808080;\n}\n\n.hljs-attr {\n  color: #f00;\n}\n\n.hljs-symbol,\n.hljs-bullet,\n.hljs-link {\n  color: #00b0e8;\n}\n\n\n.hljs-emphasis {\n  font-style: italic;\n}\n\n.hljs-strong {\n  font-weight: bold;\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Sergey Zaikin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "Date Range Picker for [Blazor](https://blazor.net/)\r\n=====================\r\n\r\n[![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/BlazorDateRangePicker.svg)](https://www.nuget.org/packages/BlazorDateRangePicker/)\r\n\r\n![https://github.com/jdtcn/BlazorDateRangePicker](https://habrastorage.org/webt/ku/ye/jt/kuyejt2khntesrw6asg9hvwiri0.png)\r\n\r\n## [Live Demo](https://blazordaterangepicker.azurewebsites.net/)\r\n\r\nThis date range picker component is a port of js [DateRangePicker](https://github.com/dangrossman/daterangepicker/), rewritten using C# as a Razor Component.\r\nIt creates a dropdown menu from which a user can select a range of dates.\r\n\r\nThere is no dependency with jquery, moment, or bootstrap\r\n\r\nFeatures include limiting the selectable date range, localizable strings and date formats,\r\na single date picker mode, and predefined date ranges.\r\n\r\nJS Interop is used for popup positioning and outside click handling. With future releases of ASP.NET Core Blazor it will be possible without js.\r\n\r\n## Get Started\r\n\r\nDownload library from NuGet in the NuGet Package Manager, or by executing the following command in the Package Manager Console:\r\n````shell\r\nInstall-Package BlazorDateRangePicker\r\n````\r\n\r\nThe component uses [css and js isolation](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/css-isolation), you don't need to add anything to your _Host.cshtml or index.html, just make sure the isolated styles are connected:\r\n\r\n````html\r\n<link href=\"{ASSEMBLY NAME}.styles.css\" rel=\"stylesheet\">\r\n````\r\n\r\n### Use the component:\r\n\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker/>\r\n````\r\nGives you:\r\n````HTML\r\n<input type=\"text\"/>\r\n````\r\n### Tag attributes will be passed to input field:\r\n\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker class=\"form-control form-control-sm\" placeholder=\"Select dates...\" />\r\n````\r\nGives you:\r\n````HTML\r\n<input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Select dates...\"/>\r\n````\r\n\r\n### Setting properties:\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker MinDate=\"DateTimeOffset.Now.AddYears(-10)\" MaxDate=\"DateTimeOffset.Now\" />\r\n````\r\n\r\n### Two-way data binding:\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker @bind-StartDate=\"StartDate\" @bind-EndDate=\"EndDate\" />\r\n\r\n@code {\r\n    DateTimeOffset? StartDate { get; set; } = DateTime.Today.AddMonths(-1);\r\n    DateTimeOffset? EndDate { get; set; } = DateTime.Today.AddDays(1).AddTicks(-1);\r\n}\r\n````\r\n\r\n### Handle selection event:\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker OnRangeSelect=\"OnRangeSelect\" />\r\n\r\n@code {\r\n    public void OnRangeSelect(DateRange range)\r\n    {\r\n        //Use range.Start and range.End here\r\n    }\r\n}\r\n````\r\n\r\n### More complex usage:\r\nUsing custom markup for picker.\r\n````C#\r\n@using BlazorDateRangePicker\r\n\r\n<DateRangePicker Culture=\"@(System.Globalization.CultureInfo.GetCultureInfo(\"en-US\"))\">\r\n    <PickerTemplate>\r\n        <div id=\"@context.Id\" @onclick=\"context.Toggle\" style=\"background: #fff; cursor: pointer; padding: 5px 10px; width: 250px; border: 1px solid #ccc;\">\r\n            <i class=\"oi oi-calendar\"></i>&nbsp;\r\n            <span>@context.FormattedRange @(string.IsNullOrEmpty(context.FormattedRange) ? \"Choose dates...\" : \"\")</span>\r\n            <i class=\"oi oi-chevron-bottom float-right\"></i>\r\n        </div>\r\n    </PickerTemplate>\r\n</DateRangePicker>\r\n````\r\nSet id=\"@context.Id\" for outside click handling to root element.\r\n\r\nCustom buttons:\r\n\r\n````C#\r\n<DateRangePicker @bind-StartDate=\"StartDate\" @bind-EndDate=\"EndDate\">\r\n    <ButtonsTemplate>\r\n        <button class=\"cancelBtn btn btn-sm btn-default\"\r\n            @onclick=\"@context.ClickCancel\" type=\"button\">Cancel</button>\r\n        <button class=\"cancelBtn btn btn-sm btn-default\"\r\n            @onclick=\"@(e => ResetClick(e, context))\" type=\"button\">Reset</button>\r\n        <button class=\"applyBtn btn btn-sm btn-primary\" @onclick=\"@context.ClickApply\"\r\n            disabled=\"@(context.TStartDate == null || context.TEndDate == null)\"\r\n            type=\"button\">Apply</button>\r\n    </ButtonsTemplate>\r\n</DateRangePicker>\r\n\r\n@code {\r\n    DateTimeOffset? StartDate { get; set; }\r\n    DateTimeOffset? EndDate { get; set; }\r\n\r\n    void ResetClick(MouseEventArgs e, DateRangePicker picker)\r\n    {\r\n        StartDate = null;\r\n        EndDate = null;\r\n        // Close the picker\r\n        picker.Close();\r\n        // Fire OnRangeSelectEvent\r\n        picker.OnRangeSelect.InvokeAsync(new DateRange());\r\n    }\r\n}\r\n````\r\n\r\nUse Picker.TStartDate and Picker.TEndDate properties to get current picker state before a user clicks the 'apply' button.\r\n\r\n### One configuration for all pickers\r\n\r\n````C#\r\n#Startup.cs\r\n\r\nusing BlazorDateRangePicker;\r\n\r\n//ConfigureServices\r\nservices.AddDateRangePicker(config =>\r\n{\r\n    config.Attributes = new Dictionary<string, object>\r\n    {\r\n        { \"class\", \"form-control form-control-sm\" }\r\n    };\r\n});\r\n````\r\nIt's possible to create multiple named config instances and bind it to picker with \"Config\" property.\r\n\r\n````C#\r\nservices.AddDateRangePicker(config => ..., configName: \"CustomConfig\");\r\n\r\n<DateRangePicker Config=\"CustomConfig\" />\r\n````\r\n\r\n## Properties\r\n\r\n| Name | Type | DefaultValue |  Description |\r\n|------|------|--------------|--------------|\r\n|StartDate|DateTimeOffset?|null|The beginning date of the initially selected date range.|\r\n|EndDate|DateTimeOffset?|null|The end date of the initially selected date range.|\r\n|MinDate|DateTimeOffset?|null|The earliest date a user may select.|\r\n|MaxDate|DateTimeOffset?|null|The latest date a user may select.|\r\n|MinSpan|TimeSpan?|null|The minimum span between the selected start and end dates.|\r\n|MaxSpan|TimeSpan?|null|The maximum span between the selected start and end dates.|\r\n|ShowDropdowns|bool|true|Show year and month select boxes above calendars to jump to a specific month and year.|\r\n|ShowWeekNumbers|bool|false|Show localized week numbers at the start of each week on the calendars.|\r\n|ShowISOWeekNumbers|bool|false|Show ISO week numbers at the start of each week on the calendars.|\r\n|Ranges|Dictionary<string, DateRange>|null|Set predefined date ranges the user can select from. Each key is the label for the range.|\r\n|ShowCustomRangeLabel|bool|true|Displays \"Custom Range\" at the end of the list of predefined ranges, when the ranges option is used. This option will be highlighted whenever the current date range selection does not match one of the predefined ranges. Clicking it will display the calendars to select a new range.|\r\n|AlwaysShowCalendars|bool|false|Normally, if you use the ranges option to specify pre-defined date ranges, calendars for choosing a custom date range are not shown until the user clicks \"Custom Range\". When this option is set to true, the calendars for choosing a custom date range are always shown instead.|\r\n|Opens|SideType enum: Left/Right/Center|Right|Whether the picker appears aligned to the left, to the right, or centered under the HTML element it's attached to.|\r\n|Drops|DropsType enum: Down/Up|Down|Whether the picker appears below (default) or above the HTML element it's attached to.|\r\n|ButtonClasses|string|btn btn-sm|CSS class names that will be added to both the apply and cancel buttons.|\r\n|ApplyButtonClasses|string|btn-primary|CSS class names that will be added only to the apply button.|\r\n|CancelButtonClasses|string|btn-default|CSS class names that will be added only to the cancel button.|\r\n|Culture|CultureInfo|CultureInfo.CurrentCulture|Allows you to provide localized strings for buttons and labels, customize the date format, and change the first day of week for the calendars.|\r\n|SingleDatePicker|bool|false|Show only a single calendar to choose one date, instead of a range picker with two calendars. The start and end dates provided to your callback will be the same single date chosen.|\r\n|AutoApply|bool|false|Hide the apply and cancel buttons, and automatically apply a new date range as soon as two dates are clicked.|\r\n|LinkedCalendars|bool|false|When enabled, the two calendars displayed will always be for two sequential months (i.e. January and February), and both will be advanced when clicking the left or right arrows above the calendars. When disabled, the two calendars can be individually advanced and display any month/year.|\r\n|DaysEnabledFunction|Func<DateTimeOffset, bool>|_ => true|A function that is passed each date in the two calendars before they are displayed, and may return true or false to indicate whether that date should be available for selection or not.|\r\n|DaysEnabledFunctionAsync|Func< DateTimeOffset, Task< bool>>|_ => true|Same as DaysEnabledFunction but with async support.|\r\n|CustomDateFunction|Func<DateTimeOffset, object>|_ => true|A function to which each date from the calendars is passed before they are displayed, may return a bool value indicates whether the string will be added to the cell, or a string with CSS class name to add to that date's calendar cell. May return string, bool, Task<string>, Task<bool>|\r\n|CustomDateClass|string|string.Empty|String of CSS class name to apply to that custom date's calendar cell.|\r\n|ApplyLabel|string|\"Apply\"|Apply button text.|\r\n|CancelLabel|string|\"Cancel\"|Cancel button text.|\r\n|CustomRangeLabel|string|\"Custom range\"|Custom range label at the end of the list of predefined ranges.|\r\n|DateFormat|string|CultureInfo.DateTimeFormat.ShortDatePattern|Enforces the desired format for formatting the date, ignoring the settings of the current CultureInfo.|\r\n|Config|string|null|Name of the named configuration to use with this picker instance.|\r\n|ShowOnlyOneCalendar|bool|false|Show only one calendar in the picker instead of two calendars.|\r\n|CloseOnOutsideClick|bool|true|Whether the picker should close on outside click.|\r\n|AutoAdjustCalendars|bool|true|Whether the picker should pick the months based on selected range.|\r\n|PickerTemplate|RenderFragment<DateRangePicker>|null|Custom input field template|\r\n|ButtonsTemplate|RenderFragment<DateRangePicker>|null|Custom picker buttons template|\r\n|DayTemplate|RenderFragment<CalendarItem>|null|Custom day cell template|\r\n|Inline|bool|false|Inline mode if true.|\r\n|ResetOnClear|bool|true|Whether the picker should set dates to null when the user clears the input.|\r\n|TimePicker|bool|false|Adds select boxes to choose times in addition to dates.|\r\n|TimePicker24Hour|bool|true|Use 24-hour instead of 12-hour times, removing the AM/PM selection.|\r\n|TimePickerIncrement|int|1|Increment of the minutes selection list for times (i.e. 30 to allow only selection of times ending in 0 or 30).|\r\n|TimePickerSeconds|bool|false|Show seconds in the timePicker.|\r\n|InitialStartTime|TimeSpan|TimeSpan.Zero|Initial start time value to show in the picker before any date selected|\r\n|InitialEndTime|TimeSpan|TimeSpan.FromDays(1).AddTicks(-1)|Initial end time value to show in the picker before any date selected|\r\n|TimeEnabledFunction|Func<DateTimeOffset?, Task<TimeSettings>>|null|Returns time available for selection.|\r\n\r\n## Events\r\n\r\n| Name | Type | Description |\r\n|------|------|-------------|\r\n|OnRangeSelect|DateRange|Triggered when the apply button is clicked, or when a predefined range is clicked.|\r\n|OnOpened|void|An event that is invoked when the DatePicker is opened.|\r\n|OnClosed|void|An event that is invoked when the DatePicker is closed.|\r\n|OnCancel|bool|An event that is invoked when user cancels the selection (`true` if by pressing \"Cancel\" button, `false` if by backdrop click).|\r\n|OnReset|void|An event that is invoked when the DatePicker is cleared.|\r\n|OnMonthChanged|void|An event that is invoked when left or right calendar's month changed.|\r\n|OnMonthChangedAsync|Task|An event that is invoked when left or right calendar's month changed and supports CancellationToken. Use this event handler to prepare the data for CustomDateFunction.|\r\n|OnSelectionStart|DateTimeOffset|An event that is invoked when StartDate is selected|\r\n|OnSelectionEnd|DateTimeOffset|An event that is invoked when EndDate is selected but before \"Apply\" button is clicked|\r\n\r\n## Methods\r\n\r\n| Name |Description |\r\n|------|------------|\r\n|Open|Show picker popup.|\r\n|Close|Close picker popup.|\r\n|Toggle|Toggle picker popup state.|\r\n|Reset|Rest picker.|\r\n|virtual InvokeClickOutside|A JSInvocable callback to handle outside click. When inherited can be overridden to modify outside click closing behavior.|\r\n\r\n## Types\r\n\r\nDateRange:\r\n````C#\r\npublic class DateRange\r\n{\r\n    public DateTimeOffset Start { get; set; }\r\n    public DateTimeOffset End { get; set; }\r\n}\r\n````\r\n\r\n>Note:\r\n>DateRange Start and End is in local timezone.\r\n>\r\n>The Start property is the start of a selected day (dateTime.Date).\r\n>\r\n>The End property is the end of a selected day (dateTime.Date.AddDays(1).AddTicks(-1)).\r\n\r\n## Changelog\r\n\r\n## 6.2.0\r\n\r\n1. Fixed calendars behavior when setting MaxDate (#115)\r\n2. Added net10 support\r\n\r\n### 6.1.0\r\n\r\n1. Added OnStartTimeChanged and OnEndTimeChanged events (#112)\r\n\r\n### 6.0.0\r\n\r\n1. Replaced reflection usage with source generators, the library is now NativeAOT-compatible\r\n2. Fixed NRE when SingleDatePicker is set to `null` (#111)\r\n\r\n### 5.4.0\r\n\r\n1. Added CustomParseFunction callback (#108)\r\n2. Added net9 support\r\n\r\n### 5.3.0\r\n\r\n1. Fixed the issue with TimePicker24Hour not working on left calendar (#104)\r\n\r\n### 5.2.0\r\n\r\n1. Fixed the issue with caching of clickAndPositionHandler.js (#96)\r\n\r\n### 5.1.0\r\n\r\n1. Fixed the issue with clickAndPositionHandler.js (#96, #97)\r\n\r\n### 5.0.0\r\n\r\n1. Removed inline style usage to make CSP work (#95)\r\n2. Fixed awaiting change handlers before closing (#91)\r\n3. Switched the component to use css and js isolation, you don't need to add js and css links to your _Host.cshtml manually anymore (#66)\r\n4. Removed NET Core 3.1 and NET 5 support\r\n\r\n### 4.5.0\r\n\r\n1. Added net 8 support\r\n2. Fixed TimePicker24Hour has wrong value issue (#90)\r\n3. Added the ability to display two calendars in single date select mode (#87)\r\n\r\n### 4.4.0\r\n\r\n1. Made it possible to change culture on the fly (#89)\r\n2. Added net 8 rc1 support\r\n\r\n### 4.3.0\r\n\r\n1. Updated to net 7\r\n\r\n### 4.2.0\r\n\r\n1. Fixed same date selection issue when TimePicker is enabled\r\n2. Fixed predefined date ranges with time\r\n3. Made `ChosenLabel` property public\r\n4. Added net7 support\r\n\r\n### 4.1.0\r\n\r\n1. Fixed months adjustment issue (#69)\r\n2. Fixed problems with dates 01/01/0001 and 31/12/9999\r\n\r\n### 4.0.0\r\n\r\n1. Updated to NET 6\r\n2. Fixed issue with handling of DateTime.MinValue and DateTime.MaxValue dates (#65)\r\n\r\n### 3.6.0\r\n\r\n1. Disable AutoApply when TimePicker is enabled (#57)\r\n\r\n### 3.5.0\r\n\r\n1. Added time picker\r\n2. Added Prerender property (ability to render DOM only after click on the input) (#52)\r\n\r\n### 3.4.0\r\n\r\n1. Added net 6 support\r\n\r\n### 3.3.0\r\n\r\n1. Fixed issue with month & year selection (#45)\r\n\r\n### 3.2.0\r\n\r\n1. Added ability to reset the picker by clearing the picker input (#42)\r\n2. Added `ResetOnClear` property\r\n3. Added `OnReset` event\r\n4. Added `Reset` method\r\n\r\n###  2.13.0\r\n\r\n1. Added ability to change input field `id` attribute (#41)\r\n\r\n###  2.12.0\r\n\r\n1. Added new `OnSelectionEnd` event\r\n2. Added new demo example which demonstrates how to override day click handlers\r\n3. Exposed some internals that might be useful for picker customization\r\n\r\n### 2.11.0\r\n\r\n1. Fix month/year select box issue (#34, #35)\r\n\r\n### 2.10.0\r\n\r\n1. Add `DayTemplate` property to customize picker day cell\r\n\r\n2. Demo applications refactored and updated with new examples\r\n\r\n### 2.9.0\r\n\r\n1. Fix issue with two-way dates binding (#32)\r\n2. Fix issue with date range label selection\r\n3. Fix issue with single date selection mode\r\n4. `OnSelectionStart` event now returns selected start date\r\n\r\n### 2.8.0\r\n\r\n1. Add OnSelectionStart event (#29)\r\n2. Add MinSpan property (#29)\r\n\r\n### 2.7.0\r\n\r\n1. Breaking change! CustomDateFunction changed from Func<DateTimeOffset, bool> to Func<DateTimeOffset, object> so that it can return string, bool, Task<string>, Task<bool>.\r\n2. OnMonthChangedAsync event added to support data loading indication.\r\n3. Fixed issue with compilerconfig.json file (#27).\r\n\r\n### 2.6.0\r\n\r\n1. Add inline mode (see `Inline` property, and last example in demo application) (#20)\r\n\r\n### 2.5.0\r\n\r\n1. Add `OnMonthChanged` event (#19)\r\n\r\n### 2.4.0\r\n\r\n1. Add `ButtonsTemplate` property to make custom picker buttons possible (#17)\r\n\r\n### 2.3.0\r\n\r\n1. Fix an issue with month selection in calendars (#14).\r\n2. Add AutoAdjustCalendars property.\r\n3. Expose LeftCalendar and RightCalendar DateRangePicker options (ability to select the months manually).\r\n4. Fix an issue with FirstDayOfWeek property when the first day is not sunday or monday.\r\n\r\n### 2.2.0\r\n\r\n1. Fixed performance issue with js outside click handler.\r\n\r\n### 2.1.0\r\n\r\n1. OnCancel event added.\r\n\r\n### 2.0.0\r\n\r\n1. Updated to support .NET Core 3.1.0 projects\r\n2. Now in Blazor WebAssembly we need to add library static assets manually\r\n\r\nIn .NET Core 3.0.0 projects you should stay on 1.\\*.\\* version\r\n\r\n## License\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2019-2024 Sergey Zaikin\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE."
  },
  {
    "path": "SourceGenerators/AddPropertiesGenerator.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp;\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\nusing System.Collections.Immutable;\nusing System.Text;\n\n[Generator]\npublic class AddPropertiesGenerator : IIncrementalGenerator\n{\n    public void Initialize(IncrementalGeneratorInitializationContext context)\n    {\n        // Get all interface declarations named \"IConfigurableOptions\"\n        var interfaceDeclarations = context.SyntaxProvider\n            .CreateSyntaxProvider(\n                predicate: static (node, _) => IsIConfigurableOptionsInterface(node),\n                transform: static (ctx, _) => GetInterfaceSymbol(ctx))\n            .Where(symbol => symbol is not null);\n\n        // Combine with the compilation for context\n        var compilationAndInterfaces = context.CompilationProvider.Combine(interfaceDeclarations.Collect());\n\n        // Register source generation\n        context.RegisterSourceOutput(compilationAndInterfaces, GenerateSource);\n    }\n\n    private static bool IsIConfigurableOptionsInterface(SyntaxNode node) =>\n        node is InterfaceDeclarationSyntax interfaceDecl && interfaceDecl.Identifier.Text == \"IConfigurableOptions\";\n\n    private static INamedTypeSymbol? GetInterfaceSymbol(GeneratorSyntaxContext context)\n    {\n        var interfaceDecl = (InterfaceDeclarationSyntax)context.Node;\n        var model = context.SemanticModel;\n        return model.GetDeclaredSymbol(interfaceDecl) as INamedTypeSymbol;\n    }\n\n    private static void GenerateSource(SourceProductionContext context, (Compilation, ImmutableArray<INamedTypeSymbol?>) source)\n    {\n        var (_, interfaces) = source;\n\n        // Extract the IConfigurableOptions interface symbol\n        var configurableOptions = interfaces.FirstOrDefault();\n        if (configurableOptions is null) return;\n\n        // Generate the DateRangePickerConfig class\n        var dateRangePickerConfigSource = $@\"\nnamespace BlazorDateRangePicker\n{{\n    public partial class DateRangePickerConfig\n    {{\n{GenerateProperties(configurableOptions)}\n    }}\n}}\";\n\n        context.AddSource(\"DateRangePickerConfig.g.cs\", dateRangePickerConfigSource);\n\n        // Generate the DateRangePicker class\n        var dateRangePickerSource = $@\"\nusing Microsoft.AspNetCore.Components;\nnamespace BlazorDateRangePicker\n{{\n    public partial class DateRangePicker\n    {{\n{GenerateProperties(configurableOptions, addParameterAttribute: true)}\n    }}\n}}\";\n\n        context.AddSource(\"DateRangePicker.g.cs\", dateRangePickerSource);\n    }\n\n    private static string GenerateProperties(INamedTypeSymbol configurableOptions, bool addParameterAttribute = false)\n    {\n        // Generate properties from the interface\n        var propertiesBuilder = new StringBuilder();\n        foreach (var member in configurableOptions.GetMembers().OfType<IPropertySymbol>())\n        {\n            var typeName = member.Type.ToDisplayString();\n            var propertyName = member.Name;\n\n            propertiesBuilder.AppendLine();\n            // Add XML documentation if available\n            var xmlDocumentation = member.GetDocumentationCommentXml();\n            if (!string.IsNullOrEmpty(xmlDocumentation))\n            {\n                propertiesBuilder.AppendLine($\"        /// {xmlDocumentation?.Replace(\"\\n\", \"\\n        /// \")}\");\n            }\n\n            // Generate property\n            if (addParameterAttribute && propertyName == \"Attributes\")\n            {\n                propertiesBuilder.AppendLine($\"        [Parameter(CaptureUnmatchedValues = true)]\");\n            }\n            else if (addParameterAttribute)\n            {\n                propertiesBuilder.AppendLine($\"        [Parameter]\");\n            }\n            propertiesBuilder.AppendLine($\"        public {typeName} {propertyName} {{ get; set; }}\");\n        }\n\n        var properties = propertiesBuilder.ToString();\n        return properties;\n    }\n}\n"
  },
  {
    "path": "SourceGenerators/CopyPropertiesGenerator.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\nusing Microsoft.CodeAnalysis.Text;\nusing System.Collections.Immutable;\nusing System.Text;\n\n[Generator]\npublic class CopyPropertiesGenerator : IIncrementalGenerator\n{\n    public void Initialize(IncrementalGeneratorInitializationContext context)\n    {\n        // Register a syntax receiver that will be created for each generation pass\n        var classDeclarations = context.SyntaxProvider\n            .CreateSyntaxProvider(\n                predicate: static (s, _) => IsClassWithProperties(s),\n                transform: static (ctx, _) => GetClassWithProperties(ctx))\n            .Where(static m => m is not null);\n\n        var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());\n\n        context.RegisterSourceOutput(compilationAndClasses, static (spc, source) => Execute(source.Left, source.Right, spc));\n    }\n\n    private static bool IsClassWithProperties(SyntaxNode node)\n    {\n        return node is ClassDeclarationSyntax classDeclaration &&\n               classDeclaration.Members.OfType<PropertyDeclarationSyntax>().Any();\n    }\n\n    private static ClassDeclarationSyntax GetClassWithProperties(GeneratorSyntaxContext context)\n    {\n        return (ClassDeclarationSyntax)context.Node;\n    }\n\n    private static void Execute(Compilation compilation, ImmutableArray<ClassDeclarationSyntax> _, SourceProductionContext context)\n    {\n        var optionsInterface = compilation.GetTypeByMetadataName(\"BlazorDateRangePicker.IConfigurableOptions\");\n        if (optionsInterface == null)\n            return;\n\n        var source = GenerateCopyPropertiesMethod(optionsInterface);\n        context.AddSource($\"ConfigExtensions_CopyProperties.g.cs\", SourceText.From(source, Encoding.UTF8));\n    }\n    private static string GenerateCopyPropertiesMethod(INamedTypeSymbol classSymbol)\n    {\n        var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();\n        var properties = new List<string>();\n\n        foreach (var member in classSymbol.GetMembers())\n        {\n            if (member is IPropertySymbol property && property.SetMethod != null)\n            {\n                properties.Add(property.Name);\n            }\n        }\n\n        var sb = new StringBuilder($@\"\nusing System;\n\n#pragma warning disable BL0005\nnamespace {namespaceName}\n{{\n    public static class BlazorDateRangePickerConfigExtensions\n    {{\n        public static void CopyProperties(this DateRangePickerConfig source, DateRangePicker destination)\n        {{\n\");\n\n        foreach (var property in properties)\n        {\n            sb.AppendLine($\"            if (destination.{property} == null) destination.{property} = source.{property};\");\n        }\n\n        sb.AppendLine(@\"\n        }\n    }\n}\n#pragma warning restore BL0005\n\");\n\n        return sb.ToString();\n    }\n}\n"
  },
  {
    "path": "SourceGenerators/SourceGenerators.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <LangVersion>latest</LangVersion>\n    <IsRoslynComponent>true</IsRoslynComponent>\n    <IncludeBuildOutput>false</IncludeBuildOutput>\n    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.CodeAnalysis.Analyzers\" Version=\"3.11.0\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"4.12.0\" />\n  </ItemGroup>\n\n</Project>\n"
  }
]