From 9d4419e5b261601ef91d3a489a77fef91e901ba5 Mon Sep 17 00:00:00 2001 From: Michael Tobisch Date: Wed, 22 May 2019 10:15:04 +0200 Subject: [PATCH 1/9] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e6a124..d174c3c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ The DNN Survey module allows you to create surveys and quizes on your DNN (forme * Quiz questions can be statistical, that means they have no correct answer. This is useful for questions about the gender, age group etc. in a quiz and allows analysis by these items. * To be able to identify which answers come from the same user (even in a survey that allows anonymous participation) there is a random GUID in the survey results which is created when the survey is submitted. ## System requirements -* [DNN Platform version 09.02.02 or higher](https://github.com/dnnsoftware/Dnn.Platform/releases/tag/v9.2.2) -* [DNN JavaScript Library for Chart.js v2.7.3](https://github.com/EngageSoftware/DNN-JavaScript-Libraries/releases/tag/chart.js_2.7.3) +* [DNN Platform version 08.00.00 or higher](https://github.com/dnnsoftware/Dnn.Platform/releases/tag/v8.0.0) ## More information This project is documented on [dnn-survey.readme.io](https://dnn-survey.readme.io) From 4a18abe20f324eae5507014f1c59a93840bf24c4 Mon Sep 17 00:00:00 2001 From: Daniel Valadas Date: Sun, 7 Jul 2019 10:26:24 -0400 Subject: [PATCH 2/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0e6a124..4b91bfa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # DNN.Survey + +[![Build Status](https://dev.azure.com/DNNCommunity/Community%20Modules/_apis/build/status/DNNCommunity.DNN.Survey?branchName=develop)](https://dev.azure.com/DNNCommunity/Community%20Modules/_build/latest?definitionId=7&branchName=develop) + The DNN Survey module allows you to create surveys and quizes on your DNN (formerly known as DotNetNuke) web site. * Answers can be single-choice, multiple-choice or free text * Result charts (created with ChartJS) From ea39a4b35863377d2aec0f022e19443dfbc6136d Mon Sep 17 00:00:00 2001 From: Michael Tobisch Date: Thu, 6 Feb 2020 19:16:02 +0100 Subject: [PATCH 3/9] Solves #44 --- .../SqlDataProvider/03.01.00.SqlDataProvider | 26 +++++++++---------- .../SqlDataProvider/09.00.00.SqlDataProvider | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/DNN.Survey/Providers/DataProviders/SqlDataProvider/03.01.00.SqlDataProvider b/DNN.Survey/Providers/DataProviders/SqlDataProvider/03.01.00.SqlDataProvider index 386eec4..26315e6 100644 --- a/DNN.Survey/Providers/DataProviders/SqlDataProvider/03.01.00.SqlDataProvider +++ b/DNN.Survey/Providers/DataProviders/SqlDataProvider/03.01.00.SqlDataProvider @@ -128,7 +128,7 @@ select SurveyID, OptionType, CreatedByUser, CreatedDate -from {objectQualifier}Surveys +from {databaseOwner}{objectQualifier}Surveys where ModuleID = @ModuleID order by ViewOrder @@ -146,11 +146,11 @@ select SurveyID, Question, ViewOrder, OptionType, - {objectQualifier}Users.FirstName + ' ' + {objectQualifier}Users.LastName AS CreatedByUser, + {databaseOwner}{objectQualifier}Users.FirstName + ' ' + {databaseOwner}{objectQualifier}Users.LastName AS CreatedByUser, CreatedDate, - ( select sum(Votes) from {objectQualifier}SurveyOptions where {objectQualifier}SurveyOptions.SurveyID = {objectQualifier}Surveys.SurveyID ) AS Votes -from {objectQualifier}Surveys -left outer join {objectQualifier}Users on {objectQualifier}Surveys.CreatedByUser = {objectQualifier}Users.UserID + ( select sum(Votes) from {databaseOwner}{objectQualifier}SurveyOptions where {databaseOwner}{objectQualifier}SurveyOptions.SurveyID = {databaseOwner}{objectQualifier}Surveys.SurveyID ) AS Votes +from {databaseOwner}{objectQualifier}{databaseOwner}Surveys +left outer join {databaseOwner}{objectQualifier}Users on {databaseOwner}{objectQualifier}Surveys.CreatedByUser = {databaseOwner}{objectQualifier}Users.UserID where SurveyID = @SurveyID and ModuleID = @ModuleID @@ -166,7 +166,7 @@ create procedure {databaseOwner}{objectQualifier}AddSurvey as -insert into {objectQualifier}Surveys ( +insert into {databaseOwner}{objectQualifier}Surveys ( ModuleID, Question, ViewOrder, @@ -197,7 +197,7 @@ create procedure {databaseOwner}{objectQualifier}UpdateSurvey as -update {objectQualifier}Surveys +update {databaseOwner}{objectQualifier}Surveys set Question = @Question, ViewOrder = @ViewOrder, OptionType = @OptionType, @@ -214,7 +214,7 @@ create procedure {databaseOwner}{objectQualifier}DeleteSurvey as delete -from {objectQualifier}Surveys +from {databaseOwner}{objectQualifier}Surveys where SurveyID = @SurveyID GO @@ -229,7 +229,7 @@ select SurveyOptionID, ViewOrder, OptionName, Votes -from {objectQualifier}SurveyOptions +from {databaseOwner}{objectQualifier}SurveyOptions where SurveyID = @SurveyID order by ViewOrder @@ -243,7 +243,7 @@ create procedure {databaseOwner}{objectQualifier}AddSurveyOption as -insert into {objectQualifier}SurveyOptions ( +insert into {databaseOwner}{objectQualifier}SurveyOptions ( SurveyID, OptionName, ViewOrder, @@ -268,7 +268,7 @@ create procedure {databaseOwner}{objectQualifier}UpdateSurveyOption as -update {objectQualifier}SurveyOptions +update {databaseOwner}{objectQualifier}SurveyOptions set OptionName = @OptionName, ViewOrder = @ViewOrder where SurveyOptionID = @SurveyOptionID @@ -282,7 +282,7 @@ create procedure {databaseOwner}{objectQualifier}DeleteSurveyOption as delete -from {objectQualifier}SurveyOptions +from {databaseOwner}{objectQualifier}SurveyOptions where SurveyOptionID = @SurveyOptionID GO @@ -293,7 +293,7 @@ create procedure {databaseOwner}{objectQualifier}AddSurveyResult as -update {objectQualifier}SurveyOptions +update {databaseOwner}{objectQualifier}SurveyOptions set Votes = Votes + 1 where SurveyOptionID = @SurveyOptionID diff --git a/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.00.00.SqlDataProvider b/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.00.00.SqlDataProvider index c51f0ed..5e54553 100644 --- a/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.00.00.SqlDataProvider +++ b/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.00.00.SqlDataProvider @@ -567,7 +567,7 @@ BEGIN ResultUserID, CreatedDate FROM - {objectQualifier}vSurveys_CsvExport + {databaseOwner}{objectQualifier}vSurveys_CsvExport WHERE ModuleID = @ModuleID ORDER BY From c1c8d291fd616cf7b3aec3e9cb1e98ad7fa56d23 Mon Sep 17 00:00:00 2001 From: Michael Tobisch Date: Thu, 11 Jun 2020 14:17:04 +0200 Subject: [PATCH 4/9] Solves #44 --- .../App_LocalResources/Settings.ascx.resx | 42 ++ DNN.Survey/Components/Base.cs | 15 + .../Controllers/SurveyBusinessController.cs | 690 ++++++++++-------- DNN.Survey/Controls/CanvasControl.ascx.cs | 3 +- DNN.Survey/DNN.Survey.csproj | 5 +- DNN.Survey/DNN_Survey.dnn | 27 +- DNN.Survey/Documentation/ReleaseNotes.html | 35 +- DNN.Survey/Properties/AssemblyInfo.cs | 4 +- .../SqlDataProvider/09.01.00.SqlDataProvider | 62 ++ DNN.Survey/Settings.ascx | 24 +- DNN.Survey/Settings.ascx.cs | 83 ++- DNN.Survey/Settings.ascx.designer.cs | 255 ++++--- DNN.Survey/SurveyOrganize.ascx.cs | 2 +- DNN.Survey/SurveyResults.ascx.cs | 6 +- DNN.Survey/SurveyView.ascx.cs | 85 ++- DNN.Survey/js/Chart.min.js | 13 +- 16 files changed, 887 insertions(+), 464 deletions(-) create mode 100644 DNN.Survey/Providers/DataProviders/SqlDataProvider/09.01.00.SqlDataProvider diff --git a/DNN.Survey/App_LocalResources/Settings.ascx.resx b/DNN.Survey/App_LocalResources/Settings.ascx.resx index 5794867..5b8f357 100644 --- a/DNN.Survey/App_LocalResources/Settings.ascx.resx +++ b/DNN.Survey/App_LocalResources/Settings.ascx.resx @@ -162,4 +162,46 @@ Survey type + + Appearance and Security Options + + + CSV Export Options + + + Double quotes + + + Select the text qualifier to use when exporting the results to a CSV file. + + + (none) + + + Single quotes + + + Text Qualifier + + + General Settings + + + Comma + + + Select the separator to use when exporting the results to a CSV file. + + + Semicolon + + + Space + + + Tab + + + Separator + \ No newline at end of file diff --git a/DNN.Survey/Components/Base.cs b/DNN.Survey/Components/Base.cs index 470f0c6..67024b2 100644 --- a/DNN.Survey/Components/Base.cs +++ b/DNN.Survey/Components/Base.cs @@ -50,6 +50,21 @@ public enum SurveyType Quiz = 1 } + public enum Separator + { + SemiColon = 0, + Comma = 1, + Space = 2, + Tab = 3 + } + + public enum TextQualifier + { + None = 0, + DoubleQuote = 1, + SingleQuote = 2 + } + public static class Base { public const string DEFAULT_SURVEY_RESULTS_TEMPLATE = "[SURVEY_OPTION_NAME] ([SURVEY_OPTION_VOTES]) \"\" [SURVEY_OPTION_PERCENTAGE]%
"; diff --git a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs index a458d89..cd71ff4 100644 --- a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs +++ b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs @@ -36,355 +36,401 @@ namespace DNN.Modules.Survey.Components.Controllers { - public class SurveyBusinessController : ModuleSearchBase, IUpgradeable, IPortable - { - #region Private Properties - private SurveysController _surveysController = null; - private SurveyOptionsController _surveyOptionsController = null; - private SurveysExportController _surveysExportController = null; - private PermissionController _permissionController = null; - private ModuleController _moduleController = null; + public class SurveyBusinessController : ModuleSearchBase, IUpgradeable, IPortable + { + #region Private Properties + private SurveysController _surveysController = null; + private SurveyOptionsController _surveyOptionsController = null; + private SurveysExportController _surveysExportController = null; + private PermissionController _permissionController = null; + private ModuleController _moduleController = null; - protected SurveysController SurveysController - { - get - { - if (_surveysController == null) - _surveysController = new SurveysController(); - return _surveysController; - } - } + protected SurveysController SurveysController + { + get + { + if (_surveysController == null) + _surveysController = new SurveysController(); + return _surveysController; + } + } - protected SurveyOptionsController SurveyOptionsController - { - get - { - if (_surveyOptionsController == null) - _surveyOptionsController = new SurveyOptionsController(); - return _surveyOptionsController; - } - } + protected SurveyOptionsController SurveyOptionsController + { + get + { + if (_surveyOptionsController == null) + _surveyOptionsController = new SurveyOptionsController(); + return _surveyOptionsController; + } + } - protected SurveysExportController SurveysExportController - { - get - { - if (_surveysExportController == null) - _surveysExportController = new SurveysExportController(); - return _surveysExportController; - } - } + protected SurveysExportController SurveysExportController + { + get + { + if (_surveysExportController == null) + _surveysExportController = new SurveysExportController(); + return _surveysExportController; + } + } - protected PermissionController PermissionController - { - get - { - if (_permissionController == null) - _permissionController = new PermissionController(); - return _permissionController; - } - } + protected PermissionController PermissionController + { + get + { + if (_permissionController == null) + _permissionController = new PermissionController(); + return _permissionController; + } + } - protected ModuleController ModuleController - { - get - { - if (_moduleController == null) - _moduleController = new ModuleController(); - return _moduleController; - } - } - #endregion + protected ModuleController ModuleController + { + get + { + if (_moduleController == null) + _moduleController = new ModuleController(); + return _moduleController; + } + } + #endregion - #region ModuleSearchBase - private static readonly int ModuleSearchTypeId = SearchHelper.Instance.GetSearchTypeByName("module").SearchTypeId; + #region ModuleSearchBase + private static readonly int ModuleSearchTypeId = SearchHelper.Instance.GetSearchTypeByName("module").SearchTypeId; - public override IList GetModifiedSearchDocuments(ModuleInfo moduleInfo, DateTime beginDateUtc) - { - List docs = new List(); - List surveys = SurveysController.GetAll(moduleInfo.ModuleID); + public override IList GetModifiedSearchDocuments(ModuleInfo moduleInfo, DateTime beginDateUtc) + { + List docs = new List(); + List surveys = SurveysController.GetAll(moduleInfo.ModuleID); - foreach (SurveysInfo survey in surveys) + foreach (SurveysInfo survey in surveys) + { + SearchDocument surveyDoc = new SearchDocument(); + surveyDoc.UniqueKey = string.Format("{0}_{1}_{2}", moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, survey.SurveyID); + surveyDoc.NumericKeys.Add("SurveyID", survey.SurveyID); + surveyDoc.Title = moduleInfo.ModuleTitle; + surveyDoc.Body = survey.Question; + surveyDoc.AuthorUserId = (survey.LastModifiedByUserID == null ? survey.CreatedByUserID : survey.LastModifiedByUserID.Value); + surveyDoc.ModuleId = moduleInfo.ModuleID; + surveyDoc.ModuleDefId = moduleInfo.ModuleDefID; + surveyDoc.PortalId = moduleInfo.PortalID; + surveyDoc.TabId = moduleInfo.ParentTab.TabID; + surveyDoc.SearchTypeId = ModuleSearchTypeId; + surveyDoc.ModifiedTimeUtc = (survey.LastModifiedDate == null ? survey.CreatedDate : survey.LastModifiedDate.Value).ToUniversalTime(); + // Important, if false, the document will be deleted from the search index + surveyDoc.IsActive = true; + docs.Add(surveyDoc); + List surveyOptions = SurveyOptionsController.GetAll(survey.SurveyID); + foreach (SurveyOptionsInfo surveyOption in surveyOptions) { - SearchDocument surveyDoc = new SearchDocument(); - surveyDoc.UniqueKey = string.Format("{0}_{1}_{2}", moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, survey.SurveyID); - surveyDoc.NumericKeys.Add("SurveyID", survey.SurveyID); - surveyDoc.Title = moduleInfo.ModuleTitle; - surveyDoc.Body = survey.Question; - surveyDoc.AuthorUserId = (survey.LastModifiedByUserID == null ? survey.CreatedByUserID : survey.LastModifiedByUserID.Value); - surveyDoc.ModuleId = moduleInfo.ModuleID; - surveyDoc.ModuleDefId = moduleInfo.ModuleDefID; - surveyDoc.PortalId = moduleInfo.PortalID; - surveyDoc.TabId = moduleInfo.ParentTab.TabID; - surveyDoc.SearchTypeId = ModuleSearchTypeId; - surveyDoc.ModifiedTimeUtc = (survey.LastModifiedDate == null ? survey.CreatedDate : survey.LastModifiedDate.Value).ToUniversalTime(); - // Important, if false, the document will be deleted from the search index - surveyDoc.IsActive = true; - docs.Add(surveyDoc); - List surveyOptions = SurveyOptionsController.GetAll(survey.SurveyID); - foreach (SurveyOptionsInfo surveyOption in surveyOptions) - { - SearchDocument surveyOptionDoc = new SearchDocument(); - surveyOptionDoc.UniqueKey = string.Format("{0}_{1}_{2}_{3}", moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, survey.SurveyID, surveyOption.SurveyOptionID); - surveyOptionDoc.NumericKeys.Add("SurveyOptionID", surveyOption.SurveyOptionID); - surveyOptionDoc.Title = survey.Question; - surveyOptionDoc.Body = surveyOption.OptionName; - surveyOptionDoc.AuthorUserId = (surveyOption.LastModifiedByUserID == null ? surveyOption.CreatedByUserID : surveyOption.LastModifiedByUserID.Value); - surveyOptionDoc.ModuleId = moduleInfo.ModuleID; - surveyOptionDoc.ModuleDefId = moduleInfo.ModuleDefID; - surveyOptionDoc.PortalId = moduleInfo.PortalID; - surveyOptionDoc.TabId = moduleInfo.ParentTab.TabID; - surveyOptionDoc.SearchTypeId = ModuleSearchTypeId; - surveyOptionDoc.ModifiedTimeUtc = (surveyOption.LastModifiedDate == null ? surveyOption.CreatedDate : surveyOption.LastModifiedDate.Value).ToUniversalTime(); - surveyOptionDoc.IsActive = true; - docs.Add(surveyOptionDoc); - } + SearchDocument surveyOptionDoc = new SearchDocument(); + surveyOptionDoc.UniqueKey = string.Format("{0}_{1}_{2}_{3}", moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, survey.SurveyID, surveyOption.SurveyOptionID); + surveyOptionDoc.NumericKeys.Add("SurveyOptionID", surveyOption.SurveyOptionID); + surveyOptionDoc.Title = survey.Question; + surveyOptionDoc.Body = surveyOption.OptionName; + surveyOptionDoc.AuthorUserId = (surveyOption.LastModifiedByUserID == null ? surveyOption.CreatedByUserID : surveyOption.LastModifiedByUserID.Value); + surveyOptionDoc.ModuleId = moduleInfo.ModuleID; + surveyOptionDoc.ModuleDefId = moduleInfo.ModuleDefID; + surveyOptionDoc.PortalId = moduleInfo.PortalID; + surveyOptionDoc.TabId = moduleInfo.ParentTab.TabID; + surveyOptionDoc.SearchTypeId = ModuleSearchTypeId; + surveyOptionDoc.ModifiedTimeUtc = (surveyOption.LastModifiedDate == null ? surveyOption.CreatedDate : surveyOption.LastModifiedDate.Value).ToUniversalTime(); + surveyOptionDoc.IsActive = true; + docs.Add(surveyOptionDoc); } - return docs; - } - #endregion + } + return docs; + } + #endregion - #region IUpgradeable - public string UpgradeModule(string version) - { - string[] _version = version.Split(new char[] { '.' }); - int major = Convert.ToInt32(_version[0]); - int minor = Convert.ToInt32(_version[1]); - int maintenance = Convert.ToInt32(_version[2]); + #region IUpgradeable + public string UpgradeModule(string version) + { + string[] _version = version.Split(new char[] { '.' }); + int major = Convert.ToInt32(_version[0]); + int minor = Convert.ToInt32(_version[1]); + int maintenance = Convert.ToInt32(_version[2]); - if (major == 9) + if (major == 9) + { + if (minor == 0) { - if (minor == 0) - { - if (maintenance == 0) - { - List modulesList = ModuleController.GetAllModules().Cast().ToList(); + if (maintenance == 0) + { + List modulesList = ModuleController.GetAllModules().Cast().ToList(); - foreach (object m in modulesList) + foreach (object m in modulesList) + { + ModuleInfo module = (ModuleInfo)m; + if (module.DesktopModule.FriendlyName == "Survey") + { + ModulePermissionCollection modulePermissions = module.ModulePermissions; + // Setting surveyresultstype: 0 = Public, 1 = Private + // goes to Permission + string surveyResultsTypeSetting = module.ModuleSettings["surveyresultstype"].ToString(); + if (string.IsNullOrEmpty(surveyResultsTypeSetting)) + { + // if not defined: make it private to be safe... + surveyResultsTypeSetting = "1"; + } + // If it is public: All Users (RoleID: -1) have the permission to view the results + if (surveyResultsTypeSetting == "0") + { + List viewResultsPermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.RoleID == -1).ToList(); + if (viewResultsPermissions.Count() == 0) + { + ModulePermissionInfo viewResultPermission = new ModulePermissionInfo(); + viewResultPermission.AllowAccess = true; + viewResultPermission.RoleID = -1; + viewResultPermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.VIEW_RESULTS_PERMISSION)[0]).PermissionID; + viewResultPermission.ModuleID = module.ModuleID; + modulePermissions.Add(viewResultPermission); + ModulePermissionController.SaveModulePermissions(module); + } + } + // All roles and user who have edit permissions get the View results permission as well + List editModulePermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == "SYSTEM_MODULE_DEFINITION" && mp.PermissionKey == "EDIT").ToList(); + foreach (ModulePermissionInfo editModulePermission in editModulePermissions) { - ModuleInfo module = (ModuleInfo)m; - if (module.DesktopModule.FriendlyName == "Survey") - { - ModulePermissionCollection modulePermissions = module.ModulePermissions; - // Setting surveyresultstype: 0 = Public, 1 = Private - // goes to Permission - string surveyResultsTypeSetting = module.ModuleSettings["surveyresultstype"].ToString(); - if (string.IsNullOrEmpty(surveyResultsTypeSetting)) - { - // if not defined: make it private to be safe... - surveyResultsTypeSetting = "1"; - } - // If it is public: All Users (RoleID: -1) have the permission to view the results - if (surveyResultsTypeSetting == "0") - { - List viewResultsPermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.RoleID == -1).ToList(); - if (viewResultsPermissions.Count() == 0) - { - ModulePermissionInfo viewResultPermission = new ModulePermissionInfo(); - viewResultPermission.AllowAccess = true; - viewResultPermission.RoleID = -1; - viewResultPermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.VIEW_RESULTS_PERMISSION)[0]).PermissionID; - viewResultPermission.ModuleID = module.ModuleID; - modulePermissions.Add(viewResultPermission); - ModulePermissionController.SaveModulePermissions(module); - } - } - // All roles and user who have edit permissions get the View results permission as well - List editModulePermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == "SYSTEM_MODULE_DEFINITION" && mp.PermissionKey == "EDIT").ToList(); - foreach (ModulePermissionInfo editModulePermission in editModulePermissions) - { - List viewResultsPermissions; - ModulePermissionInfo viewResultPermission = new ModulePermissionInfo(); - if (String.IsNullOrEmpty(editModulePermission.RoleName)) - { - // when the role name is empty it is a user poermission - viewResultsPermissions = modulePermissions.Where(mp => mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.UserID == editModulePermission.UserID).ToList(); - viewResultPermission.UserID = editModulePermission.UserID; - viewResultPermission.Username = editModulePermission.Username; - } - else - { - // role permission - viewResultsPermissions = modulePermissions.Where(mp => mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.RoleID == editModulePermission.RoleID).ToList(); - viewResultPermission.RoleID = editModulePermission.RoleID; - viewResultPermission.RoleName = editModulePermission.RoleName; - } - if (viewResultsPermissions.Count() == 0) - { - // if the permission for this user/role is not already set... - viewResultPermission.AllowAccess = true; - viewResultPermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.VIEW_RESULTS_PERMISSION)[0]).PermissionID; - viewResultPermission.ModuleID = module.ModuleID; - modulePermissions.Add(viewResultPermission); - ModulePermissionController.SaveModulePermissions(module); - } - } - // Setting surveytracking: 0 = Cookie, 1 = Registered user - // goes to Permission - string surveyTrackingSetting = module.ModuleSettings["surveytracking"].ToString(); - if (string.IsNullOrEmpty(surveyTrackingSetting)) - { - // if not defined: make it per user - surveyTrackingSetting = "1"; - } - // If it is Cookie tracking: All users (RoleId: -1) have the permissions to participate in the survey - // Otherwise: Registered Users have the permission to participate in the survey - // Is there a better way than using the hard coded role IDs? - int permittedRoleID = (surveyTrackingSetting == "0" ? -1 : 1); - List participatePermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.PARTICIPATE_PERMISSION && mp.RoleID == permittedRoleID).ToList(); - if (participatePermissions.Count() == 0) - { - ModulePermissionInfo participatePermission = new ModulePermissionInfo(); - participatePermission.AllowAccess = true; - participatePermission.RoleID = permittedRoleID; - participatePermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.PARTICIPATE_PERMISSION)[0]).PermissionID; - participatePermission.ModuleID = module.ModuleID; - modulePermissions.Add(participatePermission); - ModulePermissionController.SaveModulePermissions(module); - } - // Is Module a quiz? - List surveys = SurveysController.GetAll(module.ModuleID); - bool isQuiz = false; - List statisticalSurveys = new List(); - foreach (SurveysInfo survey in surveys) - { - List surveyOptions = SurveyOptionsController.GetAll(survey.SurveyID); - int countCorrect = surveyOptions.Where(so => so.IsCorrect).Count(); - if (countCorrect > 0) - { - isQuiz = true; - } - else - { - statisticalSurveys.Add(survey); - } - } - if (isQuiz) - { - ModuleController.Instance.UpdateModuleSetting(module.ModuleID, "SurveyType", ((int)SurveyType.Quiz).ToString()); - foreach (SurveysInfo statisticalSurvey in statisticalSurveys) - { - statisticalSurvey.IsStatistical = true; - SurveysController.AddOrChange(statisticalSurvey, XmlDataProvider.SurveyOptionsToXml(SurveyOptionsController.GetAll(statisticalSurvey.SurveyID)), -1); - } - } - string surveyClosingDate = module.ModuleSettings["surveyclosingdate"].ToString(); - if (!(string.IsNullOrEmpty(surveyClosingDate))) - { - ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyclosingdate"); - ModuleController.Instance.UpdateModuleSetting(module.ModuleID, "SurveyClosingDate", surveyClosingDate); - } - // Remove unused old settings - ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyresultstype"); - ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveytracking"); - ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyresulttemplate"); - ModuleController.Instance.DeleteTabModuleSetting(module.TabModuleID, "surveygraphwidth"); - } + List viewResultsPermissions; + ModulePermissionInfo viewResultPermission = new ModulePermissionInfo(); + if (String.IsNullOrEmpty(editModulePermission.RoleName)) + { + // when the role name is empty it is a user poermission + viewResultsPermissions = modulePermissions.Where(mp => mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.UserID == editModulePermission.UserID).ToList(); + viewResultPermission.UserID = editModulePermission.UserID; + viewResultPermission.Username = editModulePermission.Username; + } + else + { + // role permission + viewResultsPermissions = modulePermissions.Where(mp => mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.VIEW_RESULTS_PERMISSION && mp.RoleID == editModulePermission.RoleID).ToList(); + viewResultPermission.RoleID = editModulePermission.RoleID; + viewResultPermission.RoleName = editModulePermission.RoleName; + } + if (viewResultsPermissions.Count() == 0) + { + // if the permission for this user/role is not already set... + viewResultPermission.AllowAccess = true; + viewResultPermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.VIEW_RESULTS_PERMISSION)[0]).PermissionID; + viewResultPermission.ModuleID = module.ModuleID; + modulePermissions.Add(viewResultPermission); + ModulePermissionController.SaveModulePermissions(module); + } } - } - } + // Setting surveytracking: 0 = Cookie, 1 = Registered user + // goes to Permission + string surveyTrackingSetting = module.ModuleSettings["surveytracking"].ToString(); + if (string.IsNullOrEmpty(surveyTrackingSetting)) + { + // if not defined: make it per user + surveyTrackingSetting = "1"; + } + // If it is Cookie tracking: All users (RoleId: -1) have the permissions to participate in the survey + // Otherwise: Registered Users have the permission to participate in the survey + // Is there a better way than using the hard coded role IDs? + int permittedRoleID = (surveyTrackingSetting == "0" ? -1 : 1); + List participatePermissions = modulePermissions.Where(mp => mp.ModuleID == module.ModuleID && mp.PermissionCode == ModuleSecurity.PERMISSION_CODE && mp.PermissionKey == ModuleSecurity.PARTICIPATE_PERMISSION && mp.RoleID == permittedRoleID).ToList(); + if (participatePermissions.Count() == 0) + { + ModulePermissionInfo participatePermission = new ModulePermissionInfo(); + participatePermission.AllowAccess = true; + participatePermission.RoleID = permittedRoleID; + participatePermission.PermissionID = ((PermissionInfo)PermissionController.GetPermissionByCodeAndKey(ModuleSecurity.PERMISSION_CODE, ModuleSecurity.PARTICIPATE_PERMISSION)[0]).PermissionID; + participatePermission.ModuleID = module.ModuleID; + modulePermissions.Add(participatePermission); + ModulePermissionController.SaveModulePermissions(module); + } + // Is Module a quiz? + List surveys = SurveysController.GetAll(module.ModuleID); + bool isQuiz = false; + List statisticalSurveys = new List(); + foreach (SurveysInfo survey in surveys) + { + List surveyOptions = SurveyOptionsController.GetAll(survey.SurveyID); + int countCorrect = surveyOptions.Where(so => so.IsCorrect).Count(); + if (countCorrect > 0) + { + isQuiz = true; + } + else + { + statisticalSurveys.Add(survey); + } + } + if (isQuiz) + { + ModuleController.Instance.UpdateModuleSetting(module.ModuleID, "SurveyType", ((int)SurveyType.Quiz).ToString()); + foreach (SurveysInfo statisticalSurvey in statisticalSurveys) + { + statisticalSurvey.IsStatistical = true; + SurveysController.AddOrChange(statisticalSurvey, XmlDataProvider.SurveyOptionsToXml(SurveyOptionsController.GetAll(statisticalSurvey.SurveyID)), -1); + } + } + string surveyClosingDate = module.ModuleSettings["surveyclosingdate"].ToString(); + if (!(string.IsNullOrEmpty(surveyClosingDate))) + { + ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyclosingdate"); + ModuleController.Instance.UpdateModuleSetting(module.ModuleID, "SurveyClosingDate", surveyClosingDate); + } + // Remove unused old settings + ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyresultstype"); + ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveytracking"); + ModuleController.Instance.DeleteModuleSetting(module.ModuleID, "surveyresulttemplate"); + ModuleController.Instance.DeleteTabModuleSetting(module.TabModuleID, "surveygraphwidth"); + } + } + } } - return string.Format("Upgrading to version {0}.", version); - } - #endregion + } + return string.Format("Upgrading to version {0}.", version); + } + #endregion - #region IPortable - public string ExportModule(int moduleID) - { - StringBuilder exportXml = new StringBuilder(); - //Hashtable moduleSettings = ModuleController.Instance.GetModule(moduleID, Null.NullInteger, true).ModuleSettings; + #region IPortable + public string ExportModule(int moduleID) + { + StringBuilder exportXml = new StringBuilder(); + //Hashtable moduleSettings = ModuleController.Instance.GetModule(moduleID, Null.NullInteger, true).ModuleSettings; - exportXml.Append(""); - //if (moduleSettings == null) - //{ - // exportXml.Append(""); - //} - //else - //{ - // exportXml.Append(""); - // foreach (KeyValuePair setting in moduleSettings) - // { - // exportXml.Append(String.Format("<{0}>{1}", setting.Key, setting.Value)); - // } - // exportXml.Append(""); - //} + exportXml.Append(""); + //if (moduleSettings == null) + //{ + // exportXml.Append(""); + //} + //else + //{ + // exportXml.Append(""); + // foreach (KeyValuePair setting in moduleSettings) + // { + // exportXml.Append(String.Format("<{0}>{1}", setting.Key, setting.Value)); + // } + // exportXml.Append(""); + //} - List surveys = SurveysController.GetAll(moduleID); - exportXml.Append(XmlDataProvider.SurveysToXml(surveys, true)); - exportXml.Append(""); + List surveys = SurveysController.GetAll(moduleID); + exportXml.Append(XmlDataProvider.SurveysToXml(surveys, true)); + exportXml.Append(""); - return exportXml.ToString(); - } + return exportXml.ToString(); + } - public void ImportModule(int moduleID, string content, string version, int userID) - { - string[] versions = version.Split(new char[] { '.' }); + public void ImportModule(int moduleID, string content, string version, int userID) + { + string[] versions = version.Split(new char[] { '.' }); - if (Convert.ToInt32(versions[0]) < 9) + if (Convert.ToInt32(versions[0]) < 9) + { + // Old Xml data sructure by the original core module + XmlNode surveysNode = Globals.GetContent(content, "surveys"); + foreach (XmlNode surveyNode in surveysNode) { - // Old Xml data sructure by the original core module - XmlNode surveysNode = Globals.GetContent(content, "surveys"); - foreach (XmlNode surveyNode in surveysNode) - { - SurveysInfo survey = new SurveysInfo(); - survey.SurveyID = 0; - survey.ModuleID = moduleID; - survey.Question = surveyNode.SelectSingleNode("question").InnerText; - survey.ViewOrder = Convert.ToInt32(surveyNode.SelectSingleNode("vieworder").InnerText); - survey.OptionType = (QuestionType)Convert.ToInt32(surveyNode.SelectSingleNode("optiontype").InnerText); + SurveysInfo survey = new SurveysInfo(); + survey.SurveyID = 0; + survey.ModuleID = moduleID; + survey.Question = surveyNode.SelectSingleNode("question").InnerText; + survey.ViewOrder = Convert.ToInt32(surveyNode.SelectSingleNode("vieworder").InnerText); + survey.OptionType = (QuestionType)Convert.ToInt32(surveyNode.SelectSingleNode("optiontype").InnerText); - XmlNode surveyOptionsNode = surveyNode.SelectSingleNode("surveyoptions"); - List surveyOptions = new List(); - foreach (XmlNode surveyOptionNode in surveyOptionsNode) - { - SurveyOptionsInfo surveyOption = new SurveyOptionsInfo(); - surveyOption.SurveyOptionID = 0; - surveyOption.OptionName = surveyOptionNode.SelectSingleNode("optionname").InnerText; - surveyOption.IsCorrect = Convert.ToBoolean(surveyOptionNode.SelectSingleNode("iscorrect").InnerText); - surveyOption.ViewOrder = Convert.ToInt32(surveyOptionNode.SelectSingleNode("vieworder").InnerText); - surveyOptions.Add(surveyOption); - } - SurveysController.AddOrChange(survey, XmlDataProvider.SurveyOptionsToXml(surveyOptions), userID); - } + XmlNode surveyOptionsNode = surveyNode.SelectSingleNode("surveyoptions"); + List surveyOptions = new List(); + foreach (XmlNode surveyOptionNode in surveyOptionsNode) + { + SurveyOptionsInfo surveyOption = new SurveyOptionsInfo(); + surveyOption.SurveyOptionID = 0; + surveyOption.OptionName = surveyOptionNode.SelectSingleNode("optionname").InnerText; + surveyOption.IsCorrect = Convert.ToBoolean(surveyOptionNode.SelectSingleNode("iscorrect").InnerText); + surveyOption.ViewOrder = Convert.ToInt32(surveyOptionNode.SelectSingleNode("vieworder").InnerText); + surveyOptions.Add(surveyOption); + } + SurveysController.AddOrChange(survey, XmlDataProvider.SurveyOptionsToXml(surveyOptions), userID); } - else + } + else + { + XmlNode root = Globals.GetContent(content, "Survey"); + string exportString = root.SelectSingleNode("Surveys").OuterXml; + exportString = exportString.Replace("[MODULE_ID]", moduleID.ToString()).Replace("[CREATED_DATE]", string.Format("{0:yyyy-MM-dd hh:mm:ss}", DateTime.Now)).Replace("[USER_ID]", userID.ToString()); + List surveys = XmlDataProvider.SurveysFromXml(exportString); + foreach (SurveysInfo survey in surveys) { - XmlNode root = Globals.GetContent(content, "Survey"); - string exportString = root.SelectSingleNode("Surveys").OuterXml; - exportString = exportString.Replace("[MODULE_ID]", moduleID.ToString()).Replace("[CREATED_DATE]", string.Format("{0:yyyy-MM-dd hh:mm:ss}", DateTime.Now)).Replace("[USER_ID]", userID.ToString()); - List surveys = XmlDataProvider.SurveysFromXml(exportString); - foreach (SurveysInfo survey in surveys) - { - survey.SurveyID = 0; - survey.ModuleID = moduleID; - SurveysController.AddOrChange(survey, survey.SurveyOptionsXml, userID); - } + survey.SurveyID = 0; + survey.ModuleID = moduleID; + SurveysController.AddOrChange(survey, survey.SurveyOptionsXml, userID); } - } + } + } + #endregion + #region CSV Export + public string CSVExport(int moduleID, string resourceFile, Separator separator, TextQualifier textQualifier) + { + StringBuilder csvBuilder = new StringBuilder(); + csvBuilder.Append(string.Format("{0}SurveyID{0}{1}{0}Question{0}{1}{0}Question Type{0}{1}{0}Statistical{0}{1}{0}Answer{0}{1}{0}Votes{0}{1}{0}Correct Answer{0}{1}{0}UserID{0}{1}{0}IP Address{0}{1}{0}GUID{0}{1}{0}Date\r\n", GetTextQualifierCharacter(textQualifier), GetSeparatorCharacter(separator))); - public string CSVExport(int moduleID, string resourceFile) - { - StringBuilder csvBuilder = new StringBuilder(); - csvBuilder.Append("SurveyID; Question; Question Type; Statistical; Answer; Votes; Correct Answer; UserID; IP Address; GUID; Date\r\n"); - - List surveys = SurveysExportController.GetAll(moduleID); - foreach (SurveysExportInfo survey in surveys) - { - csvBuilder.Append(string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10:yyyy-MM-dd hh:mm:ss}\r\n", - survey.SurveyID, - survey.Question, - Localization.GetString(string.Format("QuestionType.{0}.Text", Enum.GetName(typeof(QuestionType), survey.OptionType), resourceFile)), - survey.IsStatistical, - (survey.OptionType == QuestionType.Text ? survey.TextAnswer : survey.OptionName), - survey.Votes, - survey.IsCorrect, - survey.UserID, - survey.IPAddress, - survey.ResultUserID, - survey.CreatedDate)); - } - return csvBuilder.ToString(); - } - #endregion - } + List surveys = SurveysExportController.GetAll(moduleID); + foreach (SurveysExportInfo survey in surveys) + { + csvBuilder.Append(string.Format("{0}{2}{0}{1}{0}{3}{0}{1}{0}{4}{0}{1}{0}{5}{0}{1}{0}{6}{0}{1}{0}{7}{0}{1}{0}{8}{0}{1}{0}{9}{0}{1}{0}{10}{0}{1}{0}{11}{0}{1}{0}{12:yyyy-MM-dd hh:mm:ss}\r\n", + GetTextQualifierCharacter(textQualifier), + GetSeparatorCharacter(separator), + survey.SurveyID, + survey.Question, + Localization.GetString(string.Format("QuestionType.{0}.Text", Enum.GetName(typeof(QuestionType), survey.OptionType), resourceFile)), + survey.IsStatistical, + (survey.OptionType == QuestionType.Text ? survey.TextAnswer : survey.OptionName), + survey.Votes, + survey.IsCorrect, + survey.UserID, + survey.IPAddress, + survey.ResultUserID, + survey.CreatedDate)); + } + return csvBuilder.ToString(); + } + private char GetSeparatorCharacter(Separator separator) + { + char separatorCharacter; + switch (separator) + { + case Separator.SemiColon: + separatorCharacter = ';'; + break; + case Separator.Comma: + separatorCharacter = ','; + break; + case Separator.Space: + separatorCharacter = ' '; + break; + case Separator.Tab: + separatorCharacter = (char)9; + break; + default: + separatorCharacter = ';'; + break; + } + return separatorCharacter; + } + private char GetTextQualifierCharacter(TextQualifier textQualifier) + { + char textQualifierCharacter; + switch (textQualifier) + { + case TextQualifier.None: + textQualifierCharacter = '\0'; + break; + case TextQualifier.DoubleQuote: + textQualifierCharacter = '\"'; + break; + case TextQualifier.SingleQuote: + textQualifierCharacter = '\''; + break; + default: + textQualifierCharacter = '\0'; + break; + } + return textQualifierCharacter; + } + #endregion + } } \ No newline at end of file diff --git a/DNN.Survey/Controls/CanvasControl.ascx.cs b/DNN.Survey/Controls/CanvasControl.ascx.cs index ecd2247..dc3feaf 100644 --- a/DNN.Survey/Controls/CanvasControl.ascx.cs +++ b/DNN.Survey/Controls/CanvasControl.ascx.cs @@ -21,6 +21,7 @@ using DNN.Modules.Survey.Components; using System; using System.Text; +using System.Web; using System.Web.UI; namespace DNN.Modules.Survey.Controls @@ -58,7 +59,7 @@ protected void Page_Load(object sender, EventArgs e) for (int i = 0; i < labels.Length; i++) { // Let Google see the results... - Graph.InnerHtml += string.Format("{0}: {1} ({2:0.00}%)", Server.HtmlEncode(labels[i]), data[i], (data[i] == "0" ? 0 : Convert.ToDouble(data[i]) * 100 / sum)); + Graph.InnerHtml += string.Format("{0}: {1} ({2:0.00}%)", labels[i], data[i], (data[i] == "0" ? 0 : Convert.ToDouble(data[i]) * 100 / sum)); } } diff --git a/DNN.Survey/DNN.Survey.csproj b/DNN.Survey/DNN.Survey.csproj index e23475f..a1cda39 100644 --- a/DNN.Survey/DNN.Survey.csproj +++ b/DNN.Survey/DNN.Survey.csproj @@ -156,7 +156,9 @@ - + + Designer + @@ -233,6 +235,7 @@ + 10.0 diff --git a/DNN.Survey/DNN_Survey.dnn b/DNN.Survey/DNN_Survey.dnn index 6da722d..1a7760e 100644 --- a/DNN.Survey/DNN_Survey.dnn +++ b/DNN.Survey/DNN_Survey.dnn @@ -1,6 +1,6 @@  - + Survey - 08.00.00 + 09.04.04 @@ -664,15 +664,20 @@ 04.70.00.SqlDataProvider 04.70.00 - - + + @@ -760,7 +765,7 @@ DNN.Modules.Survey.Components.Controllers.SurveyBusinessController [DESKTOPMODULEID] - 03.01.00,03.03.00,04.00.20,04.00.60,04.00.70,04.00.85,04.01.00,04.05.00,04.06.00,04.07.00,09.00.00,09.00.01 + 03.01.00,03.03.00,04.00.20,04.00.60,04.00.70,04.00.85,04.01.00,04.05.00,04.06.00,04.07.00,09.00.00,09.01.00,09.01.00 @@ -770,7 +775,7 @@ bin DNN.Modules.Survey.dll - 9.0.1.0 + 9.1.0.0 diff --git a/DNN.Survey/Documentation/ReleaseNotes.html b/DNN.Survey/Documentation/ReleaseNotes.html index c1f18b1..422adfe 100644 --- a/DNN.Survey/Documentation/ReleaseNotes.html +++ b/DNN.Survey/Documentation/ReleaseNotes.html @@ -1,7 +1,7 @@ 

DNN Survey Module

DNN® - www.dnnsoftware.com
- © 2002-2019 by DNN Corp.
+ © 2002-2020 by DNN Corp.

DNN Survey Project 09.00.00

@@ -9,9 +9,7 @@

DNN Survey Project 09.00.00

Minimum System requirements:

    -
  • DNN Platform version 09.02.02 or higher
  • -
  • DNN JavaScript Library for Chart.js v2.7.3
  • -
  • SQL Server 2016 (any edition, also Express)
  • +
  • DNN Platform version 08.00.00 or higher

Changes: @@ -27,4 +25,33 @@

DNN Survey Project 09.00.00

  • Added text answers
  • Added quiz result view
  • +

    DNN Survey Project 09.00.01

    +

    + Bugfixes: +

    +
      +
    • #39 - Show closing date message" and "Add consent checkbox?" check boxes are not saved correctly when the values are changed from checked to unchecked.
    • +
    +

    DNN Survey Project 09.01.00

    +

    + Minimum System requirements: +

    +
      +
    • DNN Platform version 09.04.04 or higher
    • +
    +

    + Changes: +

    +
      +
    • Updated Chart.js to version 2.9.3
    • +
    • #14 - CSV Export: Add setting for separator and delimiter
    • +
    +

    + Bugfixes: +

    +
      +
    • #44 - Error when installing DNN Survey module 9.00.01 on DNN 9.2.2
    • +
    • #47 - Missing Surveys
    • +
    • #48 - Charts don't display when a double quote was entered in a free text response
    • +
    \ No newline at end of file diff --git a/DNN.Survey/Properties/AssemblyInfo.cs b/DNN.Survey/Properties/AssemblyInfo.cs index dc4a084..fe80b16 100644 --- a/DNN.Survey/Properties/AssemblyInfo.cs +++ b/DNN.Survey/Properties/AssemblyInfo.cs @@ -32,8 +32,8 @@ // // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: -[assembly: AssemblyVersion("9.0.1.0")] -[assembly: AssemblyFileVersion("9.0.1.0")] +[assembly: AssemblyVersion("9.1.0.0")] +[assembly: AssemblyFileVersion("9.1.0.0")] // Add assembly reference to allow for WebResource.axd access to JavaScript files // see: http://aspnet.4guysfromrolla.com/articles/080906-1.aspx diff --git a/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.01.00.SqlDataProvider b/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.01.00.SqlDataProvider new file mode 100644 index 0000000..82458e0 --- /dev/null +++ b/DNN.Survey/Providers/DataProviders/SqlDataProvider/09.01.00.SqlDataProvider @@ -0,0 +1,62 @@ +ALTER PROCEDURE {databaseOwner}{objectQualifier}Surveys_Sort + @SurveysXML xml +AS +BEGIN + DECLARE @idoc int + DECLARE @ModuleID int + DECLARE @SurveyID int + DECLARE @ViewOrder int + DECLARE @LastModifiedByUserID int + DECLARE @SurveyIDs table(SurveyID int) + + BEGIN TRY + BEGIN TRANSACTION + + EXEC sp_xml_preparedocument @idoc OUTPUT, @SurveysXML + + DECLARE curQuestions CURSOR FOR + SELECT + ModuleID, + SurveyID, + ViewOrder, + LastModifiedByUserID + FROM + OPENXML(@idoc, '/Surveys/Survey', 2) WITH (ModuleID int, SurveyID int, ViewOrder int, LastModifiedByUserID int) + + OPEN curQuestions + FETCH NEXT FROM curQuestions INTO @ModuleID, @SurveyID, @ViewOrder, @LastModifiedByUserID + WHILE @@FETCH_STATUS = 0 + BEGIN + UPDATE + {databaseOwner}{objectQualifier}Surveys + SET + ViewOrder = @ViewOrder, + LastModifiedByUserID = @LastModifiedByUserID, + LastModifiedDate = GETDATE() + WHERE + SurveyID = @SurveyID + -- Collect SurveyID for later purpose (delete surveys not included, see below) + INSERT INTO @SurveyIDs(SurveyID) VALUES(@SurveyID) + FETCH NEXT FROM curQuestions INTO @ModuleID, @SurveyID, @ViewOrder, @LastModifiedByUserID + END + CLOSE curQuestions + DEALLOCATE curQuestions + + -- Delete surveys that were not submitted in the XML + DELETE FROM {databaseOwner}{objectQualifier}Surveys WHERE ModuleID = @ModuleID AND SurveyID NOT IN (SELECT SurveyID FROM @SurveyIDs) + + IF @@TRANCOUNT > 0 + BEGIN + COMMIT TRANSACTION + END + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 + BEGIN + ROLLBACK TRANSACTION + END + DECLARE @ErrMsg nvarchar(max), @ErrSeverity int + SELECT @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY() + RAISERROR(@ErrMsg, @ErrSeverity, 1) + END CATCH +END diff --git a/DNN.Survey/Settings.ascx b/DNN.Survey/Settings.ascx index 296a0c7..68c62da 100644 --- a/DNN.Survey/Settings.ascx +++ b/DNN.Survey/Settings.ascx @@ -5,6 +5,7 @@
    +

    - -
    @@ -27,6 +26,9 @@
    +
    +

    +
    - - -
    +

    +
    +
    + + +
    +
    + + +
    +
    \ No newline at end of file diff --git a/DNN.Survey/Settings.ascx.cs b/DNN.Survey/Settings.ascx.cs index 8001109..8c5c3a1 100644 --- a/DNN.Survey/Settings.ascx.cs +++ b/DNN.Survey/Settings.ascx.cs @@ -113,6 +113,44 @@ protected bool ShowClosingDateMessage UpdateBooleanSetting("ShowClosingDateMessage", value); } } + protected Separator Separator + { + get + { + object separator = ModuleSettings["Separator"]; + if (separator == null) + { + return Separator.SemiColon; + } + else + { + return (Separator)Convert.ToInt32(separator); + } + } + set + { + UpdateIntegerSetting("Separator", Convert.ToInt32(value)); + } + } + protected TextQualifier TextQualifier + { + get + { + object textQualifier = ModuleSettings["TextQualifier"]; + if (textQualifier == null) + { + return TextQualifier.None; + } + else + { + return (TextQualifier)Convert.ToInt32(textQualifier); + } + } + set + { + UpdateIntegerSetting("TextQualifier", Convert.ToInt32(value)); + } + } #endregion #region Page Events @@ -129,9 +167,9 @@ protected override void OnPreRender(EventArgs e) #region Settings Events public override void LoadSettings() { - foreach (ListItem li in SurveyTypeRadioButtonList.Items) + foreach (SurveyType surveyType in (SurveyType[]) Enum.GetValues(typeof(SurveyType))) { - li.Text = Localization.GetString(string.Format("SurveyType.{0}.Text", Enum.GetName(typeof(SurveyType), Convert.ToInt32(li.Value))), LocalResourceFile); + SurveyTypeRadioButtonList.Items.Add(new ListItem(Localization.GetString(string.Format("SurveyType.{0}.Text", Enum.GetName(typeof(SurveyType), surveyType)), LocalResourceFile), Convert.ToInt32(surveyType).ToString())); } SurveyTypeRadioButtonList.SelectedValue = Convert.ToInt32(SurveyType).ToString(); @@ -143,12 +181,24 @@ public override void LoadSettings() PrivacyConfirmationCheckBox.Checked = PrivacyConfirmation; ShowClosingDateMessageCheckBox.Checked = ShowClosingDateMessage; - foreach (ListItem li in UseCaptchaRadioButtonList.Items) + foreach (UseCaptcha useCaptcha in (UseCaptcha[]) Enum.GetValues(typeof(UseCaptcha))) { - li.Text = Localization.GetString(string.Format("UseCaptcha.{0}.Text", Enum.GetName(typeof(UseCaptcha), Convert.ToInt32(li.Value))), LocalResourceFile); + UseCaptchaRadioButtonList.Items.Add(new ListItem(Localization.GetString(string.Format("UseCaptcha.{0}.Text", Enum.GetName(typeof(UseCaptcha), useCaptcha)), LocalResourceFile), Convert.ToInt32(useCaptcha).ToString())); } UseCaptchaRadioButtonList.SelectedValue = Convert.ToInt32(UseCaptcha).ToString(); + foreach (Separator separator in (Separator[]) Enum.GetValues(typeof(Separator))) + { + CSVSeparatorDropDownlist.Items.Add(new ListItem(Localization.GetString(string.Format("Separator.{0}.Text", Enum.GetName(typeof(Separator), separator)), LocalResourceFile), Convert.ToInt32(separator).ToString())); + } + CSVSeparatorDropDownlist.SelectedValue = ((int)Separator).ToString(); + + foreach (TextQualifier textQualifier in (TextQualifier[]) Enum.GetValues(typeof(TextQualifier))) + { + CSVTextQualifierDropDownList.Items.Add(new ListItem(Localization.GetString(string.Format("TextQualifier.{0}.Text", Enum.GetName(typeof(TextQualifier), textQualifier)), LocalResourceFile), Convert.ToInt32(textQualifier).ToString())); + } + CSVTextQualifierDropDownList.SelectedValue = ((int)TextQualifier).ToString(); + base.LoadSettings(); } @@ -168,7 +218,8 @@ public override void UpdateSettings() PrivacyConfirmation = PrivacyConfirmationCheckBox.Checked; ShowClosingDateMessage = ShowClosingDateMessageCheckBox.Checked; UseCaptcha = (UseCaptcha)Convert.ToInt32(UseCaptchaRadioButtonList.SelectedValue); - + TextQualifier = (TextQualifier)Convert.ToInt32(CSVTextQualifierDropDownList.SelectedValue); + Separator = (Separator)Convert.ToInt32(CSVSeparatorDropDownlist.SelectedValue); base.UpdateSettings(); } #endregion @@ -245,9 +296,16 @@ private void UpdateIntegerSetting(string settingName, int? settingValue, bool is { if (isTabModuleSetting) { - if (settingValue != null) + if (settingValue.HasValue) { - ModuleController.Instance.UpdateTabModuleSetting(TabModuleId, settingName, settingValue.ToString()); + if (settingValue.Value == 0) + { + ModuleController.Instance.DeleteTabModuleSetting(TabModuleId, settingName); + } + else + { + ModuleController.Instance.UpdateTabModuleSetting(TabModuleId, settingName, settingValue.ToString()); + } } else { @@ -256,9 +314,16 @@ private void UpdateIntegerSetting(string settingName, int? settingValue, bool is } else { - if (settingValue != null) + if (settingValue.HasValue) { - ModuleController.Instance.UpdateModuleSetting(ModuleId, settingName, settingValue.ToString()); + if (settingValue.Value == 0) + { + ModuleController.Instance.DeleteModuleSetting(ModuleId, settingName); + } + else + { + ModuleController.Instance.UpdateModuleSetting(ModuleId, settingName, settingValue.ToString()); + } } else { diff --git a/DNN.Survey/Settings.ascx.designer.cs b/DNN.Survey/Settings.ascx.designer.cs index 5932bcf..91ca6f4 100644 --- a/DNN.Survey/Settings.ascx.designer.cs +++ b/DNN.Survey/Settings.ascx.designer.cs @@ -7,99 +7,164 @@ // //------------------------------------------------------------------------------ -namespace DNN.Modules.Survey { - - - public partial class Settings { - - /// - /// SurveyTypeLabel-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::DotNetNuke.UI.UserControls.LabelControl SurveyTypeLabel; - - /// - /// SurveyTypeRadioButtonList-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::System.Web.UI.WebControls.RadioButtonList SurveyTypeRadioButtonList; - - /// - /// SurveyClosingDateLabel-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::DotNetNuke.UI.UserControls.LabelControl SurveyClosingDateLabel; - - /// - /// SurveyClosingDateTextBox-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::System.Web.UI.WebControls.TextBox SurveyClosingDateTextBox; - - /// - /// ShowClosingDateMessageLabel-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::DotNetNuke.UI.UserControls.LabelControl ShowClosingDateMessageLabel; - - /// - /// ShowClosingDateMessageCheckBox-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::System.Web.UI.WebControls.CheckBox ShowClosingDateMessageCheckBox; - - /// - /// PrivacyConfirmationLabel-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::DotNetNuke.UI.UserControls.LabelControl PrivacyConfirmationLabel; - - /// - /// PrivacyConfirmationCheckBox-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::System.Web.UI.WebControls.CheckBox PrivacyConfirmationCheckBox; - - /// - /// UseCaptchaLabel-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::DotNetNuke.UI.UserControls.LabelControl UseCaptchaLabel; - - /// - /// UseCaptchaRadioButtonList-Steuerelement - /// - /// - /// Automatisch generiertes Feld - /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. - /// - protected global::System.Web.UI.WebControls.RadioButtonList UseCaptchaRadioButtonList; - } +namespace DNN.Modules.Survey +{ + + + public partial class Settings + { + + /// + /// GeneralSettingsLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.Label GeneralSettingsLabel; + + /// + /// SurveyTypeLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl SurveyTypeLabel; + + /// + /// SurveyTypeRadioButtonList-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.RadioButtonList SurveyTypeRadioButtonList; + + /// + /// SurveyClosingDateLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl SurveyClosingDateLabel; + + /// + /// SurveyClosingDateTextBox-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.TextBox SurveyClosingDateTextBox; + + /// + /// AppearanceSecurityOptionsLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.Label AppearanceSecurityOptionsLabel; + + /// + /// ShowClosingDateMessageLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl ShowClosingDateMessageLabel; + + /// + /// ShowClosingDateMessageCheckBox-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.CheckBox ShowClosingDateMessageCheckBox; + + /// + /// PrivacyConfirmationLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl PrivacyConfirmationLabel; + + /// + /// PrivacyConfirmationCheckBox-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.CheckBox PrivacyConfirmationCheckBox; + + /// + /// UseCaptchaLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl UseCaptchaLabel; + + /// + /// UseCaptchaRadioButtonList-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.RadioButtonList UseCaptchaRadioButtonList; + + /// + /// CSVExportOptionsLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.Label CSVExportOptionsLabel; + + /// + /// CSVSeparatorLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl CSVSeparatorLabel; + + /// + /// CSVSeparatorDropDownlist-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.DropDownList CSVSeparatorDropDownlist; + + /// + /// CSVTextQualifierLabel-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::DotNetNuke.UI.UserControls.LabelControl CSVTextQualifierLabel; + + /// + /// CSVTextQualifierDropDownList-Steuerelement + /// + /// + /// Automatisch generiertes Feld + /// Zum Ändern Felddeklaration aus der Designerdatei in eine Code-Behind-Datei verschieben. + /// + protected global::System.Web.UI.WebControls.DropDownList CSVTextQualifierDropDownList; + } } diff --git a/DNN.Survey/SurveyOrganize.ascx.cs b/DNN.Survey/SurveyOrganize.ascx.cs index 380d58f..08aeebb 100644 --- a/DNN.Survey/SurveyOrganize.ascx.cs +++ b/DNN.Survey/SurveyOrganize.ascx.cs @@ -82,7 +82,7 @@ protected override void OnInit(EventArgs e) protected override void OnLoad(EventArgs e) { - if (!(Page.IsPostBack)) + if (!Page.IsPostBack) { Surveys = SurveysController.GetAll(ModuleId); QuestionsGrid.DataSource = Surveys; diff --git a/DNN.Survey/SurveyResults.ascx.cs b/DNN.Survey/SurveyResults.ascx.cs index ccc1494..948cdbd 100644 --- a/DNN.Survey/SurveyResults.ascx.cs +++ b/DNN.Survey/SurveyResults.ascx.cs @@ -21,6 +21,7 @@ using DNN.Modules.Survey.Components; using DNN.Modules.Survey.Components.Controllers; using DNN.Modules.Survey.Components.Entities; +using DNN.Modules.Survey.Components.UI; using DNN.Modules.Survey.Controls; using DotNetNuke.Common; using DotNetNuke.Entities.Modules; @@ -28,6 +29,7 @@ using DotNetNuke.Security; using DotNetNuke.Security.Permissions; using DotNetNuke.Services.Localization; +using DotNetNuke.UI.Utilities; using DotNetNuke.Web.Client.ClientResourceManagement; using System; using System.Collections.Generic; @@ -215,7 +217,7 @@ protected override void OnPreRender(EventArgs e) StringBuilder bColorsBuilder = new StringBuilder(); foreach (SurveyResultInfo r in result) { - labelBuilder.Append(string.Format("\"{0}\"", String.Format("{0}{1}", r.OptionName, r.IsCorrect ? string.Format(" {0}", Localization.GetString("CorrectAnswer.Text", LocalResourceFile)) : string.Empty))); + labelBuilder.Append(string.Format("\"{0}\"", String.Format("{0}{1}", ClientAPI.GetSafeJSString(r.OptionName), r.IsCorrect ? string.Format(" {0}", Localization.GetString("CorrectAnswer.Text", LocalResourceFile)) : string.Empty))); dataBuilder.Append(r.Votes); bgColorsBuilder.Append(string.Format("\"{0}\"", Base.GetColor(result.IndexOf(r), (!(r.IsCorrect))))); bColorsBuilder.Append(string.Format("\"{0}\"", r.IsCorrect ? "rgba(0,170,0,1)" : Base.GetColor(result.IndexOf(r), false))); @@ -243,7 +245,7 @@ protected override void OnPreRender(EventArgs e) protected void ViewSurveyButton_Click(object sender, EventArgs e) { - Response.Redirect(Globals.NavigateURL(), false); + Response.Redirect(DotNetNuke.Common.Globals.NavigateURL(), false); } #endregion } diff --git a/DNN.Survey/SurveyView.ascx.cs b/DNN.Survey/SurveyView.ascx.cs index e1f75eb..3a1fe8e 100644 --- a/DNN.Survey/SurveyView.ascx.cs +++ b/DNN.Survey/SurveyView.ascx.cs @@ -37,6 +37,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using System.Text.RegularExpressions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; @@ -51,6 +52,7 @@ public partial class SurveyView : PortalModuleBase, IActionable private SurveyOptionsController _surveyOptionsController = null; private SurveyResultsController _surveyResultsController = null; private SurveyBusinessController _surveyBusinessController = null; + private PortalSecurity _portalSecurity = null; private string _cookie; @@ -59,7 +61,9 @@ protected ModulePermissionCollection ModulePermissionCollection get { if (_modulePermissionCollection == null) + { _modulePermissionCollection = ModulePermissionController.GetModulePermissions(ModuleId, TabId); + } return _modulePermissionCollection; } } @@ -69,7 +73,9 @@ protected SurveysController SurveysController get { if (_surveysController == null) + { _surveysController = new SurveysController(); + } return _surveysController; } } @@ -79,7 +85,9 @@ protected SurveyOptionsController SurveyOptionsController get { if (_surveyOptionsController == null) + { _surveyOptionsController = new SurveyOptionsController(); + } return _surveyOptionsController; } } @@ -89,7 +97,9 @@ protected SurveyResultsController SurveyResultsController get { if (_surveyResultsController == null) + { _surveyResultsController = new SurveyResultsController(); + } return _surveyResultsController; } } @@ -99,11 +109,26 @@ protected SurveyBusinessController SurveyBusinessController get { if (_surveyBusinessController == null) + { _surveyBusinessController = new SurveyBusinessController(); + } + return _surveyBusinessController; } } + protected PortalSecurity PortalSecurity + { + get + { + if (_portalSecurity == null) + { + _portalSecurity = new PortalSecurity(); + } + return _portalSecurity; + } + } + protected bool IsSurveyExpired { get @@ -182,9 +207,13 @@ protected SurveyType SurveyType { object surveyType = Settings["SurveyType"]; if (surveyType == null) + { return SurveyType.Survey; + } else + { return (SurveyType)Convert.ToInt32(surveyType); + } } } @@ -194,9 +223,13 @@ protected DateTime SurveyClosingDate { object surveyClosingDate = Settings["SurveyClosingDate"]; if (surveyClosingDate == null) + { return DateTime.MinValue; + } else + { return Convert.ToDateTime(surveyClosingDate); + } } } @@ -206,9 +239,13 @@ protected bool ShowClosingDateMessage { object showClosingDateMessage = Settings["ShowClosingDateMessage"]; if (showClosingDateMessage == null) + { return false; + } else + { return Convert.ToBoolean(showClosingDateMessage); + } } } @@ -218,9 +255,13 @@ protected bool PrivacyConfirmation { object privacyConfirmation = Settings["PrivacyConfirmation"]; if (privacyConfirmation == null) + { return false; + } else + { return Convert.ToBoolean(privacyConfirmation); + } } } @@ -230,9 +271,13 @@ protected UseCaptcha UseCaptcha { object useCaptcha = Settings["UseCaptcha"]; if (useCaptcha == null) + { return UseCaptcha.Never; + } else + { return (UseCaptcha)Convert.ToInt32(useCaptcha); + } } } @@ -243,9 +288,43 @@ protected int ResultsVersion { object resultsVersion = Settings["ResultsVersion"]; if (resultsVersion == null) + { return 0; + } else + { return Convert.ToInt32(resultsVersion); + } + } + } + protected Separator Separator + { + get + { + object separator = Settings["Separator"]; + if (separator == null) + { + return Separator.SemiColon; + } + else + { + return (Separator)Convert.ToInt32(separator); + } + } + } + protected TextQualifier TextQualifier + { + get + { + object textQualifier = Settings["TextQualifier"]; + if (textQualifier == null) + { + return TextQualifier.None; + } + else + { + return (TextQualifier)Convert.ToInt32(textQualifier); + } } } #endregion @@ -440,7 +519,7 @@ protected void SubmitSurveyButton_Click(object sender, EventArgs e) surveyResult.SurveyOptionID = surveyTextBox.SurveyOptionID; surveyResult.UserID = (UserId < 1 ? (int?)null : UserId); surveyResult.IPAddress = Request.ServerVariables["REMOTE_ADDR"]; - surveyResult.TextAnswer = surveyTextBox.Text; + surveyResult.TextAnswer = PortalSecurity.InputFilter(surveyTextBox.Text, PortalSecurity.FilterFlag.MultiLine | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup | PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoSQL); surveyResult.IsCorrect = true; surveyResult.ResultUserID = resultUserID; surveyResults.Add(surveyResult); @@ -503,7 +582,7 @@ protected void ContactByFaxOnlyCheckBox_CheckedChanged(object sender, EventArgs protected void ExportToCsvButton_Click(object sender, EventArgs e) { - string csv = SurveyBusinessController.CSVExport(ModuleId, Localization.SharedResourceFile); + string csv = SurveyBusinessController.CSVExport(ModuleId, Localization.SharedResourceFile, Separator, TextQualifier); Response.Clear(); Response.Charset = string.Empty; Response.AddHeader("content-disposition", string.Format("attachment; filename=Survey_Results_{0}_{1:yyyy-MM-dd-hhmmss}.csv", ModuleId, DateTime.Now)); @@ -699,7 +778,7 @@ private void SurveyActions_Click(object sender, ActionEventArgs e) case "ExportToCsv": try { - string csv = SurveyBusinessController.CSVExport(ModuleId, Localization.SharedResourceFile); + string csv = SurveyBusinessController.CSVExport(ModuleId, Localization.SharedResourceFile, Separator, TextQualifier); Response.Clear(); Response.Charset = string.Empty; Response.AddHeader("content-disposition", string.Format("attachment; filename=Survey_Results_{0}_{1:yyyy-MM-dd-hhmmss}.csv", ModuleId, DateTime.Now)); diff --git a/DNN.Survey/js/Chart.min.js b/DNN.Survey/js/Chart.min.js index 653e7cf..7c16b0d 100644 --- a/DNN.Survey/js/Chart.min.js +++ b/DNN.Survey/js/Chart.min.js @@ -1,10 +1,7 @@ /*! - * Chart.js - * http://chartjs.org/ - * Version: 2.7.3 - * - * Copyright 2018 Chart.js Contributors - * Released under the MIT license - * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md + * Chart.js v2.9.3 + * https://www.chartjs.org + * (c) 2019 Chart.js Contributors + * Released under the MIT License */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function o(r,s,l){function u(e,t){if(!s[e]){if(!r[e]){var i="function"==typeof require&&require;if(!t&&i)return i(e,!0);if(d)return d(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};r[e][0].call(a.exports,function(t){return u(r[e][1][t]||t)},a,a.exports,o,r,s,l)}return s[e].exports}for(var d="function"==typeof require&&require,t=0;t');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o'),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(l){var u=l.data;return u.labels.length&&u.datasets.length?u.labels.map(function(t,e){var i=l.getDatasetMeta(0),n=u.datasets[0],a=i.data[e],o=a&&a.custom||{},r=A.valueAtIndexOrDefault,s=l.options.elements.arc;return{text:t,fillStyle:o.backgroundColor?o.backgroundColor:r(n.backgroundColor,e,s.backgroundColor),strokeStyle:o.borderColor?o.borderColor:r(n.borderColor,e,s.borderColor),lineWidth:o.borderWidth?o.borderWidth:r(n.borderWidth,e,s.borderWidth),hidden:isNaN(n.data[e])||i.data[e].hidden,index:e}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i=Math.PI?-1:f<-Math.PI?1:0))+h,p=Math.cos(f),m=Math.sin(f),v=Math.cos(g),b=Math.sin(g),x=f<=0&&0<=g||f<=2*Math.PI&&2*Math.PI<=g,y=f<=.5*Math.PI&&.5*Math.PI<=g||f<=2.5*Math.PI&&2.5*Math.PI<=g,k=f<=-Math.PI&&-Math.PI<=g||f<=Math.PI&&Math.PI<=g,M=f<=.5*-Math.PI&&.5*-Math.PI<=g||f<=1.5*Math.PI&&1.5*Math.PI<=g,w=c/100,C=k?-1:Math.min(p*(p<0?1:w),v*(v<0?1:w)),S=M?-1:Math.min(m*(m<0?1:w),b*(b<0?1:w)),_=x?1:Math.max(p*(0');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o'),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(s){var l=s.data;return l.labels.length&&l.datasets.length?l.labels.map(function(t,e){var i=s.getDatasetMeta(0),n=l.datasets[0],a=i.data[e].custom||{},o=k.valueAtIndexOrDefault,r=s.options.elements.arc;return{text:t,fillStyle:a.backgroundColor?a.backgroundColor:o(n.backgroundColor,e,r.backgroundColor),strokeStyle:a.borderColor?a.borderColor:o(n.borderColor,e,r.borderColor),lineWidth:a.borderWidth?a.borderWidth:o(n.borderWidth,e,r.borderWidth),hidden:isNaN(n.data[e])||i.data[e].hidden,index:e}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i=e.numSteps?(o.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}}},{26:26,46:46}],24:[function(t,e,i){"use strict";var s=t(22),l=t(23),c=t(26),h=t(46),a=t(29),o=t(31),f=t(49),g=t(32),p=t(34),n=t(36);e.exports=function(u){function d(t){return"top"===t||"bottom"===t}u.types={},u.instances={},u.controllers={},h.extend(u.prototype,{construct:function(t,e){var i,n,a=this;(n=(i=(i=e)||{}).data=i.data||{}).datasets=n.datasets||[],n.labels=n.labels||[],i.options=h.configMerge(c.global,c[i.type],i.options||{}),e=i;var o=f.acquireContext(t,e),r=o&&o.canvas,s=r&&r.height,l=r&&r.width;a.id=h.uid(),a.ctx=o,a.canvas=r,a.config=e,a.width=l,a.height=s,a.aspectRatio=s?l/s:null,a.options=e.options,a._bufferedRender=!1,(a.chart=a).controller=a,u.instances[a.id]=a,Object.defineProperty(a,"data",{get:function(){return a.config.data},set:function(t){a.config.data=t}}),o&&r?(a.initialize(),a.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return g.notify(t,"beforeInit"),h.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),g.notify(t,"afterInit"),t},clear:function(){return h.canvas.clear(this),this},stop:function(){return l.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,a=i.maintainAspectRatio&&e.aspectRatio||null,o=Math.max(0,Math.floor(h.getMaximumWidth(n))),r=Math.max(0,Math.floor(a?o/a:h.getMaximumHeight(n)));if((e.width!==o||e.height!==r)&&(n.width=e.width=o,n.height=e.height=r,n.style.width=o+"px",n.style.height=r+"px",h.retinaScale(e,i.devicePixelRatio),!t)){var s={width:o,height:r};g.notify(e,"resize",[s]),e.options.onResize&&e.options.onResize(e,s),e.stop(),e.update({duration:e.options.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;h.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),h.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var r=this,t=r.options,s=r.scales||{},e=[],l=Object.keys(s).reduce(function(t,e){return t[e]=!1,t},{});t.scales&&(e=e.concat((t.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(t.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),t.scale&&e.push({options:t.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),h.each(e,function(t){var e=t.options,i=e.id,n=h.valueOrDefault(e.type,t.dtype);d(e.position)!==d(t.dposition)&&(e.position=t.dposition),l[i]=!0;var a=null;if(i in s&&s[i].type===n)(a=s[i]).options=e,a.ctx=r.ctx,a.chart=r;else{var o=p.getScaleConstructor(n);if(!o)return;a=new o({id:i,type:n,options:e,ctx:r.ctx,chart:r}),s[a.id]=a}a.mergeTicksOptions(),t.isDefault&&(r.scale=a)}),h.each(l,function(t,e){t||delete s[e]}),r.scales=s,p.addScalesToLayout(this)},buildOrUpdateControllers:function(){var o=this,r=[],s=[];return h.each(o.data.datasets,function(t,e){var i=o.getDatasetMeta(e),n=t.type||o.config.type;if(i.type&&i.type!==n&&(o.destroyDatasetMeta(e),i=o.getDatasetMeta(e)),i.type=n,r.push(i.type),i.controller)i.controller.updateIndex(e),i.controller.linkScales();else{var a=u.controllers[i.type];if(void 0===a)throw new Error('"'+i.type+'" is not a chart type.');i.controller=new a(o,e),s.push(i.controller)}},o),s},resetElements:function(){var i=this;h.each(i.data.datasets,function(t,e){i.getDatasetMeta(e).controller.reset()},i)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,i,n=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),i=(e=n).options,h.each(e.scales,function(t){o.removeBox(e,t)}),i=h.configMerge(u.defaults.global,u.defaults[e.config.type],i),e.options=e.config.options=i,e.ensureScalesHaveIDs(),e.buildOrUpdateScales(),e.tooltip._options=i.tooltips,e.tooltip.initialize(),g._invalidate(n),!1!==g.notify(n,"beforeUpdate")){n.tooltip._data=n.data;var a=n.buildOrUpdateControllers();h.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.buildOrUpdateElements()},n),n.updateLayout(),n.options.animation&&n.options.animation.duration&&h.each(a,function(t){t.reset()}),n.updateDatasets(),n.tooltip.initialize(),n.lastActive=[],g.notify(n,"afterUpdate"),n._bufferedRender?n._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:n.render(t)}},updateLayout:function(){!1!==g.notify(this,"beforeLayout")&&(o.update(this,this.width,this.height),g.notify(this,"afterScaleUpdate"),g.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==g.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t=e[t].length&&e[t].push({}),!e[t][a].type||r.type&&r.type!==e[t][a].type?g.merge(e[t][a],[l.getScaleDefaults(o),r]):g.merge(e[t][a],r)}else g._merger(t,e,i,n)}})},g.where=function(t,e){if(g.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return g.each(t,function(t){e(t)&&i.push(t)}),i},g.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},g.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},g.niceNum=function(t,e){var i=Math.floor(g.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},g.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},g.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,o=t.target||t.srcElement,r=o.getBoundingClientRect(),s=a.touches;n=s&&0i.length){for(var l=0;le&&(e=t.length)}),e},g.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},g.getHoverColor=function(t){return t instanceof CanvasPattern?t:g.color(t).saturate(.5).darken(.1).rgbString()}}},{26:26,3:3,34:34,46:46}],29:[function(t,e,i){"use strict";var n=t(46);function s(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function l(t,e){var i,n,a,o,r;for(n=0,o=t.data.datasets.length;nt.maxHeight){o--;break}o++,l=r*s}t.labelRotation=o},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},i=k(t._ticks),n=t.options,a=n.ticks,o=n.scaleLabel,r=n.gridLines,s=n.display,l=t.isHorizontal(),u=w(a),d=n.gridLines.tickMarkLength;if(e.width=l?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:s&&r.drawTicks?d:0,e.height=l?s&&r.drawTicks?d:0:t.maxHeight,o.display&&s){var c=C(o)+H.options.toPadding(o.padding).height;l?e.height+=c:e.width+=c}if(a.display&&s){var h=H.longestText(t.ctx,u.font,i,t.longestTextCache),f=H.numberOfLabelLines(i),g=.5*u.size,p=t.options.ticks.padding;if(l){t.longestLabelWidth=h;var m=H.toRadians(t.labelRotation),v=Math.cos(m),b=Math.sin(m)*h+u.size*f+g*(f-1)+g;e.height=Math.min(t.maxHeight,e.height+b+p),t.ctx.font=u.font;var x=M(t.ctx,i[0],u.font),y=M(t.ctx,i[i.length-1],u.font);0!==t.labelRotation?(t.paddingLeft="bottom"===n.position?v*x+3:v*g+3,t.paddingRight="bottom"===n.position?v*g+3:v*y+3):(t.paddingLeft=x/2+3,t.paddingRight=y/2+3)}else a.mirror?h=0:h+=p+g,e.width=Math.min(t.maxWidth,e.width+h),t.paddingTop=u.size/2,t.paddingBottom=u.size/2}t.handleMargins(),t.width=e.width,t.height=e.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(H.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:H.noop,getPixelForValue:H.noop,getValueForPixel:H.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+Math.round(a);return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:0o.width-(o.paddingLeft+o.paddingRight)&&(e=1+Math.floor((c+s.autoSkipPadding)*l/(o.width-(o.paddingLeft+o.paddingRight)))),a&&al.height-e.height&&(c="bottom");var h=(u.left+u.right)/2,f=(u.top+u.bottom)/2;n="center"===c?(i=function(t){return t<=h},function(t){return h=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",c=r(s.y))):n(s.x)&&(d="right",o(s.x)&&(d="center",c=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:c}}(this,I=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,l=e.footer.length,u=e.titleFontSize,d=e.bodyFontSize,c=e.footerFontSize;n+=s*u,n+=s?(s-1)*e.titleSpacing:0,n+=s?e.titleMarginBottom:0,n+=r*d,n+=r?(r-1)*e.bodySpacing:0,n+=l?e.footerMarginTop:0,n+=l*c,n+=l?(l-1)*e.footerSpacing:0;var h=0,f=function(t){a=Math.max(a,i.measureText(t).width+h)};return i.font=R.fontString(u,e._titleFontStyle,e._titleFontFamily),R.each(e.title,f),i.font=R.fontString(d,e._bodyFontStyle,e._bodyFontFamily),R.each(e.beforeBody.concat(e.afterBody),f),h=e.displayColors?d+2:0,R.each(o,function(t){R.each(t.before,f),R.each(t.lines,f),R.each(t.after,f)}),h=0,i.font=R.fontString(c,e._footerFontStyle,e._footerFontFamily),R.each(e.footer,f),{width:a+=2*e.xPadding,height:n}}(this,C)),n=C,a=I,o=D,r=k._chart,s=n.x,l=n.y,u=n.caretSize,d=n.caretPadding,c=n.cornerRadius,h=o.xAlign,f=o.yAlign,g=u+d,p=c+d,"right"===h?s-=a.width:"center"===h&&((s-=a.width/2)+a.width>r.width&&(s=r.width-a.width),s<0&&(s=0)),"top"===f?l+=g:l-="bottom"===f?a.height+g:a.height/2,"center"===f?"left"===h?s+=g:"right"===h&&(s-=g):"left"===h?s-=p:"right"===h&&(s+=p),P={x:s,y:l}}else C.opacity=0;return C.xAlign=D.xAlign,C.yAlign=D.yAlign,C.x=P.x,C.y=P.y,C.width=I.width,C.height=I.height,C.caretX=A.x,C.caretY=A.y,k._model=C,t&&M.custom&&M.custom.call(k,C),k},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,u=i.caretSize,d=i.cornerRadius,c=i.xAlign,h=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)s=g+m/2,l="left"===c?(a=(n=f)-u,o=n,r=s+u,s-u):(a=(n=f+p)+u,o=n,r=s-u,s+u);else if(o=(n="left"===c?(a=f+d+u)-u:"right"===c?(a=f+p-d-u)-u:(a=i.caretX)-u,a+u),"top"===h)s=(r=g)-u,l=r;else{s=(r=g+m)+u,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,e,i,n){var a=e.title;if(a.length){i.textAlign=e._titleAlign,i.textBaseline="top";var o,r,s=e.titleFontSize,l=e.titleSpacing;for(i.fillStyle=h(e.titleFontColor,n),i.font=R.fontString(s,e._titleFontStyle,e._titleFontFamily),o=0,r=a.length;o=i.innerRadius&&o<=i.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{26:26,27:27,46:46}],38:[function(t,e,i){"use strict";var n=t(26),a=t(27),d=t(46),c=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:c.defaultColor,borderWidth:3,borderColor:c.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,o=this._chart.ctx,r=a.spanGaps,s=this._children.slice(),l=c.elements.line,u=-1;for(this._loop&&s.length&&s.push(s[0]),o.save(),o.lineCap=a.borderCapStyle||l.borderCapStyle,o.setLineDash&&o.setLineDash(a.borderDash||l.borderDash),o.lineDashOffset=a.borderDashOffset||l.borderDashOffset,o.lineJoin=a.borderJoinStyle||l.borderJoinStyle,o.lineWidth=a.borderWidth||l.borderWidth,o.strokeStyle=a.borderColor||c.defaultColor,o.beginPath(),u=-1,t=0;t=t.left&&1.01*t.right>=i.x&&i.y>=t.top&&1.01*t.bottom>=i.y)&&(n.strokeStyle=e.borderColor||c,n.lineWidth=d.valueOrDefault(e.borderWidth,u.global.elements.point.borderWidth),n.fillStyle=e.backgroundColor||c,d.canvas.drawPoint(n,a,r,s,l,o))}})},{26:26,27:27,46:46}],40:[function(t,e,i){"use strict";var n=t(26),a=t(27);function l(t){return void 0!==t._view.width}function o(t){var e,i,n,a,o=t._view;if(l(t)){var r=o.width/2;e=o.x-r,i=o.x+r,n=Math.min(o.y,o.base),a=Math.max(o.y,o.base)}else{var s=o.height/2;e=Math.min(o.x,o.base),i=Math.max(o.x,o.base),n=o.y-s,a=o.y+s}return{left:e,top:n,right:i,bottom:a}}n._set("global",{elements:{rectangle:{backgroundColor:n.global.defaultColor,borderColor:n.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a,o,r,s=this._chart.ctx,l=this._view,u=l.borderWidth;if(r=l.horizontal?(t=l.base,e=l.x,i=l.y-l.height/2,n=l.y+l.height/2,a=t=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=o(this);return l(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=o(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=o(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return e=l(this)?(t=i.x,(i.y+i.base)/2):(t=(i.x+i.base)/2,i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{26:26,27:27}],41:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(37),e.exports.Line=t(38),e.exports.Point=t(39),e.exports.Rectangle=t(40)},{37:37,38:38,39:39,40:40}],42:[function(t,e,i){"use strict";var n=t(43);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,a/2-1e-7,n/2-1e-7);t.moveTo(e+r,i),t.lineTo(e+n-r,i),t.arcTo(e+n,i,e+n,i+r,r),t.lineTo(e+n,i+a-r),t.arcTo(e+n,i+a,e+n-r,i+a,r),t.lineTo(e+r,i+a),t.arcTo(e,i+a,e,i+a-r,r),t.lineTo(e,i+r),t.arcTo(e,i,e+r,i,r),t.closePath(),t.moveTo(e,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a,o){var r,s,l,u,d,c;if(o=o||0,!e||"object"!=typeof e||"[object HTMLImageElement]"!==(r=e.toString())&&"[object HTMLCanvasElement]"!==r){if(!(isNaN(i)||i<=0)){switch(t.save(),t.translate(n,a),t.rotate(o*Math.PI/180),t.beginPath(),e){default:t.arc(0,0,i,0,2*Math.PI),t.closePath();break;case"triangle":d=(s=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(-s/2,d/3),t.lineTo(s/2,d/3),t.lineTo(0,-2*d/3),t.closePath();break;case"rect":c=1/Math.SQRT2*i,t.rect(-c,-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=-h,g=-h,p=Math.SQRT2*i;this.roundedRect(t,f,g,p,p,.425*i);break;case"rectRot":c=1/Math.SQRT2*i,t.moveTo(-c,0),t.lineTo(0,c),t.lineTo(c,0),t.lineTo(0,-c),t.closePath();break;case"cross":t.moveTo(0,i),t.lineTo(0,-i),t.moveTo(-i,0),t.lineTo(i,0);break;case"crossRot":l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,t.moveTo(-l,-u),t.lineTo(l,u),t.moveTo(-l,u),t.lineTo(l,-u);break;case"star":t.moveTo(0,i),t.lineTo(0,-i),t.moveTo(-i,0),t.lineTo(i,0),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,t.moveTo(-l,-u),t.lineTo(l,u),t.moveTo(-l,u),t.lineTo(l,-u);break;case"line":t.moveTo(-i,0),t.lineTo(i,0);break;case"dash":t.moveTo(0,0),t.lineTo(i,0)}t.fill(),t.stroke(),t.restore()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments)}},{43:43}],43:[function(t,e,i){"use strict";var n,d={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return d.valueOrDefault(d.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var a,o,r;if(d.isArray(t))if(o=t.length,n)for(a=o-1;0<=a;a--)e.call(i,t[a],a);else for(a=0;a
    ';var a=e.childNodes[0],o=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,o.scrollLeft=1e6,o.scrollTop=1e6};var r=function(){e._reset(),t()};return x(a,"scroll",r.bind(a,"expand")),x(o,"scroll",r.bind(o,"shrink")),e}((o=!(n=function(){if(c.resizer)return t(y("resize",i))}),r=[],function(){r=Array.prototype.slice.call(arguments),a=a||this,o||(o=!0,f.requestAnimFrame.call(window,function(){o=!1,n.apply(a,r)}))}));l=function(){if(c.resizer){var t=e.parentNode;t&&t!==h.parentNode&&t.insertBefore(h,t.firstChild),h._reset()}},u=(s=e)[g]||(s[g]={}),d=u.renderProxy=function(t){t.animationName===v&&l()},f.each(b,function(t){x(s,t,d)}),u.reflow=!!s.offsetParent,s.classList.add(m)}function o(t){var e,i,n,a=t[g]||{},o=a.resizer;delete a.resizer,i=(e=t)[g]||{},(n=i.renderProxy)&&(f.each(b,function(t){r(e,t,n)}),delete i.renderProxy),e.classList.remove(m),o&&o.parentNode&&o.parentNode.removeChild(o)}e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t,e,i,n="from{opacity:0.99}to{opacity:1}";e="@-webkit-keyframes "+v+"{"+n+"}@keyframes "+v+"{"+n+"}."+m+"{-webkit-animation:"+v+" 0.001s;animation:"+v+" 0.001s;}",i=(t=this)._style||document.createElement("style"),t._style||(e="/* Chart.js */\n"+e,(t._style=i).setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(i)),i.appendChild(document.createTextNode(e))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){var i=t.style,n=t.getAttribute("height"),a=t.getAttribute("width");if(t[g]={initial:{height:n,width:a,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===a||""===a){var o=l(t,"width");void 0!==o&&(t.width=o)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var r=l(t,"height");void 0!==o&&(t.height=r)}}(t,e),i):null},releaseContext:function(t){var i=t.canvas;if(i[g]){var n=i[g].initial;["height","width"].forEach(function(t){var e=n[t];f.isNullOrUndef(e)?i.removeAttribute(t):i.setAttribute(t,e)}),f.each(n.style||{},function(t,e){i.style[e]=t}),i.width=i.width,delete i[g]}},addEventListener:function(o,t,r){var e=o.canvas;if("resize"!==t){var i=r[g]||(r[g]={});x(e,t,(i.proxies||(i.proxies={}))[o.id+"_"+t]=function(t){var e,i,n,a;r((i=o,n=s[(e=t).type]||e.type,a=f.getRelativePosition(e,i),y(n,i,a.x,a.y,e)))})}else a(e,r,o)},removeEventListener:function(t,e,i){var n=t.canvas;if("resize"!==e){var a=((i[g]||{}).proxies||{})[t.id+"_"+e];a&&r(n,e,a)}else o(n)}},f.addEvent=x,f.removeEvent=r},{46:46}],49:[function(t,e,i){"use strict";var n=t(46),a=t(47),o=t(48),r=o._enabled?o:a;e.exports=n.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},r)},{46:46,47:47,48:48}],50:[function(t,e,i){"use strict";e.exports={},e.exports.filler=t(51),e.exports.legend=t(52),e.exports.title=t(53)},{51:51,52:52,53:53}],51:[function(t,e,i){"use strict";var u=t(26),h=t(41),d=t(46);u._set("global",{plugins:{filler:{propagate:!0}}});var f={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],o=a.length||0;return o?function(t,e){return e');for(var i=0;i'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("");return e.push(""),e.join("")}});var r=n.extend({initialize:function(t){D.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:o,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:function(){var e=this,i=e.options.labels||{},t=D.callback(i.generateLabels,[e.chart],e)||[];i.filter&&(t=t.filter(function(t){return i.filter(t,e.chart.data)})),e.options.reverse&&t.reverse(),e.legendItems=t},afterBuildLabels:o,beforeFit:o,fit:function(){var n=this,t=n.options,a=t.labels,e=t.display,o=n.ctx,i=_.global,r=D.valueOrDefault,s=r(a.fontSize,i.defaultFontSize),l=r(a.fontStyle,i.defaultFontStyle),u=r(a.fontFamily,i.defaultFontFamily),d=D.fontString(s,l,u),c=n.legendHitBoxes=[],h=n.minSize,f=n.isHorizontal();if(h.height=f?(h.width=n.maxWidth,e?10:0):(h.width=e?10:0,n.maxHeight),e)if(o.font=d,f){var g=n.lineWidths=[0],p=n.legendItems.length?s+a.padding:0;o.textAlign="left",o.textBaseline="top",D.each(n.legendItems,function(t,e){var i=P(a,s)+s/2+o.measureText(t.text).width;g[g.length-1]+i+a.padding>=n.width&&(p+=s+a.padding,g[g.length]=n.left),c[e]={left:0,top:0,width:i,height:s},g[g.length-1]+=i+a.padding}),h.height+=p}else{var m=a.padding,v=n.columnWidths=[],b=a.padding,x=0,y=0,k=s+m;D.each(n.legendItems,function(t,e){var i=P(a,s)+s/2+o.measureText(t.text).width;y+k>h.height&&(b+=x+a.padding,v.push(x),y=x=0),x=Math.max(x,i),y+=k,c[e]={left:0,top:0,width:i,height:s}}),b+=x,v.push(x),h.width+=b}n.width=h.width,n.height=h.height},afterFit:o,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var c=this,h=c.options,f=h.labels,g=_.global,p=g.elements.line,m=c.width,v=c.lineWidths;if(h.display){var b,x=c.ctx,y=D.valueOrDefault,t=y(f.fontColor,g.defaultFontColor),k=y(f.fontSize,g.defaultFontSize),e=y(f.fontStyle,g.defaultFontStyle),i=y(f.fontFamily,g.defaultFontFamily),n=D.fontString(k,e,i);x.textAlign="left",x.textBaseline="middle",x.lineWidth=.5,x.strokeStyle=t,x.fillStyle=t,x.font=n;var M=P(f,k),w=c.legendHitBoxes,C=c.isHorizontal();b=C?{x:c.left+(m-v[0])/2,y:c.top+f.padding,line:0}:{x:c.left+f.padding,y:c.top+f.padding,line:0};var S=k+f.padding;D.each(c.legendItems,function(t,e){var i,n,a,o,r,s=x.measureText(t.text).width,l=M+k/2+s,u=b.x,d=b.y;C?m<=u+l&&(d=b.y+=S,b.line++,u=b.x=c.left+(m-v[b.line])/2):d+S>c.bottom&&(u=b.x=u+c.columnWidths[b.line]+f.padding,d=b.y=c.top+f.padding,b.line++),function(t,e,i){if(!(isNaN(M)||M<=0)){x.save(),x.fillStyle=y(i.fillStyle,g.defaultColor),x.lineCap=y(i.lineCap,p.borderCapStyle),x.lineDashOffset=y(i.lineDashOffset,p.borderDashOffset),x.lineJoin=y(i.lineJoin,p.borderJoinStyle),x.lineWidth=y(i.lineWidth,p.borderWidth),x.strokeStyle=y(i.strokeStyle,g.defaultColor);var n=0===y(i.lineWidth,p.borderWidth);if(x.setLineDash&&x.setLineDash(y(i.lineDash,p.borderDash)),h.labels&&h.labels.usePointStyle){var a=k*Math.SQRT2/2,o=a/Math.SQRT2,r=t+o,s=e+o;D.canvas.drawPoint(x,i.pointStyle,a,r,s)}else n||x.strokeRect(t,e,M,k),x.fillRect(t,e,M,k);x.restore()}}(u,d,t),w[e].left=u,w[e].top=d,i=t,n=s,o=M+(a=k/2)+u,r=d+a,x.fillText(i.text,o,r),i.hidden&&(x.beginPath(),x.lineWidth=2,x.moveTo(o,r),x.lineTo(o+n,r),x.stroke()),C?b.x+=l+f.padding:b.y+=S})}},handleEvent:function(t){var e=this,i=e.options,n="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===n){if(!i.onHover)return}else{if("click"!==n)return;if(!i.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===n){i.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===n){i.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function s(t,e){var i=new r({ctx:t.ctx,options:e,chart:t});a.configure(t,i,e),a.addBox(t,i),t.legend=i}e.exports={id:"legend",_element:r,beforeInit:function(t){var e=t.options.legend;e&&s(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(D.mergeIf(e,_.global.legend),i?(a.configure(t,i,e),i.options=e):s(t,e)):i&&(a.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}}},{26:26,27:27,31:31,46:46}],53:[function(t,e,i){"use strict";var M=t(26),n=t(27),w=t(46),a=t(31),o=w.noop;M._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var r=n.extend({initialize:function(t){w.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:o,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:o,afterBuildLabels:o,beforeFit:o,fit:function(){var t=this,e=w.valueOrDefault,i=t.options,n=i.display,a=e(i.fontSize,M.global.defaultFontSize),o=t.minSize,r=w.isArray(i.text)?i.text.length:1,s=w.options.toLineHeight(i.lineHeight,a),l=n?r*s+2*i.padding:0;t.isHorizontal()?(o.width=t.maxWidth,o.height=l):(o.width=l,o.height=t.maxHeight),t.width=o.width,t.height=o.height},afterFit:o,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,i=w.valueOrDefault,n=t.options,a=M.global;if(n.display){var o,r,s,l=i(n.fontSize,a.defaultFontSize),u=i(n.fontStyle,a.defaultFontStyle),d=i(n.fontFamily,a.defaultFontFamily),c=w.fontString(l,u,d),h=w.options.toLineHeight(n.lineHeight,l),f=h/2+n.padding,g=0,p=t.top,m=t.left,v=t.bottom,b=t.right;e.fillStyle=i(n.fontColor,a.defaultFontColor),e.font=c,t.isHorizontal()?(r=m+(b-m)/2,s=p+f,o=b-m):(r="left"===n.position?m+f:b-f,s=p+(v-p)/2,o=v-p,g=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(r,s),e.rotate(g),e.textAlign="center",e.textBaseline="middle";var x=n.text;if(w.isArray(x))for(var y=0,k=0;kr.max&&(r.max=i))})});r.min=isFinite(r.min)&&!isNaN(r.min)?r.min:0,r.max=isFinite(r.max)&&!isNaN(r.max)?r.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var i=c.valueOrDefault(e.fontSize,n.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*i)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,i=e.start,n=+e.getRightValue(t),a=e.end-i;return e.isHorizontal()?e.left+e.width/a*(n-i):e.bottom-e.height/a*(n-i)},getValueForPixel:function(t){var e=this,i=e.isHorizontal(),n=i?e.width:e.height,a=(i?t-e.left:e.bottom-t)/n;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});a.registerScaleType("linear",i,e)}},{26:26,34:34,35:35,46:46}],56:[function(t,e,i){"use strict";var c=t(46),n=t(33);e.exports=function(t){var e=c.noop;t.LinearScaleBase=n.extend({getRightValue:function(t){return"string"==typeof t?+t:n.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var i=c.sign(t.min),n=c.sign(t.max);i<0&&n<0?t.max=0:0=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),n={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,precision:e.precision,stepSize:c.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var i,n,a,o=[];if(t.stepSize&&0r.max&&(r.max=i),0!==i&&(null===r.minNotZero||ir.r&&(r.r=g.end,s.r=h),p.startr.b&&(r.b=p.end,s.b=h)}t.setReductions(o,r,s)}(this):(t=this,e=Math.min(t.height/2,t.width/2),t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0))},setReductions:function(t,e,i){var n=e.l/Math.sin(i.l),a=Math.max(e.r-this.width,0)/Math.sin(i.r),o=-e.t/Math.cos(i.t),r=-Math.max(e.b-this.height,0)/Math.cos(i.b);n=s(n),a=s(a),o=s(o),r=s(r),this.drawingArea=Math.min(Math.round(t-(n+a)/2),Math.round(t-(o+r)/2)),this.setCenterPoint(n,a,o,r)},setCenterPoint:function(t,e,i,n){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,s=i+a.drawingArea,l=a.height-n-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/b(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var i=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*i:(t-e.min)*i},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+this.xCenter,y:Math.round(Math.sin(i)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:0>1)-1]||null,o=t[n],!a)return{lo:null,hi:o};if(o[e]i))return{lo:a,hi:o};s=n-1}}return{lo:o,hi:null}}(t,e,i),o=a.lo?a.hi?a.lo:t[t.length-2]:t[0],r=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=r[e]-o[e],l=s?(i-o[e])/s:0,u=(r[n]-o[n])*l;return o[n]+u}function C(t,e){var i=e.parser,n=e.parser||e.format;return"function"==typeof i?i(t):"string"==typeof t&&"string"==typeof n?x(t,n):(t instanceof x||(t=x(t)),t.isValid()?t:"function"==typeof n?n(t):t)}function S(t,e){if(m.isNullOrUndef(t))return null;var i=e.options.time,n=C(e.getRightValue(t),i);return n.isValid()?(i.round&&n.startOf(i.round),n.valueOf()):null}function _(t){for(var e=k.indexOf(t)+1,i=k.length;e=k.indexOf(e);a--)if(o=k[a],y[o].common&&r.as(o)>=t.length)return o;return k[e?k.indexOf(e):0]}(b,m.minUnit,h.min,h.max),h._majorUnit=_(h._unit),h._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,o,r,s,l,u=[],d=[e];for(a=0,o=t.length;a1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-S.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*S.easeInBounce(2*t):.5*S.easeOutBounce(2*t-1)+.5}},C={effects:S};M.easingEffects=S;var P=Math.PI,A=P/180,D=2*P,T=P/2,I=P/4,F=2*P/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(V.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},J=V.options.resolve,Q=["push","pop","shift","splice","unshift"];function tt(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(Q.forEach((function(e){delete t[e]})),delete t._chartjs)}}var et=function(t,e){this.initialize(t,e)};V.extend(et.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&tt(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function rt(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+it,at(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=it,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+it,n.startAngle,!0),a=0;as;)a-=it;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/it)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+it,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=vt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function xt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&mt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}z._set("global",{elements:{rectangle:{backgroundColor:gt,borderColor:gt,borderSkipped:"bottom",borderWidth:0}}});var yt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=mt(t),n=e.right-e.left,i=e.bottom-e.top,a=bt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return xt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return pt(n)?xt(n,t,null):xt(n,null,e)},inXRange:function(t){return xt(this._view,t,null)},inYRange:function(t){return xt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return pt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return pt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),_t={},kt=ot,wt=ut,Mt=ft,St=yt;_t.Arc=kt,_t.Line=wt,_t.Point=Mt,_t.Rectangle=St;var Ct=V._deprecated,Pt=V.valueOrDefault;function At(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=V.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return V.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}z._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),z._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Dt=nt.extend({dataElementType:_t.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;nt.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Ct("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Ct("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Ct("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Ct("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Ct("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Ot?-Rt:b<-Ot?Rt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=Rt,S=b<=zt&&x>=zt||x>=Rt+zt,C=b<=-zt&&x>=-zt||x>=Ot+zt,P=b===-Ot||x>=Ot?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i0&&!isNaN(t)?Rt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Vt(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ie(t,e,{intersect:!1})},point:function(t,e){return te(t,Jt(e,t))},nearest:function(t,e,n){var i=Jt(e,t);n.axis=n.axis||"xy";var a=ne(n.axis);return ee(t,i,n.intersect,a)},x:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},re=V.extend;function oe(t,e){return V.where(t,(function(t){return t.pos===e}))}function se(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function le(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function ue(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-le(o,t,"left","right"),a=e.outerHeight-le(o,t,"top","bottom"),i!==t.w||a!==t.h)return t.w=i,t.h=a,n.horizontal?i!==t.w:a!==t.h}function de(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function he(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&fe.default||fe,me="$chartjs",ve="chartjs-size-monitor",be="chartjs-render-monitor",xe="chartjs-render-animation",ye=["animationstart","webkitAnimationStart"],_e={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function ke(t,e){var n=V.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var we=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Me(t,e,n){t.addEventListener(e,n,we)}function Se(t,e,n){t.removeEventListener(e,n,we)}function Ce(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Pe(t){var e=document.createElement("div");return e.className=t||"",e}function Ae(t,e,n){var i,a,r,o,s=t[me]||(t[me]={}),l=s.resizer=function(t){var e=Pe(ve),n=Pe(ve+"-expand"),i=Pe(ve+"-shrink");n.appendChild(Pe()),i.appendChild(Pe()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Me(n,"scroll",a.bind(n,"expand")),Me(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Ce("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function We(t){var e=z.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Re(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Re(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Re(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Re(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Re(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Re(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Re(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Re(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Re(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Ve(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function He(t){return Be([],Ee(t))}var je=X.extend({initialize:function(){this._model=We(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Be(o,Ee(i)),o=Be(o,Ee(a)),o=Be(o,Ee(r))},getBeforeBody:function(){return He(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return V.each(t,(function(t){var r={before:[],lines:[],after:[]};Be(r.before,Ee(i.beforeLabel.call(n,t,e))),Be(r.lines,i.label.call(n,t,e)),Be(r.after,Ee(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return He(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Be(r,Ee(n)),r=Be(r,Ee(i)),r=Be(r,Ee(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=We(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Ne[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=ze(e.rtl,e.x,e.width);for(t.x=Ve(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=V.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,V.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),V.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!V.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),qe=Ne,Ue=je;Ue.positioners=qe;var Ye=V.valueOrDefault;function Ge(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?V.merge(e[t][a],[Oe.getScaleDefaults(r),o]):V.merge(e[t][a],o)}else V._merger(t,e,n,i)}})}function Xe(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||{},r=n[t];"scales"===t?e[t]=Ge(a,r):"scale"===t?e[t]=V.merge(a,[Oe.getScaleDefaults(r.type),r]):V._merger(t,e,n,i)}})}function Ke(t){var e=t.options;V.each(t.scales,(function(e){ge.removeBox(t,e)})),e=Xe(z.global,z[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Ze(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(V.findIndex(t,a)>=0);return i}function $e(t){return"top"===t||"bottom"===t}function Je(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}z._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var Qe=function(t,e){return this.construct(t,e),this};V.extend(Qe.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Xe(z.global,z[t.type],t.options||{}),t}(e);var i=Fe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=V.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,Qe.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),V.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return V.canvas.clear(this),this},stop:function(){return $.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(V.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:V.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",V.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;V.each(e.xAxes,(function(t,n){t.id||(t.id=Ze(e.xAxes,"x-axis-",n))})),V.each(e.yAxes,(function(t,n){t.id||(t.id=Ze(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),V.each(i,(function(e){var i=e.options,r=i.id,o=Ye(i.type,e.dtype);$e(i.position)!==$e(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Oe.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),V.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Oe.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return ae.modes.single(this,t)},getElementsAtEvent:function(t){return ae.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return ae.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=ae.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return ae.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=V.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=V.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(V.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},on=V.isArray,sn=V.isNullOrUndef,ln=V.valueOrDefault,un=V.valueAtIndexOrDefault;function dn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function hn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[];for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-cn(l.gridLines)-u.padding-fn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=V.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){V.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){V.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=cn(o)+fn(r)),u?s&&(e.height=cn(o)+fn(r)):e.height=t.maxHeight,a.display&&s){var d=pn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=V.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){V.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(sn(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,vn(t,i,V.isNullOrUndef(a)?0:d-a,d),vn(t,i,h,V.isNullOrUndef(a)?t.length:h+a),mn(t)}return vn(t,i),mn(t)},_tickSize:function(){var t=this.options.ticks,e=V.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;xn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return yn(e)||yn(n)||(t=o.chart.data.datasets[n].data[e]),yn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=V.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),kn={position:"bottom"};_n._defaults=kn;var wn=V.noop,Mn=V.isNullOrUndef;var Sn=xn.extend({getRightValue:function(t){return"string"==typeof t?+t:xn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=V.sign(t.min),i=V.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:wn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:V.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=V.niceNum((g-f)/u/l)*l;if(p<1e-14&&Mn(d)&&Mn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=V.niceNum(r*p/u/l)*l),s||Mn(c)?n=Math.pow(10,V._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Mn(d)&&V.almostWhole(d/p,p/1e3)&&(i=d),!Mn(h)&&V.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=V.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Mn(d)?i:d);for(var m=1;me.length-1?null:this.getPixelForValue(e[t])}}),Tn=Cn;Dn._defaults=Tn;var In=V.valueOrDefault,Fn=V.math.log10;var Ln={position:"left",ticks:{callback:rn.formatters.logarithmic}};function On(t,e){return V.isFinite(t)&&t>=0?t:e}var Rn=xn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=V.min(t),n=V.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Fn(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:On(e.min),max:On(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=In(t.min,Math.pow(10,Math.floor(Fn(e.min)))),o=Math.floor(Fn(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Fn(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Fn(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(Fn(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;xn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=In(t.options.ticks.fontSize,z.global.defaultFontSize)/t._length),t._startValue=Fn(e),t._valueOffset=n,t._valueRange=(Fn(t.max)-Fn(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Fn(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),zn=Ln;Rn._defaults=zn;var Nn=V.valueOrDefault,Bn=V.valueAtIndexOrDefault,En=V.options.resolve,Wn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:rn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Vn(t){var e=t.ticks;return e.display&&t.display?Nn(e.fontSize,z.global.defaultFontSize)+2*e.backdropPaddingY:0}function Hn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function jn(t){return 0===t||180===t?"center":t<180?"left":"right"}function qn(t,e,n,i){var a,r,o=n.y+i/2;if(V.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Yn(t){return V.isNumber(t)?t:0}var Gn=Sn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Vn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;V.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);V.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Vn(this.options))},convertTicksToLabels:function(){var t=this;Sn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=V.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=V.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Yn(a),r=Yn(r),o=Yn(o),s=Yn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(V.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Nn(s.lineWidth,o.lineWidth),u=Nn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Vn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=V.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=Bn(i.fontColor,s,z.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=V.toDegrees(h);e.textAlign=jn(c),Un(c,t._pointLabelSizes[s],u),qn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&V.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=Bn(e.color,i-1),u=Bn(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=V.options._parseFont(n),s=Nn(n.fontColor,z.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",V.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:V.noop}),Xn=Wn;Gn._defaults=Xn;var Kn=V._deprecated,Zn=V.options.resolve,$n=V.valueOrDefault,Jn=Number.MIN_SAFE_INTEGER||-9007199254740991,Qn=Number.MAX_SAFE_INTEGER||9007199254740991,ti={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ei=Object.keys(ti);function ni(t,e){return t-e}function ii(t){return V.valueOrDefault(t.time.min,t.ticks.min)}function ai(t){return V.valueOrDefault(t.time.max,t.ticks.max)}function ri(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function oi(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),V.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),V.isFinite(o)||(o=n.parse(o))),o)}function si(t,e){if(V.isNullOrUndef(e))return null;var n=t.options.time,i=oi(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function li(t,e,n,i){var a,r,o,s=ei.length;for(a=ei.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var di=xn.extend({initialize:function(){this.mergeTicksOptions(),xn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new an._date(e.adapters.date);return Kn("time scale",n.format,"time.format","time.parser"),Kn("time scale",n.min,"time.min","ticks.min"),Kn("time scale",n.max,"time.max","ticks.max"),V.mergeIf(n.displayFormats,i.formats()),xn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),xn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=Qn,f=Jn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?li(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ei.length-1;r>=ei.indexOf(n);r--)if(o=ei[r],ti[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ei[n?ei.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ei.indexOf(t)+1,n=ei.length;ee&&s=0&&t0?s:1}}),hi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};di._defaults=hi;var ci={category:_n,linear:Dn,logarithmic:Rn,radialLinear:Gn,time:di},fi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};an._date.override("function"==typeof t?{_id:"moment",formats:function(){return fi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),z._set("global",{plugins:{filler:{propagate:!0}}});var gi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function mi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)V.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function _i(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||z.global.defaultColor,o&&s&&r.length&&(V.canvas.clipArea(u,t.chartArea),_i(u,r,o,a,s,i._loop),V.canvas.unclipArea(u)))}},wi=V.rtl.getRtlAdapter,Mi=V.noop,Si=V.valueOrDefault;function Ci(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}z._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;V.each(t.legendItems,(function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Mi,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=z.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=wi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Si(n.fontColor,i.defaultFontColor),g=V.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Ci(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},V.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;V.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Si(i.lineWidth,r.borderWidth);if(c.fillStyle=Si(i.fillStyle,a),c.lineCap=Si(i.lineCap,r.borderCapStyle),c.lineDashOffset=Si(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Si(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Si(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Si(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;V.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),V.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Ai(t,e){var n=new Pi({ctx:t.ctx,options:e,chart:t});ge.configure(t,n,e),ge.addBox(t,n),t.legend=n}var Di={id:"legend",_element:Pi,beforeInit:function(t){var e=t.options.legend;e&&Ai(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(V.mergeIf(e,z.global.legend),n?(ge.configure(t,n,e),n.options=e):Ai(t,e)):n&&(ge.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ti=V.noop;z._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Ii=X.extend({initialize:function(t){V.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ti,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ti,beforeSetDimensions:Ti,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ti,beforeBuildLabels:Ti,buildLabels:Ti,afterBuildLabels:Ti,beforeFit:Ti,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(V.isArray(n.text)?n.text.length:1)*V.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ti,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=V.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=V.valueOrDefault(n.fontColor,z.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(V.isArray(g))for(var p=0,m=0;m=0;i--){var a=t[i];if(e(a))return a}},V.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},V.almostEquals=function(t,e,n){return Math.abs(t-e)=t},V.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},V.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},V.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},V.toRadians=function(t){return t*(Math.PI/180)},V.toDegrees=function(t){return t*(180/Math.PI)},V._decimalPlaces=function(t){if(V.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},V.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},V.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},V.aliasPixel=function(t){return t%2==0?0:.5},V._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},V.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},V.EPSILON=Number.EPSILON||1e-14,V.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},V.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},V.niceNum=function(t,e){var n=Math.floor(V.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},V.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},V.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(V.getStyle(r,"padding-left")),u=parseFloat(V.getStyle(r,"padding-top")),d=parseFloat(V.getStyle(r,"padding-right")),h=parseFloat(V.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},V.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},V.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},V._calculatePadding=function(t,e,n){return(e=V.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},V._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},V.getMaximumWidth=function(t){var e=V._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-V._calculatePadding(e,"padding-left",n)-V._calculatePadding(e,"padding-right",n),a=V.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},V.getMaximumHeight=function(t){var e=V._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-V._calculatePadding(e,"padding-top",n)-V._calculatePadding(e,"padding-bottom",n),a=V.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},V.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},V.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},V.fontString=function(t,e,n){return e+" "+t+"px "+n},V.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},V.numberOfLabelLines=function(t){var e=1;return V.each(t,(function(t){V.isArray(t)&&t.length>e&&(e=t.length)})),e},V.color=k?function(t){return t instanceof CanvasGradient&&(t=z.global.defaultColor),k(t)}:function(t){return console.error("Color.js not found!"),t},V.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:V.color(t).saturate(.5).darken(.1).rgbString()}}(),tn._adapters=an,tn.Animation=Z,tn.animationService=$,tn.controllers=$t,tn.DatasetController=nt,tn.defaults=z,tn.Element=X,tn.elements=_t,tn.Interaction=ae,tn.layouts=ge,tn.platform=Fe,tn.plugins=Le,tn.Scale=xn,tn.scaleService=Oe,tn.Ticks=rn,tn.Tooltip=Ue,tn.helpers.each(ci,(function(t,e){tn.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Ni)&&tn.plugins.register(Li[Ni]);tn.platform.initialize();var Bi=tn;return"undefined"!=typeof window&&(window.Chart=tn),tn.Chart=tn,tn.Legend=Li.legend._element,tn.Title=Li.title._element,tn.pluginService=tn.plugins,tn.PluginBase=tn.Element.extend({}),tn.canvasHelpers=tn.helpers.canvas,tn.layoutService=tn.layouts,tn.LinearScaleBase=Sn,tn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){tn[t]=function(e,n){return new tn(e,tn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Bi})); From 4e6e954bfe34c61251c0e915cad010dee474948e Mon Sep 17 00:00:00 2001 From: Michael Tobisch Date: Sat, 7 Nov 2020 18:39:27 +0100 Subject: [PATCH 5/9] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c09b0ba..a1098af 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The DNN Survey module allows you to create surveys and quizes on your DNN (forme * Result charts (created with ChartJS) * Quiz questions can be statistical, that means they have no correct answer. This is useful for questions about the gender, age group etc. in a quiz and allows analysis by these items. * To be able to identify which answers come from the same user (even in a survey that allows anonymous participation) there is a random GUID in the survey results which is created when the survey is submitted. +* Survey results can be downloaded as a CSV file to be processed with any reporting tool of your choice. To give maximum flexibility, the separator and delimiter can be set in the module settings. ## System requirements * [DNN Platform version 08.00.00 or higher](https://github.com/dnnsoftware/Dnn.Platform/releases/tag/v8.0.0) ## More information From 44a58830b006f80f947e0cdbd8efc4c81a547f6e Mon Sep 17 00:00:00 2001 From: Daniel Valadas Date: Sat, 7 Nov 2020 13:38:30 -0500 Subject: [PATCH 6/9] Fixed an issue where the csv export was missing a textQualifier at the end. When exporting to csv the last item was missing a text qualifier (such as single quote or double quote) This PR fixes it. --- DNN.Survey/Components/Controllers/SurveyBusinessController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs index cd71ff4..39e0948 100644 --- a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs +++ b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs @@ -366,12 +366,12 @@ public void ImportModule(int moduleID, string content, string version, int userI public string CSVExport(int moduleID, string resourceFile, Separator separator, TextQualifier textQualifier) { StringBuilder csvBuilder = new StringBuilder(); - csvBuilder.Append(string.Format("{0}SurveyID{0}{1}{0}Question{0}{1}{0}Question Type{0}{1}{0}Statistical{0}{1}{0}Answer{0}{1}{0}Votes{0}{1}{0}Correct Answer{0}{1}{0}UserID{0}{1}{0}IP Address{0}{1}{0}GUID{0}{1}{0}Date\r\n", GetTextQualifierCharacter(textQualifier), GetSeparatorCharacter(separator))); + csvBuilder.Append(string.Format("{0}SurveyID{0}{1}{0}Question{0}{1}{0}Question Type{0}{1}{0}Statistical{0}{1}{0}Answer{0}{1}{0}Votes{0}{1}{0}Correct Answer{0}{1}{0}UserID{0}{1}{0}IP Address{0}{1}{0}GUID{0}{1}{0}Date{0}\r\n", GetTextQualifierCharacter(textQualifier), GetSeparatorCharacter(separator))); List surveys = SurveysExportController.GetAll(moduleID); foreach (SurveysExportInfo survey in surveys) { - csvBuilder.Append(string.Format("{0}{2}{0}{1}{0}{3}{0}{1}{0}{4}{0}{1}{0}{5}{0}{1}{0}{6}{0}{1}{0}{7}{0}{1}{0}{8}{0}{1}{0}{9}{0}{1}{0}{10}{0}{1}{0}{11}{0}{1}{0}{12:yyyy-MM-dd hh:mm:ss}\r\n", + csvBuilder.Append(string.Format("{0}{2}{0}{1}{0}{3}{0}{1}{0}{4}{0}{1}{0}{5}{0}{1}{0}{6}{0}{1}{0}{7}{0}{1}{0}{8}{0}{1}{0}{9}{0}{1}{0}{10}{0}{1}{0}{11}{0}{1}{0}{12:yyyy-MM-dd hh:mm:ss}{0}\r\n", GetTextQualifierCharacter(textQualifier), GetSeparatorCharacter(separator), survey.SurveyID, From 69bb9b0730f58ae78701ab533f15bcb6e5882471 Mon Sep 17 00:00:00 2001 From: Daniel Valadas Date: Sat, 7 Nov 2020 14:02:07 -0500 Subject: [PATCH 7/9] Fixed an issue with csv conflict on qualifier character When an answer included the string qualifier character, csv export was not properly escaping them. This PR fixed that. --- .../Controllers/SurveyBusinessController.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs index 39e0948..a0da26d 100644 --- a/DNN.Survey/Components/Controllers/SurveyBusinessController.cs +++ b/DNN.Survey/Components/Controllers/SurveyBusinessController.cs @@ -378,7 +378,7 @@ public string CSVExport(int moduleID, string resourceFile, Separator separator, survey.Question, Localization.GetString(string.Format("QuestionType.{0}.Text", Enum.GetName(typeof(QuestionType), survey.OptionType), resourceFile)), survey.IsStatistical, - (survey.OptionType == QuestionType.Text ? survey.TextAnswer : survey.OptionName), + (survey.OptionType == QuestionType.Text ? EscapeTextQualifier(survey.TextAnswer, textQualifier) : survey.OptionName), survey.Votes, survey.IsCorrect, survey.UserID, @@ -388,7 +388,20 @@ public string CSVExport(int moduleID, string resourceFile, Separator separator, } return csvBuilder.ToString(); } - private char GetSeparatorCharacter(Separator separator) + + private string EscapeTextQualifier(string textAnswer, TextQualifier textQualifier) + { + var escapedAnswer = textAnswer; + string qualifier = GetTextQualifierCharacter(textQualifier).ToString(); + if (textAnswer.Contains(qualifier)) + { + escapedAnswer = textAnswer.Replace(qualifier, string.Format("{0}{0}", qualifier)); + } + + return escapedAnswer; + } + + private char GetSeparatorCharacter(Separator separator) { char separatorCharacter; switch (separator) From 796f2e1e5390e5806f71fe2dd4c50e7f8d15f4a9 Mon Sep 17 00:00:00 2001 From: Daniel Valadas Date: Sat, 7 Nov 2020 14:15:48 -0500 Subject: [PATCH 8/9] Bumped Dnn dependency to 9.4.0 Bumped Dnn dependency to 9.4.0 Tested up to 9.8.0 --- DNN.Survey/DNN.Survey.csproj | 33 ++++++++++++++++++++++----------- DNN.Survey/DNN_Survey.dnn | 2 +- DNN.Survey/packages.config | 6 +++--- DNN.Survey/web.Debug.config | 30 ++++++++++++++++++++++++++++++ DNN.Survey/web.Release.config | 31 +++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 DNN.Survey/web.Debug.config create mode 100644 DNN.Survey/web.Release.config diff --git a/DNN.Survey/DNN.Survey.csproj b/DNN.Survey/DNN.Survey.csproj index a1cda39..2d8ceda 100644 --- a/DNN.Survey/DNN.Survey.csproj +++ b/DNN.Survey/DNN.Survey.csproj @@ -14,7 +14,7 @@ Properties DNN.Modules.Survey DNN.Modules.Survey - v4.6.1 + v4.7.2 true @@ -24,6 +24,7 @@ +
    true @@ -197,36 +198,39 @@ - - ..\packages\DotNetNuke.Core.8.0.0.809\lib\net40\DotNetNuke.dll + + ..\packages\DotNetNuke.Core.9.4.0\lib\net45\DotNetNuke.dll False False - - ..\packages\DotNetNuke.Web.8.0.0.809\lib\net40\DotNetNuke.Web.dll + + ..\packages\DotNetNuke.Web.9.4.0\lib\net45\DotNetNuke.Web.dll False False - - ..\packages\DotNetNuke.Web.Client.8.0.1.239\lib\net40\DotNetNuke.Web.Client.dll + + ..\packages\DotNetNuke.Web.Client.9.4.0\lib\net45\DotNetNuke.Web.Client.dll False False - ..\packages\DotNetNuke.Web.8.0.0.809\lib\net40\DotNetNuke.WebUtility.dll + ..\packages\DotNetNuke.Web.9.4.0\lib\net45\DotNetNuke.WebUtility.dll False False - ..\packages\DotNetNuke.Core.8.0.0.809\lib\net40\Microsoft.ApplicationBlocks.Data.dll - False - False + ..\packages\DotNetNuke.Core.9.4.0\lib\net45\Microsoft.ApplicationBlocks.Data.dll + + + + + @@ -236,6 +240,13 @@ + + + web.config + + + web.config + 10.0 diff --git a/DNN.Survey/DNN_Survey.dnn b/DNN.Survey/DNN_Survey.dnn index 1a7760e..c3ad635 100644 --- a/DNN.Survey/DNN_Survey.dnn +++ b/DNN.Survey/DNN_Survey.dnn @@ -17,7 +17,7 @@ - 09.04.04 + 09.04.00 diff --git a/DNN.Survey/packages.config b/DNN.Survey/packages.config index 8e54bde..c539dee 100644 --- a/DNN.Survey/packages.config +++ b/DNN.Survey/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/DNN.Survey/web.Debug.config b/DNN.Survey/web.Debug.config new file mode 100644 index 0000000..fae9cfe --- /dev/null +++ b/DNN.Survey/web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/DNN.Survey/web.Release.config b/DNN.Survey/web.Release.config new file mode 100644 index 0000000..da6e960 --- /dev/null +++ b/DNN.Survey/web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file From e4354e282e4f67379aa436438b6d5f636b3a9301 Mon Sep 17 00:00:00 2001 From: Daniel Valadas Date: Sat, 7 Nov 2020 14:30:21 -0500 Subject: [PATCH 9/9] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a1098af..e4b2772 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ The DNN Survey module allows you to create surveys and quizes on your DNN (forme * To be able to identify which answers come from the same user (even in a survey that allows anonymous participation) there is a random GUID in the survey results which is created when the survey is submitted. * Survey results can be downloaded as a CSV file to be processed with any reporting tool of your choice. To give maximum flexibility, the separator and delimiter can be set in the module settings. ## System requirements -* [DNN Platform version 08.00.00 or higher](https://github.com/dnnsoftware/Dnn.Platform/releases/tag/v8.0.0) +* .Net Framework 4.7.2 or higher +* [DNN Platform version 09.04.00 or higher](https://github.com/dnnsoftware/Dnn.Platform/releases/tag/v9.4.0) ## More information This project is documented on [dnn-survey.readme.io](https://dnn-survey.readme.io)