NinjaFirewall (WP Edition) - Version 4.5

Version Description

  • Added the possibility to enter custom HTTP response headers. See "Firewall Policies > Advanced Policies > HTTP response headers > Custom HTTP headers".
  • Added the possibility to view the server's HTTP response headers. Click on the "Firewall Policies > Advanced Policies > HTTP response headers > HTTP headers test" button.
  • Added a warning if WordPress is running inside a Docker image and the user wants to upgrade NinjaFirewall to Full WAF mode.
  • Fixed a PHP "Undefined array key pluginzip" warning when reinstalling a plugin from a ZIP archive.
  • WP+ Edition (Premium): The Access Control URI whitelist and blacklist now support permalinks.
  • Fixed an issue where the daily report could be sent multiple times on some multisite installations.
  • Fixed deprecated readonly() function message on WordPress 5.9.
  • Fixed an issue where the firewall would wrongly send a WordPress update notification.
  • WP+ Edition (Premium): Updated Stripes webhook notifications IP addresses in the Access Control section.
  • Updated Charts.js library.
  • WP+ Edition (Premium): Updated GeoIP databases.
  • Many small fixes and adjustments.
Download this release

Release Info

Developer nintechnet
Plugin Icon 128x128 NinjaFirewall (WP Edition)
Version 4.5
Comparing to
See all releases

Code changes from version 4.4.3 to 4.5

images/{scan_progress.gif → progress.gif} RENAMED
File without changes
languages/ninjafirewall-fr_FR.mo CHANGED
Binary file
languages/ninjafirewall-fr_FR.po CHANGED
@@ -4,8 +4,8 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Stable (latest release)\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ninjafirewall\n"
7
- "POT-Creation-Date: 2021-09-17 15:59+0700\n"
8
- "PO-Revision-Date: 2021-09-17 15:59+0700\n"
9
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
10
  "Language-Team: NinTechNet <nintechnet.com>\n"
11
  "Language: fr_FR\n"
@@ -16,7 +16,7 @@ msgstr ""
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
18
 
19
- #: lib/anti_malware.php:24 ninjafirewall.php:914
20
  msgid "Anti-Malware"
21
  msgstr "Anti-Malware"
22
 
@@ -113,7 +113,7 @@ msgstr "NinjaFirewall (WP Edition)"
113
  msgid "Your changes have been saved."
114
  msgstr "Les modifications ont été enregistrées."
115
 
116
- #: lib/dashboard.php:132 ninjafirewall.php:892
117
  msgid "Dashboard"
118
  msgstr "Tableau de Bord"
119
 
@@ -463,12 +463,6 @@ msgstr ""
463
  msgid "Help &amp; configuration"
464
  msgstr "Aide &amp; configuration"
465
 
466
- #: lib/dashboard.php:515
467
- msgid "Cannot check if the PHP INI file is readable: connection error"
468
- msgstr ""
469
- "Impossible de vérifier si le fichier PHP INI est protégé : erreur de "
470
- "connexion"
471
-
472
  #: lib/dashboard_about.php:29
473
  msgid "Our blog:"
474
  msgstr "Notre blog :"
@@ -489,10 +483,6 @@ msgstr "Conformité RGPD"
489
  msgid "Rate it on WordPress.org!"
490
  msgstr "Notez-le sur WordPress.org !"
491
 
492
- #: lib/dashboard_about.php:33
493
- msgid "NinjaFirewall Referral Program"
494
- msgstr "Programme de parrainage de NinjaFirewall"
495
-
496
  #: lib/dashboard_statistics.php:76
497
  msgid "You do not have any stats for the selected month yet."
498
  msgstr "Vous n'avez pas de statistiques pour le mois sélectionné."
@@ -583,8 +573,8 @@ msgstr ""
583
  #: lib/email_sodium.php:169 lib/monitoring_file_check.php:759
584
  #: lib/monitoring_file_check.php:761 lib/monitoring_file_check.php:781
585
  #: lib/monitoring_file_check.php:783 lib/security_rules_update.php:559
586
- #: lib/security_rules_update.php:561 lib/utils.php:225 lib/utils.php:306
587
- #: lib/utils.php:425 lib/utils.php:1038 lib/utils.php:1212 lib/utils.php:1484
588
  msgid "Blog:"
589
  msgstr "Blog :"
590
 
@@ -592,14 +582,14 @@ msgstr "Blog :"
592
  msgid "Email address:"
593
  msgstr "Adresse e-mail :"
594
 
595
- #: lib/email_sodium.php:171 lib/utils.php:230 lib/utils.php:310
596
- #: lib/utils.php:427 lib/utils.php:1220 lib/utils.php:1485
597
  msgid "User IP:"
598
  msgstr "IP utilisateur :"
599
 
600
  #: lib/email_sodium.php:172 lib/event_updates.php:157 lib/utils.php:233
601
- #: lib/utils.php:313 lib/utils.php:430 lib/utils.php:1039 lib/utils.php:1223
602
- #: lib/utils.php:1488
603
  msgid "Date:"
604
  msgstr "Date :"
605
 
@@ -633,7 +623,7 @@ msgstr "Oui"
633
  msgid "No"
634
  msgstr "Non"
635
 
636
- #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:922
637
  msgid "Event Notifications"
638
  msgstr "Notifications d'Événement"
639
 
@@ -825,40 +815,40 @@ msgstr "Autre(s) :"
825
  msgid "Save Event Notifications"
826
  msgstr "Sauvegarder les options"
827
 
828
- #: lib/event_notifications.php:476
829
  msgid "[NinjaFirewall] Daily Activity Report"
830
  msgstr "[NinjaFirewall] Rapport d'activité quotidien"
831
 
832
- #: lib/event_notifications.php:486
833
  #, php-format
834
  msgid "Daily activity report for: %s"
835
  msgstr "Rapport d'activité quotidien pour : %s"
836
 
837
- #: lib/event_notifications.php:487
838
  msgid "Date Range Processed: Yesterday"
839
  msgstr "Plage de date traitée : Hier"
840
 
841
- #: lib/event_notifications.php:489
842
  msgid "Blocked threats:"
843
  msgstr "Menaces bloquées :"
844
 
845
- #: lib/event_notifications.php:491
846
  msgid "critical:"
847
  msgstr "Critique :"
848
 
849
- #: lib/event_notifications.php:492
850
  msgid "high:"
851
  msgstr "Élevé :"
852
 
853
- #: lib/event_notifications.php:493
854
  msgid "medium:"
855
  msgstr "Moyen :"
856
 
857
- #: lib/event_notifications.php:495
858
  msgid "Blocked brute-force attacks:"
859
  msgstr "Attaques par force brute bloquées :"
860
 
861
- #: lib/event_notifications.php:496 lib/event_updates.php:219 lib/utils.php:1050
862
  msgid ""
863
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
864
  "\" page."
@@ -924,7 +914,7 @@ msgstr "Extension : %s"
924
  msgid "Theme: %s"
925
  msgstr "Theme : %s"
926
 
927
- #: lib/event_updates.php:217 lib/utils.php:1566
928
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
929
  msgstr ""
930
  "Ne laissez pas votre blog en danger, lancez cette mise à jour dès que "
@@ -960,12 +950,12 @@ msgstr "Version :"
960
  msgid "activated"
961
  msgstr "activé(e)"
962
 
963
- #: lib/events.php:45 lib/events.php:93 lib/events.php:173 lib/events.php:185
964
  msgid "deleted"
965
  msgstr "supprimé(e)"
966
 
967
  #: lib/events.php:81 lib/events.php:103 lib/events.php:118 lib/events.php:122
968
- #: lib/events.php:138 lib/events.php:147 lib/events.php:169 lib/events.php:181
969
  msgid "updated"
970
  msgstr "mis(e) à jour"
971
 
@@ -973,40 +963,40 @@ msgstr "mis(e) à jour"
973
  msgid "deactivated"
974
  msgstr "désactivé(e)"
975
 
976
- #: lib/events.php:130 lib/events.php:151 lib/events.php:165 lib/events.php:177
977
  msgid "installed"
978
  msgstr "installé(e)"
979
 
980
- #: lib/events.php:134 lib/events.php:155
981
  msgid "uploaded"
982
  msgstr "téléchargé(e)"
983
 
984
- #: lib/events.php:195
985
  #, php-format
986
  msgid "[NinjaFirewall] Alert: %s"
987
  msgstr "[NinjaFirewall] Alerte : %s"
988
 
989
- #: lib/events.php:197 lib/events.php:199 lib/utils.php:787
990
  msgid "-Blog:"
991
  msgstr "- Blog :"
992
 
993
- #: lib/events.php:202
994
  msgid "NinjaFirewall has detected the following activity on your account:"
995
  msgstr "NinjaFirewall a détecté l'activité suivante sur votre compte :"
996
 
997
- #: lib/events.php:204 lib/utils.php:792
998
  msgid "-User:"
999
  msgstr "- Nom :"
1000
 
1001
- #: lib/events.php:205 lib/utils.php:793
1002
  msgid "-IP:"
1003
  msgstr "- IP :"
1004
 
1005
- #: lib/events.php:206 lib/utils.php:794
1006
  msgid "-Date:"
1007
  msgstr "-Date :"
1008
 
1009
- #: lib/firewall_options.php:29 ninjafirewall.php:896
1010
  msgid "Firewall Options"
1011
  msgstr "Options du Pare-feu"
1012
 
@@ -1221,7 +1211,7 @@ msgstr ""
1221
  "Pour utiliser cette option, allez dans le <a href=\"%s\">Tableau de Bord</a> "
1222
  "et activez le mode Full WAF de NinjaFirewall."
1223
 
1224
- #: lib/firewall_policies.php:62 ninjafirewall.php:900
1225
  msgid "Firewall Policies"
1226
  msgstr "Politiques du Pare-feu"
1227
 
@@ -1381,7 +1371,7 @@ msgstr ""
1381
  "Bloquer les tentatives de publication, modification ou suppression d'un "
1382
  "article publié par des utilisateurs qui n'ont pas les bonnes capacités"
1383
 
1384
- #: lib/firewall_policies.php:411 lib/thickbox.php:89
1385
  msgid "(recommended)"
1386
  msgstr "(recommandé)"
1387
 
@@ -1786,7 +1776,31 @@ msgstr ""
1786
  msgid "Set %s (Chrome, Opera and Firefox browsers)"
1787
  msgstr "Activer %s (Chrome, Opera et Firefox)"
1788
 
1789
- #: lib/firewall_policies.php:1018
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1790
  msgid ""
1791
  "Block PHP built-in wrappers in <code>GET</code>, <code>POST</code>, "
1792
  "<code>HTTP_USER_AGENT</code>, <code>HTTP_REFERER</code> and cookies"
@@ -1795,58 +1809,58 @@ msgstr ""
1795
  "<code>GET</code>, <code>POST</code>, <code>HTTP_USER_AGENT</code>, "
1796
  "<code>HTTP_REFERER</code> et les cookies"
1797
 
1798
- #: lib/firewall_policies.php:1057
1799
  msgid "Block serialized PHP objects in the following global variables"
1800
  msgstr ""
1801
  "Bloquer les objets PHP sérialisés dans les variables globales suivantes"
1802
 
1803
- #: lib/firewall_policies.php:1067 lib/help.php:295
1804
  msgid "Block attempts to override PHP Superglobals"
1805
  msgstr "Bloquer les tentatives de modification des Superglobales PHP"
1806
 
1807
- #: lib/firewall_policies.php:1073 lib/help.php:297
1808
  msgid "Hide PHP notice and error messages"
1809
  msgstr "Masquer les messages d'erreur de PHP"
1810
 
1811
- #: lib/firewall_policies.php:1079
1812
  msgid "Sanitise <code>PHP_SELF</code>"
1813
  msgstr "Nettoyer <code>PHP_SELF</code>"
1814
 
1815
- #: lib/firewall_policies.php:1085
1816
  msgid "Sanitise <code>PATH_TRANSLATED</code>"
1817
  msgstr "Nettoyer <code>PATH_TRANSLATED</code>"
1818
 
1819
- #: lib/firewall_policies.php:1091
1820
  msgid "Sanitise <code>PATH_INFO</code>"
1821
  msgstr "Nettoyer <code>PATH_INFO</code>"
1822
 
1823
- #: lib/firewall_policies.php:1105
1824
  msgid "This option is not compatible with your actual configuration."
1825
  msgstr ""
1826
  "Cette option n'est pas compatible avec la configuration de votre serveur."
1827
 
1828
- #: lib/firewall_policies.php:1127 lib/help.php:301
1829
  msgid "Various"
1830
  msgstr "Divers"
1831
 
1832
- #: lib/firewall_policies.php:1130
1833
  msgid "Block the <code>DOCUMENT_ROOT</code> server variable in HTTP request"
1834
  msgstr ""
1835
  "Bloquer les requêtes HTTP contenant la variable <code>DOCUMENT_ROOT</code>"
1836
 
1837
- #: lib/firewall_policies.php:1137 lib/help.php:304
1838
  msgid "Block ASCII character 0x00 (NULL byte)"
1839
  msgstr "Bloquer le caractère ASCII 0x00 (NULL byte)"
1840
 
1841
- #: lib/firewall_policies.php:1143 lib/help.php:306
1842
  msgid "Block ASCII control characters 1 to 8 and 14 to 31"
1843
  msgstr "Bloquer les caractères de contrôle ASCII 1 à 8 et 14 à 31"
1844
 
1845
- #: lib/firewall_policies.php:1156
1846
  msgid "Save Firewall Policies"
1847
  msgstr "Sauvegarder les options"
1848
 
1849
- #: lib/firewall_policies.php:1158
1850
  msgid "Restore Default Values"
1851
  msgstr "Rétablir les valeurs par défaut"
1852
 
@@ -2985,7 +2999,7 @@ msgstr ""
2985
  "intercepter les requêtes HTTP envoyées à tout script PHP, même si ce dernier "
2986
  "ne fait pas partie de WordPress (logiciel tiers, backdoor, etc)."
2987
 
2988
- #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:918
2989
  msgid "Network"
2990
  msgstr "Réseau"
2991
 
@@ -3038,7 +3052,7 @@ msgstr ""
3038
  "après avoir pénétré dans votre Tableau de bord de WordPress, d'y installer "
3039
  "une porte dérobée (backdoor) afin de prendre le contrôle de votre blog."
3040
 
3041
- #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:926
3042
  msgid "Login Protection"
3043
  msgstr "Page de Connexion"
3044
 
@@ -3642,40 +3656,36 @@ msgid "NinjaFirewall: Antispam"
3642
  msgstr "NinjaFirewall : Anti-Spam"
3643
 
3644
  #: lib/i18n-extra.php:21
3645
- msgid "Referral Program"
3646
- msgstr "Programme de parrainage"
3647
-
3648
- #: lib/i18n-extra.php:22
3649
  msgid "License"
3650
  msgstr "Licence"
3651
 
3652
- #: lib/i18n-extra.php:23
3653
  msgid "Enter your NinjaFirewall WP+ license and click on the save button"
3654
  msgstr ""
3655
  "Entrez votre licence NinjaFirewall WP+ et cliquez sur le bouton pour la "
3656
  "valider"
3657
 
3658
- #: lib/i18n-extra.php:24
3659
  msgid "Don't have a license yet?"
3660
  msgstr "Vous n'avez pas encore de licence ?"
3661
 
3662
- #: lib/i18n-extra.php:25
3663
  msgid "Click here to get one"
3664
  msgstr "Cliquez ici pour en obtenir une"
3665
 
3666
- #: lib/i18n-extra.php:26
3667
  msgid "Save License"
3668
  msgstr "Sauvegarder la Licence"
3669
 
3670
- #: lib/i18n-extra.php:27
3671
  msgid "This license has expired and is no longer valid."
3672
  msgstr "Cette licence a expiré et n'est plus valide."
3673
 
3674
- #: lib/i18n-extra.php:28
3675
  msgid "Your license is not valid"
3676
  msgstr "Votre licence n'est pas valide"
3677
 
3678
- #: lib/i18n-extra.php:29
3679
  msgid ""
3680
  "An unknown error occurred while connecting to NinjaFirewall servers. Please "
3681
  "try again in a few minutes"
@@ -3683,7 +3693,7 @@ msgstr ""
3683
  "Une erreur inconnue est survenue lors de la connexion aux serveurs de "
3684
  "NinjaFirewall. Veuillez essayer à nouveau dans quelques minutes"
3685
 
3686
- #: lib/i18n-extra.php:30
3687
  msgid ""
3688
  "An error occurred while connecting to NinjaFirewall servers. Please try "
3689
  "again in a few minutes"
@@ -3691,23 +3701,23 @@ msgstr ""
3691
  "Une erreur est survenue lors de la connexion aux serveurs de NinjaFirewall. "
3692
  "Veuillez essayer à nouveau dans quelques minutes"
3693
 
3694
- #: lib/i18n-extra.php:31
3695
  msgid "Your NinaFirewall license has expired!"
3696
  msgstr "Votre licence NinjaFirewall a expiré !"
3697
 
3698
- #: lib/i18n-extra.php:32
3699
  msgid "Click here to renew it"
3700
  msgstr "Cliquez ici pour la renouveler"
3701
 
3702
- #: lib/i18n-extra.php:33
3703
  msgid "Your NinaFirewall license will expire soon!"
3704
  msgstr "Votre licence NinjaFirewall va bientôt expirer !"
3705
 
3706
- #: lib/i18n-extra.php:34
3707
  msgid "You do not have a valid NinjaFirewall license"
3708
  msgstr "Vous n'avez pas de licence NinjaFirewall valide"
3709
 
3710
- #: lib/i18n-extra.php:35
3711
  #, php-format
3712
  msgid ""
3713
  "The shared memory block seems corrupted. Try to reload this page to fix it "
@@ -3718,12 +3728,12 @@ msgstr ""
3718
  "ou bien, si l'erreur persiste, essayez de <a href=\"%s\">désactiver "
3719
  "l'utilisation de la mémoire partagée</a>."
3720
 
3721
- #: lib/i18n-extra.php:36
3722
  #, php-format
3723
  msgid "(RAM usage: %s bytes)"
3724
  msgstr "(mémoire utilisée : %s octets)"
3725
 
3726
- #: lib/i18n-extra.php:37
3727
  #, php-format
3728
  msgid ""
3729
  "Unable to access/read the shared memory block. Try to reload this page or, "
@@ -3734,15 +3744,15 @@ msgstr ""
3734
  "page ou bien, si l'erreur persiste, essayez de <a href=\"%s\">désactiver "
3735
  "l'utilisation de la mémoire partagée</a>."
3736
 
3737
- #: lib/i18n-extra.php:38
3738
  msgid "Firewall is disabled"
3739
  msgstr "Le pare-feu est désactivé"
3740
 
3741
- #: lib/i18n-extra.php:39
3742
  msgid "Shared memory"
3743
  msgstr "Mémoire partagée"
3744
 
3745
- #: lib/i18n-extra.php:40
3746
  #, php-format
3747
  msgid ""
3748
  "You are not whitelisted. Ensure that the \"Do not block the following users"
@@ -3755,7 +3765,7 @@ msgstr ""
3755
  "a> est activée pour l'Administrateur/Super Admin, sinon vous pourriez être "
3756
  "bloqué par le pare-feu lorsque vous travaillez depuis votre Tableau de bord."
3757
 
3758
- #: lib/i18n-extra.php:41
3759
  #, php-format
3760
  msgid ""
3761
  "<a href=\"%s\">Access Control Source IP</a> is setup to use %s, however your "
@@ -3765,12 +3775,12 @@ msgstr ""
3765
  "votre serveur n'utilise pas cette variable. Toutes les directives basées sur "
3766
  "une adresse IP échoueront."
3767
 
3768
- #: lib/i18n-extra.php:42
3769
  #, php-format
3770
  msgid "You have a private IP: %s"
3771
  msgstr "Vous avez l'adresse IP d'un réseau privé : %s"
3772
 
3773
- #: lib/i18n-extra.php:43
3774
  #, php-format
3775
  msgid ""
3776
  "If your site is behind a reverse proxy or a load balancer, ensure that the "
@@ -3779,7 +3789,7 @@ msgstr ""
3779
  "Si votre site est derrière un CDN ou reverse proxy, pensez à configurer "
3780
  "correctement l'option <a href=\"%s\">IP Source</a>."
3781
 
3782
- #: lib/i18n-extra.php:44
3783
  #, php-format
3784
  msgid ""
3785
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that the "
@@ -3788,7 +3798,7 @@ msgstr ""
3788
  "%s détecté : il semble que vous utilisez le service CDN Cloudflare. Assurez "
3789
  "vous d'avoir correctement configuré l'<a href=\"%s\">IP Source</a>."
3790
 
3791
- #: lib/i18n-extra.php:45
3792
  #, php-format
3793
  msgid ""
3794
  "%s detected: you seem to be using Incapsula CDN services. Ensure that the <a "
@@ -3797,30 +3807,30 @@ msgstr ""
3797
  "%s détecté : il semble que vous utilisez le service CDN Incapsula. Assurez "
3798
  "vous d'avoir correctement configuré l'<a href=\"%s\">IP Source</a>."
3799
 
3800
- #: lib/i18n-extra.php:46
3801
  msgid "Logging"
3802
  msgstr "Journal du Pare-feu"
3803
 
3804
- #: lib/i18n-extra.php:47
3805
  msgid "Logging is disabled."
3806
  msgstr "Le journal est désactivé."
3807
 
3808
- #: lib/i18n-extra.php:48
3809
  msgid "Click here to re-enable it."
3810
  msgstr "Cliquez ici pour le réactiver."
3811
 
3812
- #: lib/i18n-extra.php:49
3813
  #, php-format
3814
  msgid "Error cannot create the language files directory (%s)"
3815
  msgstr ""
3816
  "Erreur, impossible de créer le répertoire pour le fichier de langue (%s)"
3817
 
3818
- #: lib/i18n-extra.php:50
3819
  #, php-format
3820
  msgid "Error while downloading language file %s (%s)"
3821
  msgstr "Erreur en essayant de télécharger le fichier de langue %s (%s)"
3822
 
3823
- #: lib/i18n-extra.php:51
3824
  #, php-format
3825
  msgid ""
3826
  "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
@@ -3836,178 +3846,178 @@ msgstr ""
3836
  "que cette option s'applique à tous les fichiers PHP, allez dans le %sTableau "
3837
  "de Bord%s et activez son mode Full WAF."
3838
 
3839
- #: lib/i18n-extra.php:52
3840
  msgid "General"
3841
  msgstr "Général"
3842
 
3843
- #: lib/i18n-extra.php:53
3844
  msgid "Geolocation"
3845
  msgstr "Géolocalisation"
3846
 
3847
- #: lib/i18n-extra.php:54
3848
  msgid "IP address"
3849
  msgstr "Adresse IP"
3850
 
3851
- #: lib/i18n-extra.php:55
3852
  msgid "URL address"
3853
  msgstr "Adresse URL"
3854
 
3855
- #: lib/i18n-extra.php:56
3856
  msgid "Bot"
3857
  msgstr "Bot"
3858
 
3859
- #: lib/i18n-extra.php:57
3860
  msgid "User Input"
3861
  msgstr "Entrée utilisateur"
3862
 
3863
- #: lib/i18n-extra.php:58
3864
  msgid "Role-based Access Control"
3865
  msgstr "Contrôle d'Accès par Rôle"
3866
 
3867
- #: lib/i18n-extra.php:59
3868
  msgid "Do not block the following users (must be logged in)"
3869
  msgstr "Ne pas bloquer les utilisateurs suivants"
3870
 
3871
- #: lib/i18n-extra.php:60
3872
  msgid "Retrieve visitors IP address from"
3873
  msgstr "Récupérer l'adresse IP des visiteurs depuis"
3874
 
3875
- #: lib/i18n-extra.php:61
3876
  msgid "Other"
3877
  msgstr "Autre"
3878
 
3879
- #: lib/i18n-extra.php:62
3880
  #, php-format
3881
  msgid "Your server does not seem to support the %s variable."
3882
  msgstr "Votre serveur ne semble pas utiliser la variable %s."
3883
 
3884
- #: lib/i18n-extra.php:63
3885
  msgid "HTTP Methods"
3886
  msgstr "Méthodes HTTP"
3887
 
3888
- #: lib/i18n-extra.php:64
3889
  msgid "All Access Control directives should apply to the folowing HTTP methods"
3890
  msgstr ""
3891
  "Toutes les directives Contrôle d'accès s'appliquent aux méthodes HTTP "
3892
  "suivantes"
3893
 
3894
- #: lib/i18n-extra.php:65
3895
  msgid "Enable Geolocation"
3896
  msgstr "Activer la Géolocalisation"
3897
 
3898
- #: lib/i18n-extra.php:66
3899
  msgid "Retrieve the ISO 3166 code from"
3900
  msgstr "Récupérer le code ISO 3166 du pays depuis"
3901
 
3902
- #: lib/i18n-extra.php:67
3903
  msgid "PHP Variable"
3904
  msgstr "Variable PHP"
3905
 
3906
- #: lib/i18n-extra.php:68
3907
  msgid "Block the following ISO 3166 codes"
3908
  msgstr "Bloquer les codes ISO 3166 suivants"
3909
 
3910
- #: lib/i18n-extra.php:69
3911
  #, php-format
3912
  msgid "Total blocked items: %s"
3913
  msgstr "Nombre d'éléments bloqués : %s"
3914
 
3915
- #: lib/i18n-extra.php:70
3916
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3917
  msgstr ""
3918
  "S'il faut appliquer la Géolocalisation à tout le site ou à certains scripts "
3919
  "uniquement ?"
3920
 
3921
- #: lib/i18n-extra.php:71
3922
  msgid "View allowed syntax"
3923
  msgstr "Afficher la syntaxe autorisée"
3924
 
3925
- #: lib/i18n-extra.php:72
3926
  #, php-format
3927
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3928
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3929
 
3930
- #: lib/i18n-extra.php:73
3931
  msgid "One item per line."
3932
  msgstr "Une entrée par ligne."
3933
 
3934
- #: lib/i18n-extra.php:74
3935
  msgid ""
3936
  "Leave this field empty if you want geolocation to apply to all your PHP "
3937
  "scripts."
3938
  msgstr ""
3939
  "Laissez ce champ vide pour appliquer la géolocalisation à tout le site."
3940
 
3941
- #: lib/i18n-extra.php:75
3942
  msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3943
  msgstr "Ajouter NINJA_COUNTRY_CODE aux en-têtes PHP ?"
3944
 
3945
- #: lib/i18n-extra.php:76
3946
  msgid "Write event to the firewall log"
3947
  msgstr "Enregistrer l'événement dans le journal du pare-feu"
3948
 
3949
- #: lib/i18n-extra.php:77
3950
  msgid "Allow the following IP, CIDR or AS number"
3951
  msgstr "Accepter les IP, CIDR ou numéros d'AS suivants"
3952
 
3953
- #: lib/i18n-extra.php:78
3954
  #, php-format
3955
  msgid "IPv4 address: %s"
3956
  msgstr "Adresse IPv4 : %s"
3957
 
3958
- #: lib/i18n-extra.php:79
3959
  #, php-format
3960
  msgid "IPv4 CIDR: %s"
3961
  msgstr "CIDR IPv4 : %s"
3962
 
3963
- #: lib/i18n-extra.php:80
3964
  #, php-format
3965
  msgid "IPv6 address: %s"
3966
  msgstr "Adresse IPv6 : %s"
3967
 
3968
- #: lib/i18n-extra.php:81
3969
  #, php-format
3970
  msgid "IPv6 CIDR: %s"
3971
  msgstr "CIDR IPv6 : %s"
3972
 
3973
- #: lib/i18n-extra.php:82
3974
  #, php-format
3975
  msgid "Autonomous System number: %s"
3976
  msgstr "Numéro AS (Autonomous System) : %s"
3977
 
3978
- #: lib/i18n-extra.php:83
3979
  msgid "Whitelist:"
3980
  msgstr "Liste Blanche:"
3981
 
3982
- #: lib/i18n-extra.php:84
3983
  msgid "Enter one item per line."
3984
  msgstr "Une entrée par ligne."
3985
 
3986
- #: lib/i18n-extra.php:85
3987
  msgid "External Services"
3988
  msgstr "Services externes"
3989
 
3990
- #: lib/i18n-extra.php:86
3991
  msgid "Whitelist IP addresses from the following services:"
3992
  msgstr "Ajouter les adresses IP des services suivants à la liste blanche :"
3993
 
3994
- #: lib/i18n-extra.php:87
3995
  msgid "View IP addresses"
3996
  msgstr "Voir les adresses IP"
3997
 
3998
- #: lib/i18n-extra.php:88
3999
  msgid "Block the following IP, CIDR or AS number"
4000
  msgstr "Bloquer les IP, CIDR ou numéros d'AS suivants"
4001
 
4002
- #: lib/i18n-extra.php:89
4003
  msgid "Blacklist:"
4004
  msgstr "Liste noire :"
4005
 
4006
- #: lib/i18n-extra.php:90
4007
  msgid "Rate Limiting"
4008
  msgstr "Limiter le trafic"
4009
 
4010
- #: lib/i18n-extra.php:91
4011
  #, php-format
4012
  msgid ""
4013
  "Block for %s seconds any IP address with more than %s connections within a "
@@ -4016,65 +4026,65 @@ msgstr ""
4016
  "Bloquer pendant %s secondes les IP ayant plus de %s connexions en moins de "
4017
  "%s."
4018
 
4019
- #: lib/i18n-extra.php:92
4020
  msgid "5-second"
4021
  msgstr "5 secondes"
4022
 
4023
- #: lib/i18n-extra.php:93
4024
  msgid "10-second"
4025
  msgstr "10 secondes"
4026
 
4027
- #: lib/i18n-extra.php:94
4028
  msgid "15-second"
4029
  msgstr "15 secondes"
4030
 
4031
- #: lib/i18n-extra.php:95
4032
  msgid "30-second"
4033
  msgstr "30 secondes"
4034
 
4035
- #: lib/i18n-extra.php:96
4036
  msgid "Allow access to the following URL"
4037
  msgstr "Autoriser l'accès à l'URL suivante"
4038
 
4039
- #: lib/i18n-extra.php:97
4040
  #, php-format
4041
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
4042
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
4043
 
4044
- #: lib/i18n-extra.php:98
4045
  msgid "Block access to the following URL"
4046
  msgstr "Bloquer l'accès à l'URL suivante"
4047
 
4048
- #: lib/i18n-extra.php:99
4049
  msgid "Reject the following bots"
4050
  msgstr "Rejeter les bots suivants"
4051
 
4052
- #: lib/i18n-extra.php:100
4053
  msgid "A full or partial case-insensitive string."
4054
  msgstr "Chaîne de caractère complète ou partielle, insensible à la casse."
4055
 
4056
- #: lib/i18n-extra.php:101
4057
  #, php-format
4058
  msgid "Allowed characters are: %s and %s."
4059
  msgstr "Caractères autorisés : %s et %s."
4060
 
4061
- #: lib/i18n-extra.php:102
4062
  msgid "Blocked bots:"
4063
  msgstr "Bots bloqués :"
4064
 
4065
- #: lib/i18n-extra.php:103
4066
  msgid "The default list of bots will be restored. Continue?"
4067
  msgstr "Restaurer les valeurs par défaut de la liste des bots ?"
4068
 
4069
- #: lib/i18n-extra.php:104
4070
  msgid "Restore default bots list"
4071
  msgstr "Restaurer les valeurs par défaut"
4072
 
4073
- #: lib/i18n-extra.php:105
4074
  msgid "Do not filter the following user input"
4075
  msgstr "Ne pas filtrer l'entrée utilisateur suivante"
4076
 
4077
- #: lib/i18n-extra.php:106
4078
  msgid ""
4079
  "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
4080
  "sensitive input:"
@@ -4082,23 +4092,23 @@ msgstr ""
4082
  "Une variable GET, POST ou COOKIE, suivie de deux points (:) et de l'entrée, "
4083
  "sensible à la casse :"
4084
 
4085
- #: lib/i18n-extra.php:107
4086
  msgid "Unfiltered input:"
4087
  msgstr "Entrées non filtrées :"
4088
 
4089
- #: lib/i18n-extra.php:108
4090
  msgid "Block the request if the following input is present"
4091
  msgstr "Bloquer la requête si elle contient l'entrée suivante"
4092
 
4093
- #: lib/i18n-extra.php:109
4094
  msgid "Blocked input:"
4095
  msgstr "Entrées bloquées :"
4096
 
4097
- #: lib/i18n-extra.php:110
4098
  msgid "Save Access Control directives"
4099
  msgstr "Sauvegarder les options"
4100
 
4101
- #: lib/i18n-extra.php:111
4102
  msgid ""
4103
  "Warning: Your previous secret key was either corrupted or missing. A new "
4104
  "one, as well as a new public key, were created."
@@ -4106,23 +4116,23 @@ msgstr ""
4106
  "Attention : votre clé privée était soit corrompue soit manquante. Un nouveau "
4107
  "jeu de clés vient d'être créé."
4108
 
4109
- #: lib/i18n-extra.php:112
4110
  msgid "Enable Centralized Logging"
4111
  msgstr "Activer la Centralisation des Logs"
4112
 
4113
- #: lib/i18n-extra.php:113
4114
  msgid "Secret key"
4115
  msgstr "Clé privée"
4116
 
4117
- #: lib/i18n-extra.php:114
4118
  msgid "From 30 to 100 ASCII printable characters."
4119
  msgstr "De 30 à 100 caractères ASCII."
4120
 
4121
- #: lib/i18n-extra.php:115
4122
  msgid "This server's IP address"
4123
  msgstr "L'adresse IP de ce serveur"
4124
 
4125
- #: lib/i18n-extra.php:116
4126
  msgid ""
4127
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
4128
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
@@ -4132,11 +4142,11 @@ msgstr ""
4132
  "distants. Si vous ne souhaitez pas de restriction d’accès par IP, veuillez "
4133
  "entrer le caractère <code>*</code>."
4134
 
4135
- #: lib/i18n-extra.php:117
4136
  msgid "Public key"
4137
  msgstr "Clé publique"
4138
 
4139
- #: lib/i18n-extra.php:118
4140
  #, php-format
4141
  msgid ""
4142
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
@@ -4145,11 +4155,11 @@ msgstr ""
4145
  "Vous devez configurer vos sites distants avec cette nouvelle clé. <a href="
4146
  "\"%s\">Consultez notre blog</a> pour plus d'info."
4147
 
4148
- #: lib/i18n-extra.php:119
4149
  msgid "Remote websites URL"
4150
  msgstr "URL de vos sites distants"
4151
 
4152
- #: lib/i18n-extra.php:120
4153
  msgid ""
4154
  "Enter one URL per line, including the protocol (<code>http://</code> or "
4155
  "<code>https://</code>). Only ASCII URLs are accepted."
@@ -4157,11 +4167,11 @@ msgstr ""
4157
  "Entrez une URL par ligne, en incluant le protocole (<code>http://</code> ou "
4158
  "<code>https://</code>). Seules les URL au format ASCII sont acceptées."
4159
 
4160
- #: lib/i18n-extra.php:121
4161
  msgid "Save Options"
4162
  msgstr "Sauvegarder les options"
4163
 
4164
- #: lib/i18n-extra.php:122
4165
  msgid ""
4166
  "Your changes have been saved. If you are using a caching plugin, do not "
4167
  "forget to clear its cache."
@@ -4169,19 +4179,19 @@ msgstr ""
4169
  "Vos changements ont été enregistrés. Si vous utilisez une extension de mise "
4170
  "en cache, n'oubliez pas d'effacer son cache."
4171
 
4172
- #: lib/i18n-extra.php:123
4173
  msgid "Enable antispam protection"
4174
  msgstr "Activer la protection anti-spam"
4175
 
4176
- #: lib/i18n-extra.php:124
4177
  msgid "Protection level"
4178
  msgstr "Niveau de protection"
4179
 
4180
- #: lib/i18n-extra.php:125
4181
  msgid "Low (default)"
4182
  msgstr "Bas (défaut)"
4183
 
4184
- #: lib/i18n-extra.php:126
4185
  msgid ""
4186
  "If you are using a caching plugin, consult the contextual help before "
4187
  "enabling the antispam."
@@ -4189,31 +4199,31 @@ msgstr ""
4189
  "Si vous utilisez une extension de mise en cache, veuillez consulter l'aide "
4190
  "contextuelle avant d'activer l'anti-spam."
4191
 
4192
- #: lib/i18n-extra.php:127
4193
  msgid "Apply protection to"
4194
  msgstr "Appliquer la protection au"
4195
 
4196
- #: lib/i18n-extra.php:128
4197
  msgid "Comment forms (defaut)"
4198
  msgstr "Formulaire de commentaire (défaut)"
4199
 
4200
- #: lib/i18n-extra.php:129
4201
  msgid "User Registration form"
4202
  msgstr "Formulaire d'inscription"
4203
 
4204
- #: lib/i18n-extra.php:130
4205
  msgid "Save Antispam options"
4206
  msgstr "Sauvegarder les options"
4207
 
4208
- #: lib/i18n-extra.php:131
4209
  msgid "Please enable JavaScript"
4210
  msgstr "Veuillez activer JavaScript"
4211
 
4212
- #: lib/i18n-extra.php:132
4213
  msgid "Sorry, this looks like spam to me."
4214
  msgstr "Désolé, mais cela ressemble à du spam."
4215
 
4216
- #: lib/i18n-extra.php:133
4217
  msgid ""
4218
  "Error: You must be whitelisted in order to use that feature: click on the <a "
4219
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
@@ -4224,7 +4234,7 @@ msgstr ""
4224
  "et assurez vous que l'option \"Ne pas bloquer les utilisateurs suivants\" "
4225
  "est activée pour l'Administrateur/Super Admin."
4226
 
4227
- #: lib/i18n-extra.php:134
4228
  msgid ""
4229
  "Your license is valid until the indicated expiration date. If you don't "
4230
  "renew it after this date, NinjaFirewall will keep working and protecting "
@@ -4235,7 +4245,7 @@ msgstr ""
4235
  "et à protéger votre site comme d'habitude, mais les mises à jour / mises à "
4236
  "niveau ne pourront plus être effectuées."
4237
 
4238
- #: lib/i18n-extra.php:135
4239
  #, php-format
4240
  msgid ""
4241
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
@@ -4243,11 +4253,11 @@ msgstr ""
4243
  "Vous pouvez renouveler votre licence depuis le site <a href=\"%s"
4244
  "\">NinTechNet.com</a>."
4245
 
4246
- #: lib/i18n-extra.php:136
4247
  msgid "Use shared memory"
4248
  msgstr "Utiliser la mémoire partagée"
4249
 
4250
- #: lib/i18n-extra.php:137
4251
  msgid ""
4252
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
4253
  "order to speed up all operations. The firewall will no longer need to "
@@ -4266,7 +4276,7 @@ msgstr ""
4266
  "réseau multi-site, la vitesse de traitement de pare-feu va augmenter de 25% "
4267
  "à 30%."
4268
 
4269
- #: lib/i18n-extra.php:138
4270
  msgid ""
4271
  "This option requires that your PHP version was compiled with the <code>--"
4272
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
@@ -4275,7 +4285,7 @@ msgstr ""
4275
  "Cette fonction nécessite que PHP soit compilé avec le paramètre <code>--"
4276
  "enable-shmop</code>."
4277
 
4278
- #: lib/i18n-extra.php:139
4279
  #, php-format
4280
  msgid ""
4281
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
@@ -4290,11 +4300,11 @@ msgstr ""
4290
  "être en mesure de nettoyer correctement les caractères multi-octets, car il "
4291
  "n'aura pas accès à la base de données."
4292
 
4293
- #: lib/i18n-extra.php:140
4294
  msgid "Language"
4295
  msgstr "Langue"
4296
 
4297
- #: lib/i18n-extra.php:141
4298
  msgid ""
4299
  "When this option is enabled, NinjaFirewall will download, if available, the "
4300
  "corresponding language files from the WordPress repo. Then, every hour, it "
@@ -4305,7 +4315,7 @@ msgstr ""
4305
  "les heures, il vérifiera s'il existe une nouvelle version et la téléchargera "
4306
  "le cas échéant."
4307
 
4308
- #: lib/i18n-extra.php:142
4309
  msgid ""
4310
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
4311
  "locales because they are already included with NinjaFirewall."
@@ -4313,7 +4323,7 @@ msgstr ""
4313
  "Notez que cela ne s'applique pas aux locales <code>en_US</code> et "
4314
  "<code>fr_FR</code> car elles sont déjà incluses avec NinjaFirewall."
4315
 
4316
- #: lib/i18n-extra.php:143
4317
  #, php-format
4318
  msgid ""
4319
  "This options lets you export you current configuration or import it from "
@@ -4327,7 +4337,7 @@ msgstr ""
4327
  "(%s), sinon il sera rejeté. Notez que l'importation effacera toute votre "
4328
  "configuration (options et règles du pare-feu), sauf votre licence WP+."
4329
 
4330
- #: lib/i18n-extra.php:144
4331
  msgid ""
4332
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
4333
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
@@ -4341,11 +4351,11 @@ msgstr ""
4341
  "systèmes (.htaccess, .htpasswd et PHP INI) et les fichiers SVG contenant du "
4342
  "Javascript ou des Événements XML."
4343
 
4344
- #: lib/i18n-extra.php:145
4345
  msgid "Maximum allowed file size"
4346
  msgstr "Taille maximale autorisée"
4347
 
4348
- #: lib/i18n-extra.php:146
4349
  msgid ""
4350
  "If you allow uploads, you can select the maximum size of an uploaded file. "
4351
  "Any file bigger than this value will be rejected. Note that if your PHP "
@@ -4357,13 +4367,13 @@ msgstr ""
4357
  "configuration de PHP utilise la directive<code>upload_max_filesize</code>, "
4358
  "celle-ci sera prioritaire."
4359
 
4360
- #: lib/i18n-extra.php:147
4361
  msgid "Decode Base64-encoded <code>POST</code> variable:"
4362
  msgstr ""
4363
  "Décoder les chaîne encodées en Base64 dans la variable <code>POST</"
4364
  "code>&nbsp;:"
4365
 
4366
- #: lib/i18n-extra.php:148
4367
  #, php-format
4368
  msgid ""
4369
  "Object Serialization is a PHP feature used by many applications to generate "
@@ -4382,7 +4392,7 @@ msgstr ""
4382
  "<code>POST</code>, les cookies, ou dans les variables <code>HTTP_REFERER</"
4383
  "code> et <code>HTTP_USER_AGENT</code>."
4384
 
4385
- #: lib/i18n-extra.php:149
4386
  msgid ""
4387
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
4388
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
@@ -4396,7 +4406,7 @@ msgstr ""
4396
  "contenant le caractère ASCI 0x00 (NULL byte) sera bloquée immédiatement. Ce "
4397
  "caractère est dangereux et devrait toujours être rejeté."
4398
 
4399
- #: lib/i18n-extra.php:150
4400
  msgid ""
4401
  "This option will block any <code>GET</code> or <code>POST</code> request "
4402
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
@@ -4407,7 +4417,7 @@ msgstr ""
4407
  "les programmes malveillants. Attention toutefois à ne pas bloquer certains "
4408
  "scripts d'installation ou de configuration si vous l'activez."
4409
 
4410
- #: lib/i18n-extra.php:151
4411
  msgid ""
4412
  "Access Control is a powerful set of directives that can be used to allow or "
4413
  "restrict access to your website based on many criteria."
@@ -4416,7 +4426,7 @@ msgstr ""
4416
  "utilisé pour autoriser ou restreindre l'accès à votre site selon de nombreux "
4417
  "critères."
4418
 
4419
- #: lib/i18n-extra.php:152
4420
  msgid ""
4421
  "To make better use of them, it is important to understand NinjaFirewall's "
4422
  "directives processing order."
@@ -4424,7 +4434,7 @@ msgstr ""
4424
  "Afin de pouvoir optimiser son utilisation, il est important de bien "
4425
  "comprendre l'ordre dans lequel NinjaFirewall traite ces directives."
4426
 
4427
- #: lib/i18n-extra.php:153
4428
  msgid ""
4429
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
4430
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
@@ -4435,81 +4445,81 @@ msgstr ""
4435
  "(images, JS, CSS, etc). Selon votre configuration, elle peuvent également "
4436
  "s'appliquer aux pages HTML."
4437
 
4438
- #: lib/i18n-extra.php:154
4439
  msgid "Processing order:"
4440
  msgstr "Ordre de traitement des directives :"
4441
 
4442
- #: lib/i18n-extra.php:155
4443
  msgid "Incoming HTTP request"
4444
  msgstr "Requête HTTP entrante"
4445
 
4446
- #: lib/i18n-extra.php:156
4447
  #, php-format
4448
  msgid "%s file"
4449
  msgstr "Fichier %s"
4450
 
4451
- #: lib/i18n-extra.php:157
4452
  msgid "Login Protection."
4453
  msgstr "Page de Connexion."
4454
 
4455
- #: lib/i18n-extra.php:158
4456
  msgid "Access Control (except User Input Access Control):"
4457
  msgstr "Contrôle d'Accès (sauf Contrôle d'accès d'entrée utilisateur) :"
4458
 
4459
- #: lib/i18n-extra.php:159
4460
  msgid "Role-based Access Control."
4461
  msgstr "Contrôle d'Accès par Rôle."
4462
 
4463
- #: lib/i18n-extra.php:160
4464
  msgid "Allowed IPs."
4465
  msgstr "Adresses IP autorisées."
4466
 
4467
- #: lib/i18n-extra.php:161
4468
  msgid "Blocked IPs."
4469
  msgstr "Adresses IP bloquées."
4470
 
4471
- #: lib/i18n-extra.php:162
4472
  msgid "Allowed URLs."
4473
  msgstr "URL autorisées."
4474
 
4475
- #: lib/i18n-extra.php:163
4476
  msgid "Blocked URLs."
4477
  msgstr "URL bloquées."
4478
 
4479
- #: lib/i18n-extra.php:164
4480
  msgid "Bot Access Control."
4481
  msgstr "Contrôle d'accès par Bot."
4482
 
4483
- #: lib/i18n-extra.php:165
4484
  msgid "Geolocation."
4485
  msgstr "Géolocalisation."
4486
 
4487
- #: lib/i18n-extra.php:166
4488
  msgid "Rate Limiting."
4489
  msgstr "Limitation du trafic."
4490
 
4491
- #: lib/i18n-extra.php:167
4492
  msgid "File Guard."
4493
  msgstr "File Guard."
4494
 
4495
- #: lib/i18n-extra.php:168
4496
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
4497
  msgstr ""
4498
  "Règles et politiques du pare-feu + Contrôle d'accès d'entrée utilisateur."
4499
 
4500
- #: lib/i18n-extra.php:169
4501
  msgid "Response body"
4502
  msgstr "Requête HTTP sortante"
4503
 
4504
- #: lib/i18n-extra.php:170
4505
  msgid "HTTP response headers (Firewall Policies)."
4506
  msgstr "En-têtes de réponse HTTP (Politiques du Pare-feu)."
4507
 
4508
- #: lib/i18n-extra.php:171
4509
  msgid "Web Filter."
4510
  msgstr "Web Filter."
4511
 
4512
- #: lib/i18n-extra.php:172
4513
  #, php-format
4514
  msgid ""
4515
  "By default, any logged in WordPress administrator will not be blocked by "
@@ -4528,13 +4538,13 @@ msgstr ""
4528
  "options de la <a href=\"%s\">Page de Connexion</a> qui, si elle sont "
4529
  "activées, seront toujours appliquées."
4530
 
4531
- #: lib/i18n-extra.php:173
4532
  msgid "You can also add other users to the whitelist, depending on their role."
4533
  msgstr ""
4534
  "Vous pouvez ajouter d'autres utilisateurs à votre liste blanche en se basant "
4535
  "sur leur Rôle."
4536
 
4537
- #: lib/i18n-extra.php:174
4538
  #, php-format
4539
  msgid ""
4540
  "this option should be used if you are behind a reverse proxy, a load "
@@ -4558,7 +4568,7 @@ msgstr ""
4558
  "sera vérifiée. Si elle ne comprend aucune IP utilisable, NinjaFirewall "
4559
  "utilisera <code>REMOTE_ADDR</code>."
4560
 
4561
- #: lib/i18n-extra.php:175
4562
  msgid ""
4563
  "This option lets you select the HTTP method(s). All Access Control "
4564
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
@@ -4568,20 +4578,20 @@ msgstr ""
4568
  "Contrôle d'Accès (Geolocalisation, IP, bots et URL) ne s'appliqueront qu'aux "
4569
  "méthodes sélectionnées."
4570
 
4571
- #: lib/i18n-extra.php:176
4572
  msgid ""
4573
  "It does not apply to the \"Firewall Policies\" options, which use their own "
4574
  "ones."
4575
  msgstr "Cette option ne concerne pas les \"Politiques du Pare-feu\"."
4576
 
4577
- #: lib/i18n-extra.php:177
4578
  msgid ""
4579
  "You can filter and block traffic coming from specific countries/territories."
4580
  msgstr ""
4581
  "Vous pouvez filtrer et bloquer le trafic en provenance de pays ou "
4582
  "territoires spécifiques."
4583
 
4584
- #: lib/i18n-extra.php:178
4585
  msgid ""
4586
  "This is the two-letter code that is used to define a country/territory (e."
4587
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
@@ -4594,7 +4604,7 @@ msgstr ""
4594
  "données, ou à partir d'une variable PHP prédéfinie ajoutée par votre serveur "
4595
  "HTTP (par exemple, <code>GEOIP_COUNTRY_CODE</code>)."
4596
 
4597
- #: lib/i18n-extra.php:179
4598
  #, php-format
4599
  msgid ""
4600
  "You can add/remove any country/territory from the two listboxes. For more "
@@ -4606,7 +4616,7 @@ msgstr ""
4606
  "spécifiques (A1, A2, AP, EU etc),vous pouvez consulter l'aide en ligne de <a "
4607
  "href=\"%s\">MaxMind GeoIP</a>."
4608
 
4609
- #: lib/i18n-extra.php:180
4610
  msgid ""
4611
  "Whether geolocation should apply to the whole site or to specific URLs only "
4612
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
@@ -4616,11 +4626,11 @@ msgstr ""
4616
  "uniquement (ex: /wp-login.php, /xmlrpc.php etc). Laissez ce champ vide pour "
4617
  "l'appliquer à tout le site."
4618
 
4619
- #: lib/i18n-extra.php:181
4620
  msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
4621
  msgstr "Ajouter <code>NINJA_COUNTRY_CODE</code> aux en-têtes PHP?"
4622
 
4623
- #: lib/i18n-extra.php:182
4624
  msgid ""
4625
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
4626
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
@@ -4632,7 +4642,7 @@ msgstr ""
4632
  "code>. Si vous avez une application PHP qui nécessite de géolocaliser vos "
4633
  "visiteurs, activez cette option."
4634
 
4635
- #: lib/i18n-extra.php:183
4636
  msgid ""
4637
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
4638
  "it with 2 hyphens (<code>--</code>)."
@@ -4640,13 +4650,13 @@ msgstr ""
4640
  "Si NinjaFirewall ne peut pas identifier le code à deux lettres ISO 3166, il "
4641
  "le remplacera par deux traits d'union (<code>--</code>)."
4642
 
4643
- #: lib/i18n-extra.php:184
4644
  msgid ""
4645
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
4646
  msgstr ""
4647
  "Exemple de code PHP à ajouter à vos scripts pour géolocaliser vos visiteurs :"
4648
 
4649
- #: lib/i18n-extra.php:185
4650
  msgid ""
4651
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4652
  "http://www.maxmind.com"
@@ -4654,11 +4664,11 @@ msgstr ""
4654
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4655
  "http://www.maxmind.com"
4656
 
4657
- #: lib/i18n-extra.php:186
4658
  msgid "IP / URL / Bot Access Control"
4659
  msgstr "Contrôle d'Accès par IP / URL / Bots"
4660
 
4661
- #: lib/i18n-extra.php:187
4662
  msgid ""
4663
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
4664
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
@@ -4668,20 +4678,20 @@ msgstr ""
4668
  "numéro AS (Autonomous System). NinjaFirewall est compatible avec l'IPv4 et "
4669
  "l'IPv6."
4670
 
4671
- #: lib/i18n-extra.php:188
4672
  msgid "Full IP:"
4673
  msgstr "IP complète :"
4674
 
4675
- #: lib/i18n-extra.php:189
4676
  #, php-format
4677
  msgid "IP ranges using CIDR notation: %s or %s."
4678
  msgstr "Plages IP utilisant la notation CIDR : %s ou %s."
4679
 
4680
- #: lib/i18n-extra.php:190
4681
  msgid "Autonomous System number:"
4682
  msgstr "Numéro AS (Autonomous System) :"
4683
 
4684
- #: lib/i18n-extra.php:191
4685
  msgid ""
4686
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
4687
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
@@ -4700,7 +4710,7 @@ msgstr ""
4700
  "adresse IP, utilisez l'option \"Contrôle d'accès par IP\". Par défaut, la "
4701
  "limitation du trafic n'est pas activée."
4702
 
4703
- #: lib/i18n-extra.php:192
4704
  msgid ""
4705
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
4706
  "immediately by clicking either the \"Save Access Control Directives\" or "
@@ -4710,7 +4720,7 @@ msgstr ""
4710
  "débloquées simplement en cliquant sur les boutons \"Sauvegarder les options"
4711
  "\" ou \"Rétablir les valeurs par défaut\" situés en bas de la page."
4712
 
4713
- #: lib/i18n-extra.php:193
4714
  msgid ""
4715
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
4716
  "IPs even before your blog is loaded, we strongly recommend that you disable "
@@ -4724,7 +4734,7 @@ msgstr ""
4724
  "seconde, NinjaFirewall vous fera économiser de la bande passante et "
4725
  "permettra de réduire la charge du serveur."
4726
 
4727
- #: lib/i18n-extra.php:194
4728
  msgid ""
4729
  "You can permanently allow/block any access to one or more PHP scripts based "
4730
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
@@ -4735,7 +4745,7 @@ msgstr ""
4735
  "(<code>SCRIPT_NAME</code>). Vous pouvez entrer l'URL complète ou partielle, "
4736
  "sensible à la casse."
4737
 
4738
- #: lib/i18n-extra.php:195
4739
  msgid ""
4740
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
4741
  "script located inside a <code>/foo/</code> directory"
@@ -4743,11 +4753,11 @@ msgstr ""
4743
  "<code>/foo/bar.php</code> autorisera/bloquera tout accès au script PHP "
4744
  "<code>bar.php</code> situé dans un répertoire <code>/foo/</code>"
4745
 
4746
- #: lib/i18n-extra.php:196
4747
  msgid "etc"
4748
  msgstr "etc"
4749
 
4750
- #: lib/i18n-extra.php:197
4751
  msgid ""
4752
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
4753
  "<code>/foo/</code> directory and its sub-directories."
@@ -4755,7 +4765,7 @@ msgstr ""
4755
  "<code>/foo/</code> autorisera/bloquera l'accès à tous les scripts PHP situés "
4756
  "dans un répertoire <code>/foo/</code> et ses sous-répertoires."
4757
 
4758
- #: lib/i18n-extra.php:198
4759
  msgid ""
4760
  "Note that the \"Firewall Policies\" page already includes restrictions to "
4761
  "some WordPress directories."
@@ -4763,7 +4773,7 @@ msgstr ""
4763
  "Notez que le menu des \"Politiques du pare-feu\" comporte déjà des "
4764
  "restrictions à certains répertoires de WordPress."
4765
 
4766
- #: lib/i18n-extra.php:199
4767
  msgid ""
4768
  "You can block bots, scanners and various crawlers based on the "
4769
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
@@ -4773,7 +4783,7 @@ msgstr ""
4773
  "nom (<code>HTTP_USER_AGENT</code>) ou partie de celui-ci. La chaîne de "
4774
  "caractères est insensible à la casse."
4775
 
4776
- #: lib/i18n-extra.php:200
4777
  msgid ""
4778
  "You can select to ignore or block some specific user input. It applies to "
4779
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
@@ -4785,7 +4795,7 @@ msgstr ""
4785
  "<code>COOKIE</code>, par exemple <code>$_GET[\"foo\"]</code> ou <code>"
4786
  "$_POST[\"bar\"]</code> :"
4787
 
4788
- #: lib/i18n-extra.php:201
4789
  msgid ""
4790
  "When an input is added to the \"Unfiltered input\" list, it will not be "
4791
  "filtered or sanitised. All other input present in the request will be "
@@ -4795,7 +4805,7 @@ msgstr ""
4795
  "sera ni filtrée ni nettoyée. Toutes les autres entrées présentes dans la "
4796
  "demande seront filtrées."
4797
 
4798
- #: lib/i18n-extra.php:202
4799
  msgid ""
4800
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
4801
  "the request and close the connection if that input is found in the request."
@@ -4804,11 +4814,11 @@ msgstr ""
4804
  "bloquera la requête et fermera la connexion si cette entrée est présente "
4805
  "dans la requête."
4806
 
4807
- #: lib/i18n-extra.php:203
4808
  msgid "Log Event"
4809
  msgstr "Journaliser"
4810
 
4811
- #: lib/i18n-extra.php:204
4812
  msgid ""
4813
  "You can enable/disable firewall logging for each access control directive "
4814
  "separately."
@@ -4816,11 +4826,11 @@ msgstr ""
4816
  "Vous pouvez activer/désactiver la journalisation des directives "
4817
  "indépendamment les unes des autres."
4818
 
4819
- #: lib/i18n-extra.php:205
4820
  msgid "Web Filter"
4821
  msgstr "Web Filter"
4822
 
4823
- #: lib/i18n-extra.php:206
4824
  msgid ""
4825
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
4826
  "response body (i.e., the output of the HTML page right before it is sent to "
@@ -4837,7 +4847,7 @@ msgstr ""
4837
  "etc), des scripts utilisés par les hackers (shell, backdoor) et même des "
4838
  "erreurs (PHP, MySQL)."
4839
 
4840
- #: lib/i18n-extra.php:207
4841
  msgid ""
4842
  "In the case of a positive detection, NinjaFirewall will not block the "
4843
  "response body but will send you an alert by email."
@@ -4845,11 +4855,11 @@ msgstr ""
4845
  "En cas de détection positive, NinjaFirewall ne bloquera pas la requête mais "
4846
  "vous enverra immédiatement une alerte par e-mail."
4847
 
4848
- #: lib/i18n-extra.php:208
4849
  msgid "Search HTML page for the following keywords"
4850
  msgstr "Rechercher les mots suivants dans la page HTML"
4851
 
4852
- #: lib/i18n-extra.php:209
4853
  msgid ""
4854
  "You can enter any keyword from 4 to 150 characters and select whether the "
4855
  "search will be case sensitive or not."
@@ -4857,11 +4867,11 @@ msgstr ""
4857
  "Vous pouvez entrer de 4 à 150 caractères et sélectionner si la recherche est "
4858
  "sensible à la casse."
4859
 
4860
- #: lib/i18n-extra.php:210
4861
  msgid "Email Alerts"
4862
  msgstr "Alertes E-mail"
4863
 
4864
- #: lib/i18n-extra.php:211
4865
  msgid ""
4866
  "You can use the notification throttling option to limit the frequency of "
4867
  "alerts sent to you (and written to the firewall log) and select whether you "
@@ -4873,7 +4883,7 @@ msgstr ""
4873
  "d'Événement \". La page HTML ayant déclenché cette alerte peut être jointe à "
4874
  "l'e-mail."
4875
 
4876
- #: lib/i18n-extra.php:212
4877
  msgid ""
4878
  "Response body filtering can be resource-intensive. Try to limit the number "
4879
  "of keywords to what you really need (less than 10) and, if possible, prefer "
@@ -4883,7 +4893,7 @@ msgstr ""
4883
  "limiter le nombre de mots-clés (moins de 10) et, si possible, préférez la "
4884
  "recherche sensible à la casse."
4885
 
4886
- #: lib/i18n-extra.php:213
4887
  msgid ""
4888
  "NinjaFirewall can protect your blog against spam without user interaction (e."
4889
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
@@ -4898,11 +4908,11 @@ msgstr ""
4898
  "vous utilisez une extension tierce pour créer vos formulaires, ils ne seront "
4899
  "pas protégés contre le spam."
4900
 
4901
- #: lib/i18n-extra.php:214
4902
  msgid "Protection level:"
4903
  msgstr "Niveau de protection :"
4904
 
4905
- #: lib/i18n-extra.php:215
4906
  msgid ""
4907
  "Select the level of protection. In most cases, <strong>Low</strong> should "
4908
  "be enough."
@@ -4910,21 +4920,21 @@ msgstr ""
4910
  "Sélectionnez le niveau de protection. Dans la plupart des cas \"Bas\" est "
4911
  "suffisant."
4912
 
4913
- #: lib/i18n-extra.php:216
4914
  msgid "Apply protection to:"
4915
  msgstr "Appliquer la protection à :"
4916
 
4917
- #: lib/i18n-extra.php:217
4918
  msgid "Whether to protect comment and/or registration forms."
4919
  msgstr "S'il faut protéger les formulaires de commentaire et d'inscription."
4920
 
4921
- #: lib/i18n-extra.php:218
4922
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4923
  msgstr ""
4924
  "Si vous utilisez une extension de mise en cache, veuillez procéder de la "
4925
  "sorte :"
4926
 
4927
- #: lib/i18n-extra.php:219
4928
  msgid ""
4929
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4930
  "otherwise the antispam could behave erratically after a while."
@@ -4932,14 +4942,14 @@ msgstr ""
4932
  "Réglez le niveau de protection sur \"Bas\" uniquement. N'utilisez pas "
4933
  "d'autre niveau, sinon l'anti-spam pourrait se comporter de façon erratique."
4934
 
4935
- #: lib/i18n-extra.php:220
4936
  msgid ""
4937
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4938
  msgstr ""
4939
  "Videz / effacez votre cache immédiatement après l'activation ou la "
4940
  "désactivation de l'anti-spam."
4941
 
4942
- #: lib/i18n-extra.php:221
4943
  msgid ""
4944
  "The firewall log displays blocked and sanitised requests as well as some "
4945
  "useful information. It has 6 columns:"
@@ -4947,7 +4957,7 @@ msgstr ""
4947
  "Le journal du pare-feu affiche les requêtes HTTP qui ont été bloquées ou "
4948
  "nettoyées ainsi que d'autres informations utiles. Il a six colonnes :"
4949
 
4950
- #: lib/i18n-extra.php:222
4951
  msgid ""
4952
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4953
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
@@ -4958,23 +4968,23 @@ msgstr ""
4958
  "d'un numéro signifie que la règle provient de votre configuration "
4959
  "personnelle de la page \"Politiques du Pare-feu\" ou \"Contrôle d'Accès\"."
4960
 
4961
- #: lib/i18n-extra.php:223
4962
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4963
  msgstr ""
4964
  "Le journal peut aussi être exporté au format TSV (valeurs séparées par des "
4965
  "tabulations)."
4966
 
4967
- #: lib/i18n-extra.php:224
4968
  msgid "Enable firewall log"
4969
  msgstr "Activer le journal du pare-feu"
4970
 
4971
- #: lib/i18n-extra.php:225
4972
  msgid "You can disable/enable the firewall log from this page."
4973
  msgstr ""
4974
  "Vous pouvez activer / désactiver le journal du pare-feu à partir de cette "
4975
  "page."
4976
 
4977
- #: lib/i18n-extra.php:226
4978
  msgid ""
4979
  "Brute-force attacks will still be written to the firewall log, even if you "
4980
  "disable it."
@@ -4982,11 +4992,11 @@ msgstr ""
4982
  "Les attaques par force brute seront toujours enregistrées dans le journal du "
4983
  "pare-feu, même si vous désactivez celui-ci."
4984
 
4985
- #: lib/i18n-extra.php:227
4986
  msgid "Auto-rotate log"
4987
  msgstr "Rotation automatique du journal"
4988
 
4989
- #: lib/i18n-extra.php:228
4990
  msgid ""
4991
  "NinjaFirewall will rotate its log automatically on the very first day of "
4992
  "each month. If your site is very busy, you may want to allow it to rotate "
@@ -4997,24 +5007,24 @@ msgstr ""
4997
  "effectuée plus tôt, dans le cas où le journal aurait atteint une certaine "
4998
  "taille (Mo)."
4999
 
5000
- #: lib/i18n-extra.php:229
5001
  msgid ""
5002
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
5003
  "megabytes."
5004
  msgstr "Par défaut, cette taille est fixée à 2 Mo."
5005
 
5006
- #: lib/i18n-extra.php:230
5007
  msgid ""
5008
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
5009
  msgstr ""
5010
  "Les journaux des mois précédents sont accessibles depuis le menu déroulant "
5011
  "situé au dessus de la fenêtre."
5012
 
5013
- #: lib/i18n-extra.php:231
5014
  msgid "Syslog"
5015
  msgstr "Syslog"
5016
 
5017
- #: lib/i18n-extra.php:232
5018
  msgid ""
5019
  "In addition to the firewall log, events can also be redirected to the syslog "
5020
  "server (<code>LOG_USER</code> facility)."
@@ -5022,7 +5032,7 @@ msgstr ""
5022
  "En plus d'écrire dans son journal, le pare-feu peut aussi utiliser le "
5023
  "serveur Syslog (catégorie <code>LOG_USER</code>)."
5024
 
5025
- #: lib/i18n-extra.php:233
5026
  msgid ""
5027
  "If you have a shared hosting account, keep this option disabled as you do "
5028
  "not have any access to the server logs."
@@ -5030,11 +5040,11 @@ msgstr ""
5030
  "Si vous avez un hébergement mutualisé, laissez cette option désactivée car "
5031
  "vous n'avez pas accès aux journaux du serveur."
5032
 
5033
- #: lib/i18n-extra.php:234
5034
  msgid "The logline uses the following format:"
5035
  msgstr "Le format utilisé est le suivant :"
5036
 
5037
- #: lib/i18n-extra.php:235
5038
  msgid ""
5039
  "BB: the level of severity as it appears in the firewall log. It can be "
5040
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
@@ -5045,19 +5055,19 @@ msgstr ""
5045
  "<CODE>MEDIUM</CODE>, <CODE>INFO</CODE>, <CODE>UPLOAD</CODE> ou "
5046
  "<CODE>DEBUG_ON</CODE>."
5047
 
5048
- #: lib/i18n-extra.php:236
5049
  msgid "CCCCCC: the 7-digit incident ID."
5050
  msgstr "CCCCCC : le numéro d'incident à sept chiffres."
5051
 
5052
- #: lib/i18n-extra.php:237
5053
  msgid "DD: the user IPv4 or IPv6 address."
5054
  msgstr "DD : L'adresse IPv4 ou IPv6 de l'utilisateur."
5055
 
5056
- #: lib/i18n-extra.php:238
5057
  msgid "EE: the blog (sub-)domain name."
5058
  msgstr "EE : le nom de (sous-)domaine du blog."
5059
 
5060
- #: lib/i18n-extra.php:239
5061
  #, php-format
5062
  msgid ""
5063
  "This logging option does not apply to the brute-force protection which can "
@@ -5069,7 +5079,7 @@ msgstr ""
5069
  "d'authentification du serveur. Voir le menu de la <a href=\"%s\">Page de "
5070
  "Connexion</a>."
5071
 
5072
- #: lib/i18n-extra.php:240
5073
  msgid ""
5074
  "Secret key: The secret key will be used to generate your public key. Enter "
5075
  "at least 30 ASCII characters, or use the one randomly created by "
@@ -5079,7 +5089,7 @@ msgstr ""
5079
  "de 30 à 100 caractères ASCII, ou bien utilisez la clé générée aléatoirement "
5080
  "par NinjaFirewall."
5081
 
5082
- #: lib/i18n-extra.php:241
5083
  msgid ""
5084
  "This server IP address: As an additional protection layer, you can restrict "
5085
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
@@ -5090,7 +5100,7 @@ msgstr ""
5090
  "à se connecter aux sites distants. Si vous ne souhaitez pas de restriction "
5091
  "d’accès par IP, veuillez entrer le caractère <code>*</code>."
5092
 
5093
- #: lib/i18n-extra.php:242
5094
  #, php-format
5095
  msgid ""
5096
  "Public key: This is the public key that you will need to upload to each "
@@ -5099,7 +5109,7 @@ msgstr ""
5099
  "Clé publique : Vous devez configurer vos sites distants avec cette clé. <a "
5100
  "href=\"%s\">Consultez notre blog</a> pour plus d'info."
5101
 
5102
- #: lib/i18n-extra.php:243
5103
  msgid ""
5104
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
5105
  "website(s) that you want to remotely access from the main server."
@@ -5108,7 +5118,7 @@ msgstr ""
5108
  "NinjaFirewall auxquels vous souhaitez accéder à distance à partir du serveur "
5109
  "principal."
5110
 
5111
- #: lib/i18n-extra.php:244
5112
  msgid ""
5113
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
5114
  "the menu below if you want to disable it."
@@ -5117,172 +5127,172 @@ msgstr ""
5117
  "NinjaFirewall. Si vous souhaitez complètement désactiver cette option, "
5118
  "faites-le ci-dessous."
5119
 
5120
- #: lib/i18n-extra.php:245
5121
  msgid "Enable Web Filter"
5122
  msgstr "Activer Web Filter"
5123
 
5124
- #: lib/i18n-extra.php:246
5125
  msgid "A full or partial string."
5126
  msgstr "Chaîne de caractère complète ou partielle."
5127
 
5128
- #: lib/i18n-extra.php:247
5129
  msgid "From 4 to maximum 150 characters."
5130
  msgstr "De 4 à 150 caractères."
5131
 
5132
- #: lib/i18n-extra.php:248
5133
  msgid "Any character, except the vertical bar <code>|</code>"
5134
  msgstr "Tout caractère, sauf la barre verticale <code>|</code>"
5135
 
5136
- #: lib/i18n-extra.php:249
5137
  msgid "Keywords to search:"
5138
  msgstr "Mots-clés recherchés :"
5139
 
5140
- #: lib/i18n-extra.php:250
5141
  msgid "Case-sensitive search"
5142
  msgstr "Recherche sensible à la casse"
5143
 
5144
- #: lib/i18n-extra.php:251
5145
  #, php-format
5146
  msgid "Do not send me more than one email alert in a %s interval"
5147
  msgstr "Ne pas envoyer plus d'un e-mail par tranche de %s"
5148
 
5149
- #: lib/i18n-extra.php:252
5150
  msgid "5-minute"
5151
  msgstr "5 minutes"
5152
 
5153
- #: lib/i18n-extra.php:253
5154
  msgid "15-minute"
5155
  msgstr "15 minutes"
5156
 
5157
- #: lib/i18n-extra.php:254
5158
  msgid "30-minute"
5159
  msgstr "30 minutes"
5160
 
5161
- #: lib/i18n-extra.php:255
5162
  msgid "1-hour"
5163
  msgstr "1 heure"
5164
 
5165
- #: lib/i18n-extra.php:256
5166
  msgid "3-hour"
5167
  msgstr "3 heures"
5168
 
5169
- #: lib/i18n-extra.php:257
5170
  msgid "6-hour"
5171
  msgstr "6 heures"
5172
 
5173
- #: lib/i18n-extra.php:258
5174
  msgid "12-hour"
5175
  msgstr "12 heures"
5176
 
5177
- #: lib/i18n-extra.php:259
5178
  msgid "24-hour"
5179
  msgstr "24 heures"
5180
 
5181
- #: lib/i18n-extra.php:260
5182
  msgid ""
5183
  "Clicking the \"Save Web Filter options\" button below will reset the current "
5184
  "timer."
5185
  msgstr "Cliquer sur \"Sauvegarder les options\" réinitialisera le compteur."
5186
 
5187
- #: lib/i18n-extra.php:261
5188
  msgid "Attach the HTML page output to email alerts"
5189
  msgstr "Joindre la page HTML à l'e-mail"
5190
 
5191
- #: lib/i18n-extra.php:262
5192
  msgid "Save Web Filter options"
5193
  msgstr "Sauvegarder les options"
5194
 
5195
- #: lib/i18n-extra.php:263
5196
  msgid "Help Desk:"
5197
  msgstr "Help Desk :"
5198
 
5199
- #: lib/i18n-extra.php:264
5200
  msgid "The selected log was deleted"
5201
  msgstr "Le journal sélectionné a été supprimé"
5202
 
5203
- #: lib/i18n-extra.php:265
5204
  msgid "Export"
5205
  msgstr "Exporter"
5206
 
5207
- #: lib/i18n-extra.php:266
5208
  msgid "Delete"
5209
  msgstr "Supprimer"
5210
 
5211
- #: lib/i18n-extra.php:267
5212
  msgid "Delete log?"
5213
  msgstr "Supprimer le journal ?"
5214
 
5215
- #: lib/i18n-extra.php:268
5216
  msgid "Today"
5217
  msgstr "Aujourd'hui"
5218
 
5219
- #: lib/i18n-extra.php:269
5220
  msgid "Upload"
5221
  msgstr "Téléchargement"
5222
 
5223
- #: lib/i18n-extra.php:270
5224
  msgid "Info"
5225
  msgstr "Info"
5226
 
5227
- #: lib/i18n-extra.php:271
5228
  msgid "Debug"
5229
  msgstr "Débogage"
5230
 
5231
- #: lib/i18n-extra.php:272
5232
  msgid "IP address:"
5233
  msgstr "Adresse IP :"
5234
 
5235
- #: lib/i18n-extra.php:273
5236
  msgid "e.g., 1.2.3.4"
5237
  msgstr "ex : 1.2.3.4"
5238
 
5239
- #: lib/i18n-extra.php:274
5240
  msgid "Add IP to blacklist"
5241
  msgstr "Ajouter à la liste noire"
5242
 
5243
- #: lib/i18n-extra.php:275
5244
  msgid "Add IP to whitelist"
5245
  msgstr "Ajouter à la liste blanche"
5246
 
5247
- #: lib/i18n-extra.php:276
5248
  msgid "Add"
5249
  msgstr "Ajouter"
5250
 
5251
- #: lib/i18n-extra.php:277
5252
  msgid "The address wad added to your IP Access Control list."
5253
  msgstr "L'adresse a été ajoutée à votre liste du Contrôle d'accès par IP."
5254
 
5255
- #: lib/i18n-extra.php:278
5256
  #, php-format
5257
  msgid "1st day of the month, or if bigger than %s MB"
5258
  msgstr "Le 1er de chaque mois, ou si sa taille dépasse %s Mo"
5259
 
5260
- #: lib/i18n-extra.php:279
5261
  msgid "1st day of the month, regardless of its size"
5262
  msgstr "Le 1er de chaque mois, quelle que soit sa taille"
5263
 
5264
- #: lib/i18n-extra.php:280
5265
  msgid "Show the most recent"
5266
  msgstr "Afficher les dernières"
5267
 
5268
- #: lib/i18n-extra.php:281
5269
  msgid "lines"
5270
  msgstr "lignes"
5271
 
5272
- #: lib/i18n-extra.php:282
5273
  msgid "Write events to the Syslog server too"
5274
  msgstr "Enregistrer aussi les événements dans le journal syslog"
5275
 
5276
- #: lib/i18n-extra.php:283
5277
  msgid "Your server configuration is not compatible with this option."
5278
  msgstr ""
5279
  "La configuration de votre serveur n'est pas compatible avec cette option."
5280
 
5281
- #: lib/i18n-extra.php:284
5282
  msgid "See contextual help before enabling this option."
5283
  msgstr "Consultez l'aide contextuelle avant d'activer cette option."
5284
 
5285
- #: lib/i18n-extra.php:285
5286
  msgid ""
5287
  "The remote server rejected your request. Make sure that you uploaded the "
5288
  "correct public key."
@@ -5290,29 +5300,29 @@ msgstr ""
5290
  "Le serveur distant a rejeté votre requête. Veuillez vous assurer que la clé "
5291
  "publique est correcte."
5292
 
5293
- #: lib/i18n-extra.php:286
5294
  #, php-format
5295
  msgid "The remote server returned the following HTTP error: %s"
5296
  msgstr "Le serveur HTTP a retourné le code d'erreur suivant : %s"
5297
 
5298
- #: lib/i18n-extra.php:287
5299
  msgid "The requested log does not exist on the remote website."
5300
  msgstr "Le journal demandé n'existe pas sur le site distant."
5301
 
5302
- #: lib/i18n-extra.php:288
5303
  msgid "The remote website did not return the expected response."
5304
  msgstr "Le site distant n'a pas retourné la réponse attendue."
5305
 
5306
- #: lib/i18n-extra.php:289
5307
  msgid "Your server does not seem to be compatible with this option."
5308
  msgstr ""
5309
  "La configuration de votre serveur n'est pas compatible avec cette option."
5310
 
5311
- #: lib/i18n-extra.php:290
5312
  msgid "Load language files from the WordPress repo"
5313
  msgstr "Charger les fichiers de langue depuis le WordPress.org"
5314
 
5315
- #: lib/i18n-extra.php:291
5316
  #, php-format
5317
  msgid ""
5318
  "If available, NinjaFirewall will download the language files from <a "
@@ -5321,15 +5331,15 @@ msgstr ""
5321
  "Si disponible, NinjaFirewall téléchargera le fichier de langue à partir de "
5322
  "<a %s>translate.wordpress.org</a>."
5323
 
5324
- #: lib/i18n-extra.php:292
5325
  msgid "Error: you do not have any license."
5326
  msgstr "Erreur : vous n'avez pas de licence."
5327
 
5328
- #: lib/i18n-extra.php:293
5329
  msgid "You have a valid license."
5330
  msgstr "Votre licence est valide."
5331
 
5332
- #: lib/i18n-extra.php:294
5333
  msgid ""
5334
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
5335
  "try again in a few minutes"
@@ -5337,7 +5347,7 @@ msgstr ""
5337
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5338
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5339
 
5340
- #: lib/i18n-extra.php:295
5341
  msgid ""
5342
  "An error occured while connecting to NinjaFirewall servers. Please try again "
5343
  "in a few minutes"
@@ -5345,90 +5355,90 @@ msgstr ""
5345
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5346
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5347
 
5348
- #: lib/i18n-extra.php:296
5349
  msgid "Enter a valid license to save!"
5350
  msgstr "Veuillez entrer un numéro de licence valide !"
5351
 
5352
- #: lib/i18n-extra.php:297
5353
  msgid "This is already your current license!"
5354
  msgstr "Cette licence est la même que l'actuelle !"
5355
 
5356
- #: lib/i18n-extra.php:298
5357
  msgid "Your new license has been accepted and saved."
5358
  msgstr "Votre nouvelle licence a été acceptée et sauvegardée."
5359
 
5360
- #: lib/i18n-extra.php:299
5361
  msgid "This license is not valid"
5362
  msgstr "Cette licence n'est pas valide"
5363
 
5364
- #: lib/i18n-extra.php:300
5365
  msgid "WP+ Edition License"
5366
  msgstr "Licence WP+ Edition"
5367
 
5368
- #: lib/i18n-extra.php:301
5369
  msgid "License Number"
5370
  msgstr "Numéro de Licence"
5371
 
5372
- #: lib/i18n-extra.php:302
5373
  msgid "No license found"
5374
  msgstr "Aucune licence trouvée"
5375
 
5376
- #: lib/i18n-extra.php:303
5377
  msgid "Click to check your license validity"
5378
  msgstr "Cliquez pour tester la validité de votre licence"
5379
 
5380
- #: lib/i18n-extra.php:304
5381
  msgid "Expiration date"
5382
  msgstr "Date d'expiration"
5383
 
5384
- #: lib/i18n-extra.php:305
5385
  msgid "Unknown expiration date"
5386
  msgstr "Date d'expiration inconnue"
5387
 
5388
- #: lib/i18n-extra.php:306
5389
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
5390
  msgstr ""
5391
  "Selectionnez \"Cliquez pour tester la validité de votre licence\" pour "
5392
  "tenter de réparer cette erreur."
5393
 
5394
- #: lib/i18n-extra.php:307
5395
  msgid "Your license will expire soon!"
5396
  msgstr "Votre licence va bientôt expirer !"
5397
 
5398
- #: lib/i18n-extra.php:308
5399
  msgid "Your license has expired."
5400
  msgstr "Votre licence a expiré."
5401
 
5402
- #: lib/i18n-extra.php:309
5403
  msgid "License renewal"
5404
  msgstr "Renouvellement de licence"
5405
 
5406
- #: lib/i18n-extra.php:310
5407
  msgid "Click here to get a license!"
5408
  msgstr "Cliquez ici pour obtenir une licence !"
5409
 
5410
- #: lib/i18n-extra.php:311
5411
  msgid "Enter your new license and click on the save button"
5412
  msgstr "Entrez votre licence et cliquez sur le bouton pour l'enregistrer"
5413
 
5414
- #: lib/i18n-extra.php:312
5415
  msgid "Save New License"
5416
  msgstr "Sauvegarder la Licence"
5417
 
5418
- #: lib/i18n-extra.php:313
5419
  msgid "Allow, but block dangerous files"
5420
  msgstr "Autoriser, mais bloquer les fichiers dangereux"
5421
 
5422
- #: lib/i18n-extra.php:314
5423
  msgid "See contextual help for the list of files."
5424
  msgstr ""
5425
  "Consultez l'aide contextuelle pour voir la liste des fichiers concernés."
5426
 
5427
- #: lib/i18n-extra.php:315
5428
  msgid "Apply to ZIP archives file contents"
5429
  msgstr "Appliquer au contenu des fichiers ZIP"
5430
 
5431
- #: lib/i18n-extra.php:316
5432
  msgid ""
5433
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
5434
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
@@ -5438,7 +5448,7 @@ msgstr ""
5438
  "WordPress WP-Cron, sauf si vous avez ajouté leur adresse IP ou URL dans la "
5439
  "section \"Contrôle d'Accès\"."
5440
 
5441
- #: lib/i18n-extra.php:317
5442
  #, php-format
5443
  msgid ""
5444
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
@@ -5455,7 +5465,7 @@ msgstr ""
5455
  "Erreur : Votre fichier .htaccess n'est pas accessible en écriture. Veuillez "
5456
  "modifier ses autorisations : %s"
5457
 
5458
- #: lib/install.php:110 ninjafirewall.php:656 ninjafirewall.php:660
5459
  #, php-format
5460
  msgid "Error: wrong parameter value (%s)."
5461
  msgstr "Erreur : Mauvais paramètre (%s)."
@@ -5733,7 +5743,7 @@ msgstr "Erreur : le mot de passe doit comporter de 6 à 255 caractères."
5733
  msgid "Error: unable to write to the %s configuration file"
5734
  msgstr "Erreur : impossible d’écrire dans le fichier de configuration %s"
5735
 
5736
- #: lib/logs.php:36 ninjafirewall.php:930
5737
  msgid "Logs"
5738
  msgstr "Journaux"
5739
 
@@ -5803,7 +5813,7 @@ msgstr ""
5803
  msgid "Viewing:"
5804
  msgstr "Journal :"
5805
 
5806
- #: lib/logs_firewall_log.php:142 lib/logs_firewall_log.php:304
5807
  msgid "The selected log is empty."
5808
  msgstr "Le journal sélectionné est vide."
5809
 
@@ -5853,11 +5863,11 @@ msgstr "Sauvegarder la clé publique"
5853
  msgid "Delete Public Key"
5854
  msgstr "Supprimer la clé publique"
5855
 
5856
- #: lib/logs_firewall_log.php:283
5857
  msgid "The requested log does not exist."
5858
  msgstr "Le journal demandé n'existe pas."
5859
 
5860
- #: lib/logs_firewall_log.php:290
5861
  msgid "Unable to open the log for read operation."
5862
  msgstr "Impossible de lire le journal."
5863
 
@@ -5989,7 +5999,7 @@ msgstr "Sauvegarder les options"
5989
  msgid "Error: please enter the custom log format."
5990
  msgstr "Erreur : veuillez entrer le format d'affichage."
5991
 
5992
- #: lib/monitoring.php:43 ninjafirewall.php:904
5993
  msgid "Monitoring"
5994
  msgstr "Monitoring"
5995
 
@@ -6394,7 +6404,7 @@ msgstr ""
6394
  msgid "Save File Guard options"
6395
  msgstr "Sauvegarder les options"
6396
 
6397
- #: lib/network.php:24 ninjafirewall.php:1191 ninjafirewall.php:1195
6398
  #, php-format
6399
  msgid "You are not allowed to perform this task (%s)."
6400
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche (%s)."
@@ -6426,7 +6436,7 @@ msgid "Scheduled task has stopped, restarting it (%s)"
6426
  msgstr "La tâche planifiée s'est arrêtée, redémarrage en cours (%s)"
6427
 
6428
  #: lib/security_rules.php:44 lib/security_rules_update.php:565
6429
- #: ninjafirewall.php:934
6430
  msgid "Security Rules"
6431
  msgstr "Règles de Sécurité"
6432
 
@@ -6720,6 +6730,20 @@ msgstr "Fermer"
6720
 
6721
  #: lib/thickbox.php:79
6722
  msgid ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6723
  "In Full WAF mode, all scripts located inside the blog installation "
6724
  "directories and sub-directories are protected by NinjaFirewall. It gives you "
6725
  "the highest possible level of protection: security without compromise."
@@ -6729,7 +6753,7 @@ msgstr ""
6729
  "Cela vous offre le niveau de protection le plus élevé possible : La sécurité "
6730
  "sans aucun compromis."
6731
 
6732
- #: lib/thickbox.php:81
6733
  #, php-format
6734
  msgid ""
6735
  "It works on most websites right out of the box, or may require %ssome very "
@@ -6741,7 +6765,7 @@ msgstr ""
6741
  "principalement en raison de certaines restrictions d'hébergement partagé, il "
6742
  "se peut que l'installation ne puisse pas fonctionner du tout."
6743
 
6744
- #: lib/thickbox.php:83
6745
  msgid ""
6746
  "If this happened to you, don't worry: you could still run it in WordPress "
6747
  "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
@@ -6752,33 +6776,33 @@ msgstr ""
6752
  "tout de même des performances et un niveau de protection très supérieur aux "
6753
  "autres extensions de sécurité pour WordPress disponibles sur le marché."
6754
 
6755
- #: lib/thickbox.php:157
6756
  msgid "Select your HTTP server and your PHP server API"
6757
  msgstr "Sélectionnez votre serveur HTTP et PHP SAPI"
6758
 
6759
- #: lib/thickbox.php:168
6760
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
6761
  msgstr "Autre serveur + CGI/FastCGI ou PHP-FPM"
6762
 
6763
- #: lib/thickbox.php:170
6764
  msgid "View PHPINFO"
6765
  msgstr "Voir PHPINFO"
6766
 
6767
- #: lib/thickbox.php:202
6768
  msgid "Select the PHP initialization file supported by your server"
6769
  msgstr ""
6770
  "Sélectionnez le type de fichier de configuration PHP utilisé par votre "
6771
  "serveur"
6772
 
6773
- #: lib/thickbox.php:213
6774
  msgid "Folders protected by NinjaFirewall"
6775
  msgstr "Répertoires protégés par NinjaFirewall"
6776
 
6777
- #: lib/thickbox.php:215 lib/thickbox.php:362
6778
  msgid "WordPress root directory:"
6779
  msgstr "Répertoire racine de WordPress :"
6780
 
6781
- #: lib/thickbox.php:220 lib/thickbox.php:367
6782
  msgid ""
6783
  "The following folders will be protected by NinjaFirewall. If you want to "
6784
  "exclude some of them, uncheck them in the list below:"
@@ -6786,7 +6810,7 @@ msgstr ""
6786
  "Les dossiers suivants seront protégés par NinjaFirewall. Si vous souhaitez "
6787
  "en exclure certains, décochez-les dans la liste ci-dessous :"
6788
 
6789
- #: lib/thickbox.php:226
6790
  msgid ""
6791
  "After setting up the Full WAF mode, you could come back to this page to re-"
6792
  "configure it whenever you want."
@@ -6794,15 +6818,15 @@ msgstr ""
6794
  "Après avoir configuré le mode Full WAF, vous pourrez revenir sur cette page "
6795
  "pour le reconfigurer quand vous le souhaitez."
6796
 
6797
- #: lib/thickbox.php:234
6798
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
6799
  msgstr "Laissez NinjaFirewall faire les changements (recommandé)."
6800
 
6801
- #: lib/thickbox.php:236
6802
  msgid "I want to make the changes myself."
6803
  msgstr "Je veux faire les changements moi-même."
6804
 
6805
- #: lib/thickbox.php:238
6806
  msgid ""
6807
  "Please make the changes below, then click on the \"Finish Installation\" "
6808
  "button."
@@ -6810,7 +6834,7 @@ msgstr ""
6810
  "Veuillez faire les modifications ci-dessous, puis cliquer sur le bouton "
6811
  "\"Finaliser l'installation\"."
6812
 
6813
- #: lib/thickbox.php:245
6814
  #, php-format
6815
  msgid ""
6816
  "The %s file must be created, and the following lines of code added to it:"
@@ -6818,12 +6842,12 @@ msgstr ""
6818
  "Le fichier %s doit être créé, et les lignes suivantes doivent y être "
6819
  "ajoutées :"
6820
 
6821
- #: lib/thickbox.php:246
6822
  #, php-format
6823
  msgid "The following lines of code must be added to your existing %s file:"
6824
  msgstr "Les lignes suivantes doivent être ajoutées à votre fichier %s :"
6825
 
6826
- #: lib/thickbox.php:314
6827
  msgid ""
6828
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
6829
  "select your domain, add the following instructions to the \"php.ini Override"
@@ -6834,7 +6858,7 @@ msgstr ""
6834
  "section \"php.ini Override\" de l'onglet \"Général\", puis redémarrez "
6835
  "Openlitespeed:"
6836
 
6837
- #: lib/thickbox.php:321
6838
  msgid ""
6839
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
6840
  "to remove these instructions from your Openlitespeed admin dashboard "
@@ -6846,11 +6870,11 @@ msgstr ""
6846
  "<strong>avant</strong> de désinstaller NinjaFirewall, car cet installateur "
6847
  "ne pourra pas le faire à votre place."
6848
 
6849
- #: lib/thickbox.php:337
6850
  msgid "Enable the sandbox."
6851
  msgstr "Activer l'environnement de test (sandbox)."
6852
 
6853
- #: lib/thickbox.php:337
6854
  msgid ""
6855
  "If there were a problem during the installation, NinjaFirewall would undo "
6856
  "those changes automatically for you."
@@ -6858,27 +6882,27 @@ msgstr ""
6858
  "S'il y avait un problème lors de l'installation, NinjaFirewall annulerait "
6859
  "ces modifications automatiquement pour vous."
6860
 
6861
- #: lib/thickbox.php:338
6862
  msgid "Finish Installation"
6863
  msgstr "Finaliser l'installation"
6864
 
6865
- #: lib/thickbox.php:356
6866
  msgid "Configuration"
6867
  msgstr "Configuration"
6868
 
6869
- #: lib/thickbox.php:360
6870
  msgid "Full WAF mode"
6871
  msgstr "Mode Full WAF"
6872
 
6873
- #: lib/thickbox.php:374
6874
  msgid "Save Changes"
6875
  msgstr "Sauvegarder les modifications"
6876
 
6877
- #: lib/thickbox.php:385
6878
  msgid "WordPress WAF mode"
6879
  msgstr "Mode WordPress WAF"
6880
 
6881
- #: lib/thickbox.php:392
6882
  msgid ""
6883
  "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
6884
  "admin dashboard, click on \"Virtual Host\", select your domain and remove "
@@ -6890,27 +6914,27 @@ msgstr ""
6890
  "votre domaine, enlevez la directive \"auto_prepend_file\" de la section "
6891
  "\"php.ini Override\" de l'onglet \"Général\", puis redémarrez Openlitespeed."
6892
 
6893
- #: lib/thickbox.php:393 lib/thickbox.php:400
6894
  msgid "Downgrade to WordPress WAF mode"
6895
  msgstr "Revenir au mode WordPress WAF"
6896
 
6897
- #: lib/thickbox.php:397
6898
  msgid "If you want to downgrade to WordPress WAF mode, click the button below."
6899
  msgstr ""
6900
  "Si vous souhaitez revenir au mode WordPress WAF, cliquez sur le bouton ci-"
6901
  "dessous."
6902
 
6903
- #: lib/thickbox.php:402
6904
  msgid "You may have to wait five minutes for the changes to take effect."
6905
  msgstr ""
6906
  "Vous devrez peut-être attendre cinq minutes pour que les modifications "
6907
  "prennent effet."
6908
 
6909
- #: lib/thickbox.php:409
6910
  msgid "Cancel and Close"
6911
  msgstr "Annuler et Fermer"
6912
 
6913
- #: lib/utils.php:188 lib/utils.php:196 lib/utils.php:295
6914
  msgid "N/A"
6915
  msgstr "N/A"
6916
 
@@ -6924,7 +6948,7 @@ msgstr "Tentative de création de %s"
6924
  msgid "Attempt to edit a published %s (ID: %s)"
6925
  msgstr "Tentative de modification de %s (ID: %s)"
6926
 
6927
- #: lib/utils.php:212 lib/utils.php:287
6928
  msgid "Unauthenticated user"
6929
  msgstr "Utilisateur non authentifié"
6930
 
@@ -6940,7 +6964,7 @@ msgstr ""
6940
  "NinjaFirewall a bloqué une tentative de modification/création d'une page ou "
6941
  "d'un article par un utilisateur qui n'avait pas les capacités nécessaires :"
6942
 
6943
- #: lib/utils.php:226 lib/utils.php:307 lib/utils.php:426 lib/utils.php:1216
6944
  msgid "Username:"
6945
  msgstr "Utilisateur :"
6946
 
@@ -6948,13 +6972,13 @@ msgstr "Utilisateur :"
6948
  msgid "Action:"
6949
  msgstr "Action :"
6950
 
6951
- #: lib/utils.php:242 lib/utils.php:322 lib/utils.php:439 lib/utils.php:1232
6952
- #: lib/utils.php:1480
6953
  msgid "A PHP backtrace has been attached to this message for your convenience."
6954
  msgstr ""
6955
  "La pile d'exécution de PHP est jointe à ce message pour votre commodité."
6956
 
6957
- #: lib/utils.php:244 lib/utils.php:324 lib/utils.php:1234 lib/utils.php:1490
6958
  msgid ""
6959
  "This protection (and notification) can be turned off from NinjaFirewall "
6960
  "\"Firewall Policies\" page."
@@ -6962,16 +6986,16 @@ msgstr ""
6962
  "Cette protection (et notification) peut être désactivée à partir de la page "
6963
  "\"Politiques du Pare-feu\" de NinjaFirewall."
6964
 
6965
- #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:339 lib/utils.php:340
6966
- #: lib/utils.php:456 lib/utils.php:457 lib/utils.php:1250 lib/utils.php:1251
6967
  msgid "You are not allowed to perform this task."
6968
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche."
6969
 
6970
- #: lib/utils.php:298
6971
  msgid "Blocked post/page deletion attempt"
6972
  msgstr "Tentative de suppression de page/article bloquée"
6973
 
6974
- #: lib/utils.php:305
6975
  msgid ""
6976
  "NinjaFirewall has blocked an attempt to delete a post by a user who doesn't "
6977
  "have the right capabilities:"
@@ -6979,21 +7003,21 @@ msgstr ""
6979
  "NinjaFirewall a bloqué une tentative de suppression d'une page ou d'un "
6980
  "article par un utilisateur qui n'avait pas les capacités nécessaires :"
6981
 
6982
- #: lib/utils.php:416
6983
  msgid "Blocked user account creation"
6984
  msgstr "Création de compte d'utilisateur bloquée"
6985
 
6986
- #: lib/utils.php:423
6987
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
6988
  msgstr ""
6989
  "NinjaFirewall a bloqué une tentative de création d'un compte d'utilisateur :"
6990
 
6991
- #: lib/utils.php:521
6992
  #, php-format
6993
  msgid "Backup file is corrupted, deleting it (%s)"
6994
  msgstr "Le fichier de sauvegarde est corrompu, suppression en cours (%s)"
6995
 
6996
- #: lib/utils.php:529
6997
  #, php-format
6998
  msgid ""
6999
  "NinjaFirewall's options are corrupted, restoring them from last known good "
@@ -7002,7 +7026,7 @@ msgstr ""
7002
  "Les options de NinjaFirewall sont corrompues, tentative de restauration à "
7003
  "partir du dernier fichier de sauvegarde connu (%s)"
7004
 
7005
- #: lib/utils.php:535
7006
  msgid ""
7007
  "NinjaFirewall's options are corrupted, restoring their default values (no "
7008
  "valid backup found)"
@@ -7010,7 +7034,7 @@ msgstr ""
7010
  "Les options de NinjaFirewall sont corrompues, restauration des valeurs par "
7011
  "défaut (il n'existe pas de fichier de sauvegarde)"
7012
 
7013
- #: lib/utils.php:718
7014
  msgid ""
7015
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
7016
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
@@ -7021,11 +7045,11 @@ msgstr ""
7021
  "concernant le test de la requête de bouclage (ex.: code d’état HTTP 404 ou "
7022
  "401). Vous pouvez l'ignorer en toute sécurité."
7023
 
7024
- #: lib/utils.php:741 lib/utils.php:745
7025
  msgid "NinjaFirewall error"
7026
  msgstr "NinjaFirewall Erreur"
7027
 
7028
- #: lib/utils.php:742
7029
  #, php-format
7030
  msgid ""
7031
  "%s directory cannot be created. Please review your installation and ensure "
@@ -7034,7 +7058,7 @@ msgstr ""
7034
  "Le répertoire %s ne peut pas être créé. Vérifiez votre installation et "
7035
  "assurez vous que %s n'est pas en lecture seule."
7036
 
7037
- #: lib/utils.php:746
7038
  #, php-format
7039
  msgid ""
7040
  "%s directory is read-only. Please review your installation and ensure that "
@@ -7043,31 +7067,31 @@ msgstr ""
7043
  "Le répertoire %s est en lecture seule. Vérifiez votre installation et les "
7044
  "permissions de %s."
7045
 
7046
- #: lib/utils.php:761
7047
  msgid "unknown error"
7048
  msgstr "erreur inconnue"
7049
 
7050
- #: lib/utils.php:763
7051
  msgid "NinjaFirewall fatal error:"
7052
  msgstr "NinjaFirewall erreur fatale :"
7053
 
7054
- #: lib/utils.php:764
7055
  msgid "Review your installation, your site is not protected."
7056
  msgstr "Vérifiez votre installation, votre site n'est pas protégé."
7057
 
7058
- #: lib/utils.php:785
7059
  msgid "Alert: WordPress console login"
7060
  msgstr "Alerte : Connexion à WordPress"
7061
 
7062
- #: lib/utils.php:791
7063
  msgid "Someone just logged in to your WordPress admin console:"
7064
  msgstr "Quelqu'un vient de se connecter à votre Tableau de bord de WordPress:"
7065
 
7066
- #: lib/utils.php:910 lib/utils.php:937
7067
  msgid "Forbidden access"
7068
  msgstr "Accès interdit"
7069
 
7070
- #: lib/utils.php:956
7071
  #, php-format
7072
  msgid ""
7073
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
@@ -7076,11 +7100,11 @@ msgstr ""
7076
  "<strong>ERREUR</strong>: Identifiant, email ou mot de passe invalide.<br /"
7077
  "><a href=\"%s\">Mot de passe perdu</a> ?"
7078
 
7079
- #: lib/utils.php:1034
7080
  msgid "[NinjaFirewall] Alert: Database changes detected"
7081
  msgstr "[NinjaFirewall] Alerte: Modification dans la base de données"
7082
 
7083
- #: lib/utils.php:1035
7084
  msgid ""
7085
  "NinjaFirewall has detected that one or more administrator accounts were "
7086
  "modified in the database:"
@@ -7088,12 +7112,12 @@ msgstr ""
7088
  "NinjaFirewall a détecté que un ou plusieurs comptes d'administrateur ont été "
7089
  "modifiés dans la base de données:"
7090
 
7091
- #: lib/utils.php:1040
7092
  #, php-format
7093
  msgid "Total administrators : %s"
7094
  msgstr "Nombre d'administrateurs : %s"
7095
 
7096
- #: lib/utils.php:1049
7097
  msgid ""
7098
  "If you cannot see any modifications in the above fields, it is possible that "
7099
  "the administrator password was changed."
@@ -7101,11 +7125,11 @@ msgstr ""
7101
  "Si vous ne voyez pas de modifications dans les données ci-dessus, il est "
7102
  "possible que le mot de passe administrateur ait été changé."
7103
 
7104
- #: lib/utils.php:1202
7105
  msgid "Blocked privilege escalation attempt"
7106
  msgstr "Tentatives d'élévation des privilèges"
7107
 
7108
- #: lib/utils.php:1210
7109
  msgid ""
7110
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
7111
  "who does not have administrative privileges:"
@@ -7113,7 +7137,7 @@ msgstr ""
7113
  "NinjaFirewall a bloqué une tentative de modification de certaines Capacités "
7114
  "par un utilisateur ne disposant pas de privilèges administratifs :"
7115
 
7116
- #: lib/utils.php:1262
7117
  msgid ""
7118
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
7119
  "whitelisted."
@@ -7121,7 +7145,7 @@ msgstr ""
7121
  "La protection de NinjaFirewall contre les attaques par force brute est "
7122
  "activée. Vous êtes temporairement dans la liste blanche."
7123
 
7124
- #: lib/utils.php:1277
7125
  #, php-format
7126
  msgid ""
7127
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
@@ -7134,17 +7158,17 @@ msgstr ""
7134
  "a>. Il a fallu des milliers d'heures pour le développer, mais il suffit "
7135
  "seulement de quelques minutes pour le noter. Merci !"
7136
 
7137
- #: lib/utils.php:1452
7138
  msgid ""
7139
  "The attempt was blocked and the option was reversed to its original value."
7140
  msgstr ""
7141
  "La tentative a été bloquée et l'option a été remise à sa valeur d'origine."
7142
 
7143
- #: lib/utils.php:1457
7144
  msgid "Attempt to modify WordPress settings"
7145
  msgstr "Tentative de modification des paramètres de WordPress"
7146
 
7147
- #: lib/utils.php:1458
7148
  msgid ""
7149
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
7150
  "settings by a user that does not have administrative privileges:"
@@ -7153,31 +7177,31 @@ msgstr ""
7153
  "importants de WordPress par un utilisateur ne disposant pas de privilèges "
7154
  "administratifs :"
7155
 
7156
- #: lib/utils.php:1459 lib/utils.php:1468
7157
  #, php-format
7158
  msgid "Option: %s"
7159
  msgstr "Option: %s"
7160
 
7161
- #: lib/utils.php:1460
7162
  #, php-format
7163
  msgid "Original value: %s"
7164
  msgstr "Valeur originale : %s"
7165
 
7166
- #: lib/utils.php:1461
7167
  #, php-format
7168
  msgid "Modified value: %s"
7169
  msgstr "Valeur modifiée : %s"
7170
 
7171
- #: lib/utils.php:1462 lib/utils.php:1470
7172
  #, php-format
7173
  msgid "Action taken: %s"
7174
  msgstr "Action prise : %s"
7175
 
7176
- #: lib/utils.php:1466
7177
  msgid "Code injection attempt in WordPress options table"
7178
  msgstr "Tentative d'injection de code dans la table des options de WordPress"
7179
 
7180
- #: lib/utils.php:1467
7181
  msgid ""
7182
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
7183
  "table by a user that does not have administrative privileges:"
@@ -7186,28 +7210,28 @@ msgstr ""
7186
  "options de WordPress par un utilisateur ne disposant pas de privilèges "
7187
  "administratifs :"
7188
 
7189
- #: lib/utils.php:1469
7190
  #, php-format
7191
  msgid "Code: %s"
7192
  msgstr "Code : %s"
7193
 
7194
- #: lib/utils.php:1565
7195
  msgid "Important: NinjaFirewall has detected that this is a security update."
7196
  msgstr ""
7197
  "Important : NinjaFirewall a détecté que ceci est un mise à jour de sécurité."
7198
 
7199
- #: lib/utils.php:1568
7200
  msgid "More info about this warning."
7201
  msgstr "En savoir plus."
7202
 
7203
- #: lib/utils.php:1591
7204
  #, php-format
7205
  msgid "Cannot send notification, no valid email found (%s)"
7206
  msgstr ""
7207
  "Impossible d'envoyer la notification, aucune adresse e-mail valide n'a été "
7208
  "trouvée (%s)"
7209
 
7210
- #: lib/utils.php:1616
7211
  #, php-format
7212
  msgid ""
7213
  "If you don't have access to that site any longer, you can remove your email "
@@ -7216,21 +7240,21 @@ msgstr ""
7216
  "Si vous n'avez plus accès à ce site, vous pouvez supprimer votre e-mail en "
7217
  "cliquant sur le lien suivant (valide pendant 12 heures) : %s"
7218
 
7219
- #: lib/utils.php:1642
7220
  #, php-format
7221
  msgid "Error, cannot create the %s folder."
7222
  msgstr "Erreur, impossible de créer le répertoire %s."
7223
 
7224
- #: lib/utils.php:1643 lib/utils.php:1652 lib/utils.php:1661
7225
  msgid "Check your server permissions and try again."
7226
  msgstr "Vérifiez les autorisations de votre serveur et réessayez."
7227
 
7228
- #: lib/utils.php:1651
7229
  #, php-format
7230
  msgid "Error, the %s folder is not writable."
7231
  msgstr "Erreur, le répertoire %s est en lecture seule."
7232
 
7233
- #: lib/utils.php:1660
7234
  #, php-format
7235
  msgid "Error, cannot write %s."
7236
  msgstr "Erreur, impossible d'écrire dans %s."
@@ -7259,23 +7283,23 @@ msgstr "Afficher les statistiques"
7259
  msgid "View firewall log"
7260
  msgstr "Voir le journal du pare-feu"
7261
 
7262
- #: lib/widget.php:134
7263
- msgid "Latest Security News"
7264
- msgstr "Dernières Articles sur la Sécurité"
7265
 
7266
- #: lib/widget.php:138
7267
  msgid "M jS, Y"
7268
  msgstr "M jS, Y"
7269
 
7270
- #: lib/widget.php:149
7271
  msgid "More Security News"
7272
  msgstr "Autres Articles sur la Sécurité"
7273
 
7274
- #: lib/widget.php:149
7275
  msgid "(opens in a new tab)"
7276
  msgstr ""
7277
 
7278
- #: lib/widget.php:149
7279
  msgid "NinjaFirewall's Home"
7280
  msgstr "Site de NinjaFirewall"
7281
 
@@ -7929,85 +7953,99 @@ msgstr ""
7929
  msgid "Error: The HTTP server returned the following error code:"
7930
  msgstr "Erreur : Le serveur HTTP a retourné le code d'erreur suivant :"
7931
 
7932
- #: ninjafirewall.php:641 ninjafirewall.php:761 ninjafirewall.php:830
7933
  msgid "Error: Security nonces do not match. Reload the page and try again."
7934
  msgstr ""
7935
  "Erreur : Les nonces de sécurité ne correspondent pas. Veuillez recharger "
7936
  "cette page."
7937
 
7938
- #: ninjafirewall.php:647
7939
  msgid "Error: NinjaFirewall is disabled"
7940
  msgstr "Erreur : NinjaFirewall est désactivé"
7941
 
7942
- #: ninjafirewall.php:652 ninjafirewall.php:766 ninjafirewall.php:796
7943
  #, php-format
7944
  msgid "Error: missing parameter (%s)."
7945
  msgstr "Erreur : Paramètre manquant (%s)."
7946
 
7947
- #: ninjafirewall.php:892
7948
  msgid "NinjaFirewall: Dashboard"
7949
  msgstr "NinjaFirewall : Tableau de Bord"
7950
 
7951
- #: ninjafirewall.php:896
7952
  msgid "NinjaFirewall: Firewall Options"
7953
  msgstr "NinjaFirewall : Options du Pare-feu"
7954
 
7955
- #: ninjafirewall.php:900
7956
  msgid "NinjaFirewall: Firewall Policies"
7957
  msgstr "NinjaFirewall : Politiques du Pare-feu"
7958
 
7959
- #: ninjafirewall.php:904
7960
  msgid "NinjaFirewall: Monitoring"
7961
  msgstr "NinjaFirewall : Monitoring"
7962
 
7963
- #: ninjafirewall.php:914
7964
  msgid "NinjaFirewall: Anti-Malware"
7965
  msgstr "NinjaFirewall : Anti-Malware"
7966
 
7967
- #: ninjafirewall.php:918
7968
  msgid "NinjaFirewall: Network"
7969
  msgstr "NinjaFirewall : Réseau"
7970
 
7971
- #: ninjafirewall.php:922
7972
  msgid "NinjaFirewall: Event Notifications"
7973
  msgstr "NinjaFirewall : Notifications d’Événement"
7974
 
7975
- #: ninjafirewall.php:926
7976
  msgid "NinjaFirewall: Log-in Protection"
7977
  msgstr "NinjaFirewall : Page de Connexion"
7978
 
7979
- #: ninjafirewall.php:930
7980
  msgid "NinjaFirewall: Logs"
7981
  msgstr "NinjaFirewall : Journaux"
7982
 
7983
- #: ninjafirewall.php:934
7984
  msgid "NinjaFirewall: Security Rules"
7985
  msgstr "NinjaFirewall : Règles de Sécurité"
7986
 
7987
- #: ninjafirewall.php:978
7988
  msgid "NinjaFirewall Settings"
7989
  msgstr "Réglages de NinjaFirewall"
7990
 
7991
- #: ninjafirewall.php:986
7992
  msgid "NinjaFirewall is enabled"
7993
  msgstr "NinjaFirewall est activé"
7994
 
7995
- #: ninjafirewall.php:1126
7996
  msgid "Access Restricted"
7997
  msgstr "Accès limité"
7998
 
7999
- #: ninjafirewall.php:1132
8000
  msgid "Settings"
8001
  msgstr "Réglages"
8002
 
8003
- #: ninjafirewall.php:1133
8004
  msgid "Upgrade to Premium"
8005
  msgstr "Passez Premium !"
8006
 
8007
- #: ninjafirewall.php:1134
8008
  msgid "Rate it!"
8009
  msgstr "Notez-le !"
8010
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8011
  #~ msgid ""
8012
  #~ "In the Premium version of NinjaFirewall, the Access Control section "
8013
  #~ "allows you to whitelist WordPress users depending on their roles."
4
  msgstr ""
5
  "Project-Id-Version: Stable (latest release)\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ninjafirewall\n"
7
+ "POT-Creation-Date: 2022-02-03 17:19+0700\n"
8
+ "PO-Revision-Date: 2022-02-03 17:21+0700\n"
9
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
10
  "Language-Team: NinTechNet <nintechnet.com>\n"
11
  "Language: fr_FR\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
18
 
19
+ #: lib/anti_malware.php:24 ninjafirewall.php:909
20
  msgid "Anti-Malware"
21
  msgstr "Anti-Malware"
22
 
113
  msgid "Your changes have been saved."
114
  msgstr "Les modifications ont été enregistrées."
115
 
116
+ #: lib/dashboard.php:132 ninjafirewall.php:887
117
  msgid "Dashboard"
118
  msgstr "Tableau de Bord"
119
 
463
  msgid "Help &amp; configuration"
464
  msgstr "Aide &amp; configuration"
465
 
 
 
 
 
 
 
466
  #: lib/dashboard_about.php:29
467
  msgid "Our blog:"
468
  msgstr "Notre blog :"
483
  msgid "Rate it on WordPress.org!"
484
  msgstr "Notez-le sur WordPress.org !"
485
 
 
 
 
 
486
  #: lib/dashboard_statistics.php:76
487
  msgid "You do not have any stats for the selected month yet."
488
  msgstr "Vous n'avez pas de statistiques pour le mois sélectionné."
573
  #: lib/email_sodium.php:169 lib/monitoring_file_check.php:759
574
  #: lib/monitoring_file_check.php:761 lib/monitoring_file_check.php:781
575
  #: lib/monitoring_file_check.php:783 lib/security_rules_update.php:559
576
+ #: lib/security_rules_update.php:561 lib/utils.php:225 lib/utils.php:305
577
+ #: lib/utils.php:423 lib/utils.php:1077 lib/utils.php:1251 lib/utils.php:1522
578
  msgid "Blog:"
579
  msgstr "Blog :"
580
 
582
  msgid "Email address:"
583
  msgstr "Adresse e-mail :"
584
 
585
+ #: lib/email_sodium.php:171 lib/utils.php:230 lib/utils.php:309
586
+ #: lib/utils.php:425 lib/utils.php:1259 lib/utils.php:1523
587
  msgid "User IP:"
588
  msgstr "IP utilisateur :"
589
 
590
  #: lib/email_sodium.php:172 lib/event_updates.php:157 lib/utils.php:233
591
+ #: lib/utils.php:312 lib/utils.php:428 lib/utils.php:1078 lib/utils.php:1262
592
+ #: lib/utils.php:1526
593
  msgid "Date:"
594
  msgstr "Date :"
595
 
623
  msgid "No"
624
  msgstr "Non"
625
 
626
+ #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:917
627
  msgid "Event Notifications"
628
  msgstr "Notifications d'Événement"
629
 
815
  msgid "Save Event Notifications"
816
  msgstr "Sauvegarder les options"
817
 
818
+ #: lib/event_notifications.php:484
819
  msgid "[NinjaFirewall] Daily Activity Report"
820
  msgstr "[NinjaFirewall] Rapport d'activité quotidien"
821
 
822
+ #: lib/event_notifications.php:494
823
  #, php-format
824
  msgid "Daily activity report for: %s"
825
  msgstr "Rapport d'activité quotidien pour : %s"
826
 
827
+ #: lib/event_notifications.php:495
828
  msgid "Date Range Processed: Yesterday"
829
  msgstr "Plage de date traitée : Hier"
830
 
831
+ #: lib/event_notifications.php:497
832
  msgid "Blocked threats:"
833
  msgstr "Menaces bloquées :"
834
 
835
+ #: lib/event_notifications.php:499
836
  msgid "critical:"
837
  msgstr "Critique :"
838
 
839
+ #: lib/event_notifications.php:500
840
  msgid "high:"
841
  msgstr "Élevé :"
842
 
843
+ #: lib/event_notifications.php:501
844
  msgid "medium:"
845
  msgstr "Moyen :"
846
 
847
+ #: lib/event_notifications.php:503
848
  msgid "Blocked brute-force attacks:"
849
  msgstr "Attaques par force brute bloquées :"
850
 
851
+ #: lib/event_notifications.php:504 lib/event_updates.php:219 lib/utils.php:1089
852
  msgid ""
853
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
854
  "\" page."
914
  msgid "Theme: %s"
915
  msgstr "Theme : %s"
916
 
917
+ #: lib/event_updates.php:217 lib/utils.php:1608
918
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
919
  msgstr ""
920
  "Ne laissez pas votre blog en danger, lancez cette mise à jour dès que "
950
  msgid "activated"
951
  msgstr "activé(e)"
952
 
953
+ #: lib/events.php:45 lib/events.php:93 lib/events.php:175 lib/events.php:187
954
  msgid "deleted"
955
  msgstr "supprimé(e)"
956
 
957
  #: lib/events.php:81 lib/events.php:103 lib/events.php:118 lib/events.php:122
958
+ #: lib/events.php:140 lib/events.php:149 lib/events.php:171 lib/events.php:183
959
  msgid "updated"
960
  msgstr "mis(e) à jour"
961
 
963
  msgid "deactivated"
964
  msgstr "désactivé(e)"
965
 
966
+ #: lib/events.php:130 lib/events.php:153 lib/events.php:167 lib/events.php:179
967
  msgid "installed"
968
  msgstr "installé(e)"
969
 
970
+ #: lib/events.php:135 lib/events.php:157
971
  msgid "uploaded"
972
  msgstr "téléchargé(e)"
973
 
974
+ #: lib/events.php:197
975
  #, php-format
976
  msgid "[NinjaFirewall] Alert: %s"
977
  msgstr "[NinjaFirewall] Alerte : %s"
978
 
979
+ #: lib/events.php:199 lib/events.php:201 lib/utils.php:827
980
  msgid "-Blog:"
981
  msgstr "- Blog :"
982
 
983
+ #: lib/events.php:204
984
  msgid "NinjaFirewall has detected the following activity on your account:"
985
  msgstr "NinjaFirewall a détecté l'activité suivante sur votre compte :"
986
 
987
+ #: lib/events.php:206 lib/utils.php:832
988
  msgid "-User:"
989
  msgstr "- Nom :"
990
 
991
+ #: lib/events.php:207 lib/utils.php:833
992
  msgid "-IP:"
993
  msgstr "- IP :"
994
 
995
+ #: lib/events.php:208 lib/utils.php:834
996
  msgid "-Date:"
997
  msgstr "-Date :"
998
 
999
+ #: lib/firewall_options.php:29 ninjafirewall.php:891
1000
  msgid "Firewall Options"
1001
  msgstr "Options du Pare-feu"
1002
 
1211
  "Pour utiliser cette option, allez dans le <a href=\"%s\">Tableau de Bord</a> "
1212
  "et activez le mode Full WAF de NinjaFirewall."
1213
 
1214
+ #: lib/firewall_policies.php:62 ninjafirewall.php:895
1215
  msgid "Firewall Policies"
1216
  msgstr "Politiques du Pare-feu"
1217
 
1371
  "Bloquer les tentatives de publication, modification ou suppression d'un "
1372
  "article publié par des utilisateurs qui n'ont pas les bonnes capacités"
1373
 
1374
+ #: lib/firewall_policies.php:411 lib/thickbox.php:95
1375
  msgid "(recommended)"
1376
  msgstr "(recommandé)"
1377
 
1776
  msgid "Set %s (Chrome, Opera and Firefox browsers)"
1777
  msgstr "Activer %s (Chrome, Opera et Firefox)"
1778
 
1779
+ #: lib/firewall_policies.php:992
1780
+ msgid "Custom HTTP headers"
1781
+ msgstr "En-têtes HTTP personnalisés"
1782
+
1783
+ #: lib/firewall_policies.php:995
1784
+ msgid ""
1785
+ "You can enter one or more custom HTTP headers. The format is <code>header: "
1786
+ "value</code>, one per line."
1787
+ msgstr ""
1788
+ "Vous pouvez entrer un ou plusieurs en-têtes HTTP personnalisés. Le format "
1789
+ "est <code>en-tete: valeur</code>, un par ligne."
1790
+
1791
+ #: lib/firewall_policies.php:1000
1792
+ msgid "HTTP headers test"
1793
+ msgstr "Teste des en-têtes HTTP"
1794
+
1795
+ #: lib/firewall_policies.php:1002
1796
+ msgid "View your website's HTTP response headers"
1797
+ msgstr "Visualiser les en-têtes HTTP de votre site"
1798
+
1799
+ #: lib/firewall_policies.php:1005
1800
+ msgid "Make sure to save your changes before running the test."
1801
+ msgstr "Assurez-vous d'enregistrer vos modifications avant d'exécuter le test."
1802
+
1803
+ #: lib/firewall_policies.php:1047
1804
  msgid ""
1805
  "Block PHP built-in wrappers in <code>GET</code>, <code>POST</code>, "
1806
  "<code>HTTP_USER_AGENT</code>, <code>HTTP_REFERER</code> and cookies"
1809
  "<code>GET</code>, <code>POST</code>, <code>HTTP_USER_AGENT</code>, "
1810
  "<code>HTTP_REFERER</code> et les cookies"
1811
 
1812
+ #: lib/firewall_policies.php:1086
1813
  msgid "Block serialized PHP objects in the following global variables"
1814
  msgstr ""
1815
  "Bloquer les objets PHP sérialisés dans les variables globales suivantes"
1816
 
1817
+ #: lib/firewall_policies.php:1096 lib/help.php:295
1818
  msgid "Block attempts to override PHP Superglobals"
1819
  msgstr "Bloquer les tentatives de modification des Superglobales PHP"
1820
 
1821
+ #: lib/firewall_policies.php:1102 lib/help.php:297
1822
  msgid "Hide PHP notice and error messages"
1823
  msgstr "Masquer les messages d'erreur de PHP"
1824
 
1825
+ #: lib/firewall_policies.php:1108
1826
  msgid "Sanitise <code>PHP_SELF</code>"
1827
  msgstr "Nettoyer <code>PHP_SELF</code>"
1828
 
1829
+ #: lib/firewall_policies.php:1114
1830
  msgid "Sanitise <code>PATH_TRANSLATED</code>"
1831
  msgstr "Nettoyer <code>PATH_TRANSLATED</code>"
1832
 
1833
+ #: lib/firewall_policies.php:1120
1834
  msgid "Sanitise <code>PATH_INFO</code>"
1835
  msgstr "Nettoyer <code>PATH_INFO</code>"
1836
 
1837
+ #: lib/firewall_policies.php:1134
1838
  msgid "This option is not compatible with your actual configuration."
1839
  msgstr ""
1840
  "Cette option n'est pas compatible avec la configuration de votre serveur."
1841
 
1842
+ #: lib/firewall_policies.php:1156 lib/help.php:301
1843
  msgid "Various"
1844
  msgstr "Divers"
1845
 
1846
+ #: lib/firewall_policies.php:1159
1847
  msgid "Block the <code>DOCUMENT_ROOT</code> server variable in HTTP request"
1848
  msgstr ""
1849
  "Bloquer les requêtes HTTP contenant la variable <code>DOCUMENT_ROOT</code>"
1850
 
1851
+ #: lib/firewall_policies.php:1166 lib/help.php:304
1852
  msgid "Block ASCII character 0x00 (NULL byte)"
1853
  msgstr "Bloquer le caractère ASCII 0x00 (NULL byte)"
1854
 
1855
+ #: lib/firewall_policies.php:1172 lib/help.php:306
1856
  msgid "Block ASCII control characters 1 to 8 and 14 to 31"
1857
  msgstr "Bloquer les caractères de contrôle ASCII 1 à 8 et 14 à 31"
1858
 
1859
+ #: lib/firewall_policies.php:1185
1860
  msgid "Save Firewall Policies"
1861
  msgstr "Sauvegarder les options"
1862
 
1863
+ #: lib/firewall_policies.php:1187
1864
  msgid "Restore Default Values"
1865
  msgstr "Rétablir les valeurs par défaut"
1866
 
2999
  "intercepter les requêtes HTTP envoyées à tout script PHP, même si ce dernier "
3000
  "ne fait pas partie de WordPress (logiciel tiers, backdoor, etc)."
3001
 
3002
+ #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:913
3003
  msgid "Network"
3004
  msgstr "Réseau"
3005
 
3052
  "après avoir pénétré dans votre Tableau de bord de WordPress, d'y installer "
3053
  "une porte dérobée (backdoor) afin de prendre le contrôle de votre blog."
3054
 
3055
+ #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:921
3056
  msgid "Login Protection"
3057
  msgstr "Page de Connexion"
3058
 
3656
  msgstr "NinjaFirewall : Anti-Spam"
3657
 
3658
  #: lib/i18n-extra.php:21
 
 
 
 
3659
  msgid "License"
3660
  msgstr "Licence"
3661
 
3662
+ #: lib/i18n-extra.php:22
3663
  msgid "Enter your NinjaFirewall WP+ license and click on the save button"
3664
  msgstr ""
3665
  "Entrez votre licence NinjaFirewall WP+ et cliquez sur le bouton pour la "
3666
  "valider"
3667
 
3668
+ #: lib/i18n-extra.php:23
3669
  msgid "Don't have a license yet?"
3670
  msgstr "Vous n'avez pas encore de licence ?"
3671
 
3672
+ #: lib/i18n-extra.php:24
3673
  msgid "Click here to get one"
3674
  msgstr "Cliquez ici pour en obtenir une"
3675
 
3676
+ #: lib/i18n-extra.php:25
3677
  msgid "Save License"
3678
  msgstr "Sauvegarder la Licence"
3679
 
3680
+ #: lib/i18n-extra.php:26
3681
  msgid "This license has expired and is no longer valid."
3682
  msgstr "Cette licence a expiré et n'est plus valide."
3683
 
3684
+ #: lib/i18n-extra.php:27
3685
  msgid "Your license is not valid"
3686
  msgstr "Votre licence n'est pas valide"
3687
 
3688
+ #: lib/i18n-extra.php:28
3689
  msgid ""
3690
  "An unknown error occurred while connecting to NinjaFirewall servers. Please "
3691
  "try again in a few minutes"
3693
  "Une erreur inconnue est survenue lors de la connexion aux serveurs de "
3694
  "NinjaFirewall. Veuillez essayer à nouveau dans quelques minutes"
3695
 
3696
+ #: lib/i18n-extra.php:29
3697
  msgid ""
3698
  "An error occurred while connecting to NinjaFirewall servers. Please try "
3699
  "again in a few minutes"
3701
  "Une erreur est survenue lors de la connexion aux serveurs de NinjaFirewall. "
3702
  "Veuillez essayer à nouveau dans quelques minutes"
3703
 
3704
+ #: lib/i18n-extra.php:30
3705
  msgid "Your NinaFirewall license has expired!"
3706
  msgstr "Votre licence NinjaFirewall a expiré !"
3707
 
3708
+ #: lib/i18n-extra.php:31
3709
  msgid "Click here to renew it"
3710
  msgstr "Cliquez ici pour la renouveler"
3711
 
3712
+ #: lib/i18n-extra.php:32
3713
  msgid "Your NinaFirewall license will expire soon!"
3714
  msgstr "Votre licence NinjaFirewall va bientôt expirer !"
3715
 
3716
+ #: lib/i18n-extra.php:33
3717
  msgid "You do not have a valid NinjaFirewall license"
3718
  msgstr "Vous n'avez pas de licence NinjaFirewall valide"
3719
 
3720
+ #: lib/i18n-extra.php:34
3721
  #, php-format
3722
  msgid ""
3723
  "The shared memory block seems corrupted. Try to reload this page to fix it "
3728
  "ou bien, si l'erreur persiste, essayez de <a href=\"%s\">désactiver "
3729
  "l'utilisation de la mémoire partagée</a>."
3730
 
3731
+ #: lib/i18n-extra.php:35
3732
  #, php-format
3733
  msgid "(RAM usage: %s bytes)"
3734
  msgstr "(mémoire utilisée : %s octets)"
3735
 
3736
+ #: lib/i18n-extra.php:36
3737
  #, php-format
3738
  msgid ""
3739
  "Unable to access/read the shared memory block. Try to reload this page or, "
3744
  "page ou bien, si l'erreur persiste, essayez de <a href=\"%s\">désactiver "
3745
  "l'utilisation de la mémoire partagée</a>."
3746
 
3747
+ #: lib/i18n-extra.php:37
3748
  msgid "Firewall is disabled"
3749
  msgstr "Le pare-feu est désactivé"
3750
 
3751
+ #: lib/i18n-extra.php:38
3752
  msgid "Shared memory"
3753
  msgstr "Mémoire partagée"
3754
 
3755
+ #: lib/i18n-extra.php:39
3756
  #, php-format
3757
  msgid ""
3758
  "You are not whitelisted. Ensure that the \"Do not block the following users"
3765
  "a> est activée pour l'Administrateur/Super Admin, sinon vous pourriez être "
3766
  "bloqué par le pare-feu lorsque vous travaillez depuis votre Tableau de bord."
3767
 
3768
+ #: lib/i18n-extra.php:40
3769
  #, php-format
3770
  msgid ""
3771
  "<a href=\"%s\">Access Control Source IP</a> is setup to use %s, however your "
3775
  "votre serveur n'utilise pas cette variable. Toutes les directives basées sur "
3776
  "une adresse IP échoueront."
3777
 
3778
+ #: lib/i18n-extra.php:41
3779
  #, php-format
3780
  msgid "You have a private IP: %s"
3781
  msgstr "Vous avez l'adresse IP d'un réseau privé : %s"
3782
 
3783
+ #: lib/i18n-extra.php:42
3784
  #, php-format
3785
  msgid ""
3786
  "If your site is behind a reverse proxy or a load balancer, ensure that the "
3789
  "Si votre site est derrière un CDN ou reverse proxy, pensez à configurer "
3790
  "correctement l'option <a href=\"%s\">IP Source</a>."
3791
 
3792
+ #: lib/i18n-extra.php:43
3793
  #, php-format
3794
  msgid ""
3795
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that the "
3798
  "%s détecté : il semble que vous utilisez le service CDN Cloudflare. Assurez "
3799
  "vous d'avoir correctement configuré l'<a href=\"%s\">IP Source</a>."
3800
 
3801
+ #: lib/i18n-extra.php:44
3802
  #, php-format
3803
  msgid ""
3804
  "%s detected: you seem to be using Incapsula CDN services. Ensure that the <a "
3807
  "%s détecté : il semble que vous utilisez le service CDN Incapsula. Assurez "
3808
  "vous d'avoir correctement configuré l'<a href=\"%s\">IP Source</a>."
3809
 
3810
+ #: lib/i18n-extra.php:45
3811
  msgid "Logging"
3812
  msgstr "Journal du Pare-feu"
3813
 
3814
+ #: lib/i18n-extra.php:46
3815
  msgid "Logging is disabled."
3816
  msgstr "Le journal est désactivé."
3817
 
3818
+ #: lib/i18n-extra.php:47
3819
  msgid "Click here to re-enable it."
3820
  msgstr "Cliquez ici pour le réactiver."
3821
 
3822
+ #: lib/i18n-extra.php:48
3823
  #, php-format
3824
  msgid "Error cannot create the language files directory (%s)"
3825
  msgstr ""
3826
  "Erreur, impossible de créer le répertoire pour le fichier de langue (%s)"
3827
 
3828
+ #: lib/i18n-extra.php:49
3829
  #, php-format
3830
  msgid "Error while downloading language file %s (%s)"
3831
  msgstr "Erreur en essayant de télécharger le fichier de langue %s (%s)"
3832
 
3833
+ #: lib/i18n-extra.php:50
3834
  #, php-format
3835
  msgid ""
3836
  "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
3846
  "que cette option s'applique à tous les fichiers PHP, allez dans le %sTableau "
3847
  "de Bord%s et activez son mode Full WAF."
3848
 
3849
+ #: lib/i18n-extra.php:51
3850
  msgid "General"
3851
  msgstr "Général"
3852
 
3853
+ #: lib/i18n-extra.php:52
3854
  msgid "Geolocation"
3855
  msgstr "Géolocalisation"
3856
 
3857
+ #: lib/i18n-extra.php:53
3858
  msgid "IP address"
3859
  msgstr "Adresse IP"
3860
 
3861
+ #: lib/i18n-extra.php:54
3862
  msgid "URL address"
3863
  msgstr "Adresse URL"
3864
 
3865
+ #: lib/i18n-extra.php:55
3866
  msgid "Bot"
3867
  msgstr "Bot"
3868
 
3869
+ #: lib/i18n-extra.php:56
3870
  msgid "User Input"
3871
  msgstr "Entrée utilisateur"
3872
 
3873
+ #: lib/i18n-extra.php:57
3874
  msgid "Role-based Access Control"
3875
  msgstr "Contrôle d'Accès par Rôle"
3876
 
3877
+ #: lib/i18n-extra.php:58
3878
  msgid "Do not block the following users (must be logged in)"
3879
  msgstr "Ne pas bloquer les utilisateurs suivants"
3880
 
3881
+ #: lib/i18n-extra.php:59
3882
  msgid "Retrieve visitors IP address from"
3883
  msgstr "Récupérer l'adresse IP des visiteurs depuis"
3884
 
3885
+ #: lib/i18n-extra.php:60
3886
  msgid "Other"
3887
  msgstr "Autre"
3888
 
3889
+ #: lib/i18n-extra.php:61
3890
  #, php-format
3891
  msgid "Your server does not seem to support the %s variable."
3892
  msgstr "Votre serveur ne semble pas utiliser la variable %s."
3893
 
3894
+ #: lib/i18n-extra.php:62
3895
  msgid "HTTP Methods"
3896
  msgstr "Méthodes HTTP"
3897
 
3898
+ #: lib/i18n-extra.php:63
3899
  msgid "All Access Control directives should apply to the folowing HTTP methods"
3900
  msgstr ""
3901
  "Toutes les directives Contrôle d'accès s'appliquent aux méthodes HTTP "
3902
  "suivantes"
3903
 
3904
+ #: lib/i18n-extra.php:64
3905
  msgid "Enable Geolocation"
3906
  msgstr "Activer la Géolocalisation"
3907
 
3908
+ #: lib/i18n-extra.php:65
3909
  msgid "Retrieve the ISO 3166 code from"
3910
  msgstr "Récupérer le code ISO 3166 du pays depuis"
3911
 
3912
+ #: lib/i18n-extra.php:66
3913
  msgid "PHP Variable"
3914
  msgstr "Variable PHP"
3915
 
3916
+ #: lib/i18n-extra.php:67
3917
  msgid "Block the following ISO 3166 codes"
3918
  msgstr "Bloquer les codes ISO 3166 suivants"
3919
 
3920
+ #: lib/i18n-extra.php:68
3921
  #, php-format
3922
  msgid "Total blocked items: %s"
3923
  msgstr "Nombre d'éléments bloqués : %s"
3924
 
3925
+ #: lib/i18n-extra.php:69
3926
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3927
  msgstr ""
3928
  "S'il faut appliquer la Géolocalisation à tout le site ou à certains scripts "
3929
  "uniquement ?"
3930
 
3931
+ #: lib/i18n-extra.php:70
3932
  msgid "View allowed syntax"
3933
  msgstr "Afficher la syntaxe autorisée"
3934
 
3935
+ #: lib/i18n-extra.php:71
3936
  #, php-format
3937
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3938
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3939
 
3940
+ #: lib/i18n-extra.php:72
3941
  msgid "One item per line."
3942
  msgstr "Une entrée par ligne."
3943
 
3944
+ #: lib/i18n-extra.php:73
3945
  msgid ""
3946
  "Leave this field empty if you want geolocation to apply to all your PHP "
3947
  "scripts."
3948
  msgstr ""
3949
  "Laissez ce champ vide pour appliquer la géolocalisation à tout le site."
3950
 
3951
+ #: lib/i18n-extra.php:74
3952
  msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3953
  msgstr "Ajouter NINJA_COUNTRY_CODE aux en-têtes PHP ?"
3954
 
3955
+ #: lib/i18n-extra.php:75
3956
  msgid "Write event to the firewall log"
3957
  msgstr "Enregistrer l'événement dans le journal du pare-feu"
3958
 
3959
+ #: lib/i18n-extra.php:76
3960
  msgid "Allow the following IP, CIDR or AS number"
3961
  msgstr "Accepter les IP, CIDR ou numéros d'AS suivants"
3962
 
3963
+ #: lib/i18n-extra.php:77
3964
  #, php-format
3965
  msgid "IPv4 address: %s"
3966
  msgstr "Adresse IPv4 : %s"
3967
 
3968
+ #: lib/i18n-extra.php:78
3969
  #, php-format
3970
  msgid "IPv4 CIDR: %s"
3971
  msgstr "CIDR IPv4 : %s"
3972
 
3973
+ #: lib/i18n-extra.php:79
3974
  #, php-format
3975
  msgid "IPv6 address: %s"
3976
  msgstr "Adresse IPv6 : %s"
3977
 
3978
+ #: lib/i18n-extra.php:80
3979
  #, php-format
3980
  msgid "IPv6 CIDR: %s"
3981
  msgstr "CIDR IPv6 : %s"
3982
 
3983
+ #: lib/i18n-extra.php:81
3984
  #, php-format
3985
  msgid "Autonomous System number: %s"
3986
  msgstr "Numéro AS (Autonomous System) : %s"
3987
 
3988
+ #: lib/i18n-extra.php:82
3989
  msgid "Whitelist:"
3990
  msgstr "Liste Blanche:"
3991
 
3992
+ #: lib/i18n-extra.php:83
3993
  msgid "Enter one item per line."
3994
  msgstr "Une entrée par ligne."
3995
 
3996
+ #: lib/i18n-extra.php:84
3997
  msgid "External Services"
3998
  msgstr "Services externes"
3999
 
4000
+ #: lib/i18n-extra.php:85
4001
  msgid "Whitelist IP addresses from the following services:"
4002
  msgstr "Ajouter les adresses IP des services suivants à la liste blanche :"
4003
 
4004
+ #: lib/i18n-extra.php:86
4005
  msgid "View IP addresses"
4006
  msgstr "Voir les adresses IP"
4007
 
4008
+ #: lib/i18n-extra.php:87
4009
  msgid "Block the following IP, CIDR or AS number"
4010
  msgstr "Bloquer les IP, CIDR ou numéros d'AS suivants"
4011
 
4012
+ #: lib/i18n-extra.php:88
4013
  msgid "Blacklist:"
4014
  msgstr "Liste noire :"
4015
 
4016
+ #: lib/i18n-extra.php:89
4017
  msgid "Rate Limiting"
4018
  msgstr "Limiter le trafic"
4019
 
4020
+ #: lib/i18n-extra.php:90
4021
  #, php-format
4022
  msgid ""
4023
  "Block for %s seconds any IP address with more than %s connections within a "
4026
  "Bloquer pendant %s secondes les IP ayant plus de %s connexions en moins de "
4027
  "%s."
4028
 
4029
+ #: lib/i18n-extra.php:91
4030
  msgid "5-second"
4031
  msgstr "5 secondes"
4032
 
4033
+ #: lib/i18n-extra.php:92
4034
  msgid "10-second"
4035
  msgstr "10 secondes"
4036
 
4037
+ #: lib/i18n-extra.php:93
4038
  msgid "15-second"
4039
  msgstr "15 secondes"
4040
 
4041
+ #: lib/i18n-extra.php:94
4042
  msgid "30-second"
4043
  msgstr "30 secondes"
4044
 
4045
+ #: lib/i18n-extra.php:95
4046
  msgid "Allow access to the following URL"
4047
  msgstr "Autoriser l'accès à l'URL suivante"
4048
 
4049
+ #: lib/i18n-extra.php:96
4050
  #, php-format
4051
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
4052
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
4053
 
4054
+ #: lib/i18n-extra.php:97
4055
  msgid "Block access to the following URL"
4056
  msgstr "Bloquer l'accès à l'URL suivante"
4057
 
4058
+ #: lib/i18n-extra.php:98
4059
  msgid "Reject the following bots"
4060
  msgstr "Rejeter les bots suivants"
4061
 
4062
+ #: lib/i18n-extra.php:99
4063
  msgid "A full or partial case-insensitive string."
4064
  msgstr "Chaîne de caractère complète ou partielle, insensible à la casse."
4065
 
4066
+ #: lib/i18n-extra.php:100
4067
  #, php-format
4068
  msgid "Allowed characters are: %s and %s."
4069
  msgstr "Caractères autorisés : %s et %s."
4070
 
4071
+ #: lib/i18n-extra.php:101
4072
  msgid "Blocked bots:"
4073
  msgstr "Bots bloqués :"
4074
 
4075
+ #: lib/i18n-extra.php:102
4076
  msgid "The default list of bots will be restored. Continue?"
4077
  msgstr "Restaurer les valeurs par défaut de la liste des bots ?"
4078
 
4079
+ #: lib/i18n-extra.php:103
4080
  msgid "Restore default bots list"
4081
  msgstr "Restaurer les valeurs par défaut"
4082
 
4083
+ #: lib/i18n-extra.php:104
4084
  msgid "Do not filter the following user input"
4085
  msgstr "Ne pas filtrer l'entrée utilisateur suivante"
4086
 
4087
+ #: lib/i18n-extra.php:105
4088
  msgid ""
4089
  "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
4090
  "sensitive input:"
4092
  "Une variable GET, POST ou COOKIE, suivie de deux points (:) et de l'entrée, "
4093
  "sensible à la casse :"
4094
 
4095
+ #: lib/i18n-extra.php:106
4096
  msgid "Unfiltered input:"
4097
  msgstr "Entrées non filtrées :"
4098
 
4099
+ #: lib/i18n-extra.php:107
4100
  msgid "Block the request if the following input is present"
4101
  msgstr "Bloquer la requête si elle contient l'entrée suivante"
4102
 
4103
+ #: lib/i18n-extra.php:108
4104
  msgid "Blocked input:"
4105
  msgstr "Entrées bloquées :"
4106
 
4107
+ #: lib/i18n-extra.php:109
4108
  msgid "Save Access Control directives"
4109
  msgstr "Sauvegarder les options"
4110
 
4111
+ #: lib/i18n-extra.php:110
4112
  msgid ""
4113
  "Warning: Your previous secret key was either corrupted or missing. A new "
4114
  "one, as well as a new public key, were created."
4116
  "Attention : votre clé privée était soit corrompue soit manquante. Un nouveau "
4117
  "jeu de clés vient d'être créé."
4118
 
4119
+ #: lib/i18n-extra.php:111
4120
  msgid "Enable Centralized Logging"
4121
  msgstr "Activer la Centralisation des Logs"
4122
 
4123
+ #: lib/i18n-extra.php:112
4124
  msgid "Secret key"
4125
  msgstr "Clé privée"
4126
 
4127
+ #: lib/i18n-extra.php:113
4128
  msgid "From 30 to 100 ASCII printable characters."
4129
  msgstr "De 30 à 100 caractères ASCII."
4130
 
4131
+ #: lib/i18n-extra.php:114
4132
  msgid "This server's IP address"
4133
  msgstr "L'adresse IP de ce serveur"
4134
 
4135
+ #: lib/i18n-extra.php:115
4136
  msgid ""
4137
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
4138
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
4142
  "distants. Si vous ne souhaitez pas de restriction d’accès par IP, veuillez "
4143
  "entrer le caractère <code>*</code>."
4144
 
4145
+ #: lib/i18n-extra.php:116
4146
  msgid "Public key"
4147
  msgstr "Clé publique"
4148
 
4149
+ #: lib/i18n-extra.php:117
4150
  #, php-format
4151
  msgid ""
4152
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
4155
  "Vous devez configurer vos sites distants avec cette nouvelle clé. <a href="
4156
  "\"%s\">Consultez notre blog</a> pour plus d'info."
4157
 
4158
+ #: lib/i18n-extra.php:118
4159
  msgid "Remote websites URL"
4160
  msgstr "URL de vos sites distants"
4161
 
4162
+ #: lib/i18n-extra.php:119
4163
  msgid ""
4164
  "Enter one URL per line, including the protocol (<code>http://</code> or "
4165
  "<code>https://</code>). Only ASCII URLs are accepted."
4167
  "Entrez une URL par ligne, en incluant le protocole (<code>http://</code> ou "
4168
  "<code>https://</code>). Seules les URL au format ASCII sont acceptées."
4169
 
4170
+ #: lib/i18n-extra.php:120
4171
  msgid "Save Options"
4172
  msgstr "Sauvegarder les options"
4173
 
4174
+ #: lib/i18n-extra.php:121
4175
  msgid ""
4176
  "Your changes have been saved. If you are using a caching plugin, do not "
4177
  "forget to clear its cache."
4179
  "Vos changements ont été enregistrés. Si vous utilisez une extension de mise "
4180
  "en cache, n'oubliez pas d'effacer son cache."
4181
 
4182
+ #: lib/i18n-extra.php:122
4183
  msgid "Enable antispam protection"
4184
  msgstr "Activer la protection anti-spam"
4185
 
4186
+ #: lib/i18n-extra.php:123
4187
  msgid "Protection level"
4188
  msgstr "Niveau de protection"
4189
 
4190
+ #: lib/i18n-extra.php:124
4191
  msgid "Low (default)"
4192
  msgstr "Bas (défaut)"
4193
 
4194
+ #: lib/i18n-extra.php:125
4195
  msgid ""
4196
  "If you are using a caching plugin, consult the contextual help before "
4197
  "enabling the antispam."
4199
  "Si vous utilisez une extension de mise en cache, veuillez consulter l'aide "
4200
  "contextuelle avant d'activer l'anti-spam."
4201
 
4202
+ #: lib/i18n-extra.php:126
4203
  msgid "Apply protection to"
4204
  msgstr "Appliquer la protection au"
4205
 
4206
+ #: lib/i18n-extra.php:127
4207
  msgid "Comment forms (defaut)"
4208
  msgstr "Formulaire de commentaire (défaut)"
4209
 
4210
+ #: lib/i18n-extra.php:128
4211
  msgid "User Registration form"
4212
  msgstr "Formulaire d'inscription"
4213
 
4214
+ #: lib/i18n-extra.php:129
4215
  msgid "Save Antispam options"
4216
  msgstr "Sauvegarder les options"
4217
 
4218
+ #: lib/i18n-extra.php:130
4219
  msgid "Please enable JavaScript"
4220
  msgstr "Veuillez activer JavaScript"
4221
 
4222
+ #: lib/i18n-extra.php:131
4223
  msgid "Sorry, this looks like spam to me."
4224
  msgstr "Désolé, mais cela ressemble à du spam."
4225
 
4226
+ #: lib/i18n-extra.php:132
4227
  msgid ""
4228
  "Error: You must be whitelisted in order to use that feature: click on the <a "
4229
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
4234
  "et assurez vous que l'option \"Ne pas bloquer les utilisateurs suivants\" "
4235
  "est activée pour l'Administrateur/Super Admin."
4236
 
4237
+ #: lib/i18n-extra.php:133
4238
  msgid ""
4239
  "Your license is valid until the indicated expiration date. If you don't "
4240
  "renew it after this date, NinjaFirewall will keep working and protecting "
4245
  "et à protéger votre site comme d'habitude, mais les mises à jour / mises à "
4246
  "niveau ne pourront plus être effectuées."
4247
 
4248
+ #: lib/i18n-extra.php:134
4249
  #, php-format
4250
  msgid ""
4251
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
4253
  "Vous pouvez renouveler votre licence depuis le site <a href=\"%s"
4254
  "\">NinTechNet.com</a>."
4255
 
4256
+ #: lib/i18n-extra.php:135
4257
  msgid "Use shared memory"
4258
  msgstr "Utiliser la mémoire partagée"
4259
 
4260
+ #: lib/i18n-extra.php:136
4261
  msgid ""
4262
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
4263
  "order to speed up all operations. The firewall will no longer need to "
4276
  "réseau multi-site, la vitesse de traitement de pare-feu va augmenter de 25% "
4277
  "à 30%."
4278
 
4279
+ #: lib/i18n-extra.php:137
4280
  msgid ""
4281
  "This option requires that your PHP version was compiled with the <code>--"
4282
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
4285
  "Cette fonction nécessite que PHP soit compilé avec le paramètre <code>--"
4286
  "enable-shmop</code>."
4287
 
4288
+ #: lib/i18n-extra.php:138
4289
  #, php-format
4290
  msgid ""
4291
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
4300
  "être en mesure de nettoyer correctement les caractères multi-octets, car il "
4301
  "n'aura pas accès à la base de données."
4302
 
4303
+ #: lib/i18n-extra.php:139
4304
  msgid "Language"
4305
  msgstr "Langue"
4306
 
4307
+ #: lib/i18n-extra.php:140
4308
  msgid ""
4309
  "When this option is enabled, NinjaFirewall will download, if available, the "
4310
  "corresponding language files from the WordPress repo. Then, every hour, it "
4315
  "les heures, il vérifiera s'il existe une nouvelle version et la téléchargera "
4316
  "le cas échéant."
4317
 
4318
+ #: lib/i18n-extra.php:141
4319
  msgid ""
4320
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
4321
  "locales because they are already included with NinjaFirewall."
4323
  "Notez que cela ne s'applique pas aux locales <code>en_US</code> et "
4324
  "<code>fr_FR</code> car elles sont déjà incluses avec NinjaFirewall."
4325
 
4326
+ #: lib/i18n-extra.php:142
4327
  #, php-format
4328
  msgid ""
4329
  "This options lets you export you current configuration or import it from "
4337
  "(%s), sinon il sera rejeté. Notez que l'importation effacera toute votre "
4338
  "configuration (options et règles du pare-feu), sauf votre licence WP+."
4339
 
4340
+ #: lib/i18n-extra.php:143
4341
  msgid ""
4342
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
4343
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
4351
  "systèmes (.htaccess, .htpasswd et PHP INI) et les fichiers SVG contenant du "
4352
  "Javascript ou des Événements XML."
4353
 
4354
+ #: lib/i18n-extra.php:144
4355
  msgid "Maximum allowed file size"
4356
  msgstr "Taille maximale autorisée"
4357
 
4358
+ #: lib/i18n-extra.php:145
4359
  msgid ""
4360
  "If you allow uploads, you can select the maximum size of an uploaded file. "
4361
  "Any file bigger than this value will be rejected. Note that if your PHP "
4367
  "configuration de PHP utilise la directive<code>upload_max_filesize</code>, "
4368
  "celle-ci sera prioritaire."
4369
 
4370
+ #: lib/i18n-extra.php:146
4371
  msgid "Decode Base64-encoded <code>POST</code> variable:"
4372
  msgstr ""
4373
  "Décoder les chaîne encodées en Base64 dans la variable <code>POST</"
4374
  "code>&nbsp;:"
4375
 
4376
+ #: lib/i18n-extra.php:147
4377
  #, php-format
4378
  msgid ""
4379
  "Object Serialization is a PHP feature used by many applications to generate "
4392
  "<code>POST</code>, les cookies, ou dans les variables <code>HTTP_REFERER</"
4393
  "code> et <code>HTTP_USER_AGENT</code>."
4394
 
4395
+ #: lib/i18n-extra.php:148
4396
  msgid ""
4397
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
4398
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
4406
  "contenant le caractère ASCI 0x00 (NULL byte) sera bloquée immédiatement. Ce "
4407
  "caractère est dangereux et devrait toujours être rejeté."
4408
 
4409
+ #: lib/i18n-extra.php:149
4410
  msgid ""
4411
  "This option will block any <code>GET</code> or <code>POST</code> request "
4412
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
4417
  "les programmes malveillants. Attention toutefois à ne pas bloquer certains "
4418
  "scripts d'installation ou de configuration si vous l'activez."
4419
 
4420
+ #: lib/i18n-extra.php:150
4421
  msgid ""
4422
  "Access Control is a powerful set of directives that can be used to allow or "
4423
  "restrict access to your website based on many criteria."
4426
  "utilisé pour autoriser ou restreindre l'accès à votre site selon de nombreux "
4427
  "critères."
4428
 
4429
+ #: lib/i18n-extra.php:151
4430
  msgid ""
4431
  "To make better use of them, it is important to understand NinjaFirewall's "
4432
  "directives processing order."
4434
  "Afin de pouvoir optimiser son utilisation, il est important de bien "
4435
  "comprendre l'ordre dans lequel NinjaFirewall traite ces directives."
4436
 
4437
+ #: lib/i18n-extra.php:152
4438
  msgid ""
4439
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
4440
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
4445
  "(images, JS, CSS, etc). Selon votre configuration, elle peuvent également "
4446
  "s'appliquer aux pages HTML."
4447
 
4448
+ #: lib/i18n-extra.php:153
4449
  msgid "Processing order:"
4450
  msgstr "Ordre de traitement des directives :"
4451
 
4452
+ #: lib/i18n-extra.php:154
4453
  msgid "Incoming HTTP request"
4454
  msgstr "Requête HTTP entrante"
4455
 
4456
+ #: lib/i18n-extra.php:155
4457
  #, php-format
4458
  msgid "%s file"
4459
  msgstr "Fichier %s"
4460
 
4461
+ #: lib/i18n-extra.php:156
4462
  msgid "Login Protection."
4463
  msgstr "Page de Connexion."
4464
 
4465
+ #: lib/i18n-extra.php:157
4466
  msgid "Access Control (except User Input Access Control):"
4467
  msgstr "Contrôle d'Accès (sauf Contrôle d'accès d'entrée utilisateur) :"
4468
 
4469
+ #: lib/i18n-extra.php:158
4470
  msgid "Role-based Access Control."
4471
  msgstr "Contrôle d'Accès par Rôle."
4472
 
4473
+ #: lib/i18n-extra.php:159
4474
  msgid "Allowed IPs."
4475
  msgstr "Adresses IP autorisées."
4476
 
4477
+ #: lib/i18n-extra.php:160
4478
  msgid "Blocked IPs."
4479
  msgstr "Adresses IP bloquées."
4480
 
4481
+ #: lib/i18n-extra.php:161
4482
  msgid "Allowed URLs."
4483
  msgstr "URL autorisées."
4484
 
4485
+ #: lib/i18n-extra.php:162
4486
  msgid "Blocked URLs."
4487
  msgstr "URL bloquées."
4488
 
4489
+ #: lib/i18n-extra.php:163
4490
  msgid "Bot Access Control."
4491
  msgstr "Contrôle d'accès par Bot."
4492
 
4493
+ #: lib/i18n-extra.php:164
4494
  msgid "Geolocation."
4495
  msgstr "Géolocalisation."
4496
 
4497
+ #: lib/i18n-extra.php:165
4498
  msgid "Rate Limiting."
4499
  msgstr "Limitation du trafic."
4500
 
4501
+ #: lib/i18n-extra.php:166
4502
  msgid "File Guard."
4503
  msgstr "File Guard."
4504
 
4505
+ #: lib/i18n-extra.php:167
4506
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
4507
  msgstr ""
4508
  "Règles et politiques du pare-feu + Contrôle d'accès d'entrée utilisateur."
4509
 
4510
+ #: lib/i18n-extra.php:168
4511
  msgid "Response body"
4512
  msgstr "Requête HTTP sortante"
4513
 
4514
+ #: lib/i18n-extra.php:169
4515
  msgid "HTTP response headers (Firewall Policies)."
4516
  msgstr "En-têtes de réponse HTTP (Politiques du Pare-feu)."
4517
 
4518
+ #: lib/i18n-extra.php:170
4519
  msgid "Web Filter."
4520
  msgstr "Web Filter."
4521
 
4522
+ #: lib/i18n-extra.php:171
4523
  #, php-format
4524
  msgid ""
4525
  "By default, any logged in WordPress administrator will not be blocked by "
4538
  "options de la <a href=\"%s\">Page de Connexion</a> qui, si elle sont "
4539
  "activées, seront toujours appliquées."
4540
 
4541
+ #: lib/i18n-extra.php:172
4542
  msgid "You can also add other users to the whitelist, depending on their role."
4543
  msgstr ""
4544
  "Vous pouvez ajouter d'autres utilisateurs à votre liste blanche en se basant "
4545
  "sur leur Rôle."
4546
 
4547
+ #: lib/i18n-extra.php:173
4548
  #, php-format
4549
  msgid ""
4550
  "this option should be used if you are behind a reverse proxy, a load "
4568
  "sera vérifiée. Si elle ne comprend aucune IP utilisable, NinjaFirewall "
4569
  "utilisera <code>REMOTE_ADDR</code>."
4570
 
4571
+ #: lib/i18n-extra.php:174
4572
  msgid ""
4573
  "This option lets you select the HTTP method(s). All Access Control "
4574
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
4578
  "Contrôle d'Accès (Geolocalisation, IP, bots et URL) ne s'appliqueront qu'aux "
4579
  "méthodes sélectionnées."
4580
 
4581
+ #: lib/i18n-extra.php:175
4582
  msgid ""
4583
  "It does not apply to the \"Firewall Policies\" options, which use their own "
4584
  "ones."
4585
  msgstr "Cette option ne concerne pas les \"Politiques du Pare-feu\"."
4586
 
4587
+ #: lib/i18n-extra.php:176
4588
  msgid ""
4589
  "You can filter and block traffic coming from specific countries/territories."
4590
  msgstr ""
4591
  "Vous pouvez filtrer et bloquer le trafic en provenance de pays ou "
4592
  "territoires spécifiques."
4593
 
4594
+ #: lib/i18n-extra.php:177
4595
  msgid ""
4596
  "This is the two-letter code that is used to define a country/territory (e."
4597
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
4604
  "données, ou à partir d'une variable PHP prédéfinie ajoutée par votre serveur "
4605
  "HTTP (par exemple, <code>GEOIP_COUNTRY_CODE</code>)."
4606
 
4607
+ #: lib/i18n-extra.php:178
4608
  #, php-format
4609
  msgid ""
4610
  "You can add/remove any country/territory from the two listboxes. For more "
4616
  "spécifiques (A1, A2, AP, EU etc),vous pouvez consulter l'aide en ligne de <a "
4617
  "href=\"%s\">MaxMind GeoIP</a>."
4618
 
4619
+ #: lib/i18n-extra.php:179
4620
  msgid ""
4621
  "Whether geolocation should apply to the whole site or to specific URLs only "
4622
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
4626
  "uniquement (ex: /wp-login.php, /xmlrpc.php etc). Laissez ce champ vide pour "
4627
  "l'appliquer à tout le site."
4628
 
4629
+ #: lib/i18n-extra.php:180
4630
  msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
4631
  msgstr "Ajouter <code>NINJA_COUNTRY_CODE</code> aux en-têtes PHP?"
4632
 
4633
+ #: lib/i18n-extra.php:181
4634
  msgid ""
4635
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
4636
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
4642
  "code>. Si vous avez une application PHP qui nécessite de géolocaliser vos "
4643
  "visiteurs, activez cette option."
4644
 
4645
+ #: lib/i18n-extra.php:182
4646
  msgid ""
4647
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
4648
  "it with 2 hyphens (<code>--</code>)."
4650
  "Si NinjaFirewall ne peut pas identifier le code à deux lettres ISO 3166, il "
4651
  "le remplacera par deux traits d'union (<code>--</code>)."
4652
 
4653
+ #: lib/i18n-extra.php:183
4654
  msgid ""
4655
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
4656
  msgstr ""
4657
  "Exemple de code PHP à ajouter à vos scripts pour géolocaliser vos visiteurs :"
4658
 
4659
+ #: lib/i18n-extra.php:184
4660
  msgid ""
4661
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4662
  "http://www.maxmind.com"
4664
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4665
  "http://www.maxmind.com"
4666
 
4667
+ #: lib/i18n-extra.php:185
4668
  msgid "IP / URL / Bot Access Control"
4669
  msgstr "Contrôle d'Accès par IP / URL / Bots"
4670
 
4671
+ #: lib/i18n-extra.php:186
4672
  msgid ""
4673
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
4674
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
4678
  "numéro AS (Autonomous System). NinjaFirewall est compatible avec l'IPv4 et "
4679
  "l'IPv6."
4680
 
4681
+ #: lib/i18n-extra.php:187
4682
  msgid "Full IP:"
4683
  msgstr "IP complète :"
4684
 
4685
+ #: lib/i18n-extra.php:188
4686
  #, php-format
4687
  msgid "IP ranges using CIDR notation: %s or %s."
4688
  msgstr "Plages IP utilisant la notation CIDR : %s ou %s."
4689
 
4690
+ #: lib/i18n-extra.php:189
4691
  msgid "Autonomous System number:"
4692
  msgstr "Numéro AS (Autonomous System) :"
4693
 
4694
+ #: lib/i18n-extra.php:190
4695
  msgid ""
4696
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
4697
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
4710
  "adresse IP, utilisez l'option \"Contrôle d'accès par IP\". Par défaut, la "
4711
  "limitation du trafic n'est pas activée."
4712
 
4713
+ #: lib/i18n-extra.php:191
4714
  msgid ""
4715
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
4716
  "immediately by clicking either the \"Save Access Control Directives\" or "
4720
  "débloquées simplement en cliquant sur les boutons \"Sauvegarder les options"
4721
  "\" ou \"Rétablir les valeurs par défaut\" situés en bas de la page."
4722
 
4723
+ #: lib/i18n-extra.php:192
4724
  msgid ""
4725
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
4726
  "IPs even before your blog is loaded, we strongly recommend that you disable "
4734
  "seconde, NinjaFirewall vous fera économiser de la bande passante et "
4735
  "permettra de réduire la charge du serveur."
4736
 
4737
+ #: lib/i18n-extra.php:193
4738
  msgid ""
4739
  "You can permanently allow/block any access to one or more PHP scripts based "
4740
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
4745
  "(<code>SCRIPT_NAME</code>). Vous pouvez entrer l'URL complète ou partielle, "
4746
  "sensible à la casse."
4747
 
4748
+ #: lib/i18n-extra.php:194
4749
  msgid ""
4750
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
4751
  "script located inside a <code>/foo/</code> directory"
4753
  "<code>/foo/bar.php</code> autorisera/bloquera tout accès au script PHP "
4754
  "<code>bar.php</code> situé dans un répertoire <code>/foo/</code>"
4755
 
4756
+ #: lib/i18n-extra.php:195
4757
  msgid "etc"
4758
  msgstr "etc"
4759
 
4760
+ #: lib/i18n-extra.php:196
4761
  msgid ""
4762
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
4763
  "<code>/foo/</code> directory and its sub-directories."
4765
  "<code>/foo/</code> autorisera/bloquera l'accès à tous les scripts PHP situés "
4766
  "dans un répertoire <code>/foo/</code> et ses sous-répertoires."
4767
 
4768
+ #: lib/i18n-extra.php:197
4769
  msgid ""
4770
  "Note that the \"Firewall Policies\" page already includes restrictions to "
4771
  "some WordPress directories."
4773
  "Notez que le menu des \"Politiques du pare-feu\" comporte déjà des "
4774
  "restrictions à certains répertoires de WordPress."
4775
 
4776
+ #: lib/i18n-extra.php:198
4777
  msgid ""
4778
  "You can block bots, scanners and various crawlers based on the "
4779
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
4783
  "nom (<code>HTTP_USER_AGENT</code>) ou partie de celui-ci. La chaîne de "
4784
  "caractères est insensible à la casse."
4785
 
4786
+ #: lib/i18n-extra.php:199
4787
  msgid ""
4788
  "You can select to ignore or block some specific user input. It applies to "
4789
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
4795
  "<code>COOKIE</code>, par exemple <code>$_GET[\"foo\"]</code> ou <code>"
4796
  "$_POST[\"bar\"]</code> :"
4797
 
4798
+ #: lib/i18n-extra.php:200
4799
  msgid ""
4800
  "When an input is added to the \"Unfiltered input\" list, it will not be "
4801
  "filtered or sanitised. All other input present in the request will be "
4805
  "sera ni filtrée ni nettoyée. Toutes les autres entrées présentes dans la "
4806
  "demande seront filtrées."
4807
 
4808
+ #: lib/i18n-extra.php:201
4809
  msgid ""
4810
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
4811
  "the request and close the connection if that input is found in the request."
4814
  "bloquera la requête et fermera la connexion si cette entrée est présente "
4815
  "dans la requête."
4816
 
4817
+ #: lib/i18n-extra.php:202
4818
  msgid "Log Event"
4819
  msgstr "Journaliser"
4820
 
4821
+ #: lib/i18n-extra.php:203
4822
  msgid ""
4823
  "You can enable/disable firewall logging for each access control directive "
4824
  "separately."
4826
  "Vous pouvez activer/désactiver la journalisation des directives "
4827
  "indépendamment les unes des autres."
4828
 
4829
+ #: lib/i18n-extra.php:204
4830
  msgid "Web Filter"
4831
  msgstr "Web Filter"
4832
 
4833
+ #: lib/i18n-extra.php:205
4834
  msgid ""
4835
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
4836
  "response body (i.e., the output of the HTML page right before it is sent to "
4847
  "etc), des scripts utilisés par les hackers (shell, backdoor) et même des "
4848
  "erreurs (PHP, MySQL)."
4849
 
4850
+ #: lib/i18n-extra.php:206
4851
  msgid ""
4852
  "In the case of a positive detection, NinjaFirewall will not block the "
4853
  "response body but will send you an alert by email."
4855
  "En cas de détection positive, NinjaFirewall ne bloquera pas la requête mais "
4856
  "vous enverra immédiatement une alerte par e-mail."
4857
 
4858
+ #: lib/i18n-extra.php:207
4859
  msgid "Search HTML page for the following keywords"
4860
  msgstr "Rechercher les mots suivants dans la page HTML"
4861
 
4862
+ #: lib/i18n-extra.php:208
4863
  msgid ""
4864
  "You can enter any keyword from 4 to 150 characters and select whether the "
4865
  "search will be case sensitive or not."
4867
  "Vous pouvez entrer de 4 à 150 caractères et sélectionner si la recherche est "
4868
  "sensible à la casse."
4869
 
4870
+ #: lib/i18n-extra.php:209
4871
  msgid "Email Alerts"
4872
  msgstr "Alertes E-mail"
4873
 
4874
+ #: lib/i18n-extra.php:210
4875
  msgid ""
4876
  "You can use the notification throttling option to limit the frequency of "
4877
  "alerts sent to you (and written to the firewall log) and select whether you "
4883
  "d'Événement \". La page HTML ayant déclenché cette alerte peut être jointe à "
4884
  "l'e-mail."
4885
 
4886
+ #: lib/i18n-extra.php:211
4887
  msgid ""
4888
  "Response body filtering can be resource-intensive. Try to limit the number "
4889
  "of keywords to what you really need (less than 10) and, if possible, prefer "
4893
  "limiter le nombre de mots-clés (moins de 10) et, si possible, préférez la "
4894
  "recherche sensible à la casse."
4895
 
4896
+ #: lib/i18n-extra.php:212
4897
  msgid ""
4898
  "NinjaFirewall can protect your blog against spam without user interaction (e."
4899
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
4908
  "vous utilisez une extension tierce pour créer vos formulaires, ils ne seront "
4909
  "pas protégés contre le spam."
4910
 
4911
+ #: lib/i18n-extra.php:213
4912
  msgid "Protection level:"
4913
  msgstr "Niveau de protection :"
4914
 
4915
+ #: lib/i18n-extra.php:214
4916
  msgid ""
4917
  "Select the level of protection. In most cases, <strong>Low</strong> should "
4918
  "be enough."
4920
  "Sélectionnez le niveau de protection. Dans la plupart des cas \"Bas\" est "
4921
  "suffisant."
4922
 
4923
+ #: lib/i18n-extra.php:215
4924
  msgid "Apply protection to:"
4925
  msgstr "Appliquer la protection à :"
4926
 
4927
+ #: lib/i18n-extra.php:216
4928
  msgid "Whether to protect comment and/or registration forms."
4929
  msgstr "S'il faut protéger les formulaires de commentaire et d'inscription."
4930
 
4931
+ #: lib/i18n-extra.php:217
4932
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4933
  msgstr ""
4934
  "Si vous utilisez une extension de mise en cache, veuillez procéder de la "
4935
  "sorte :"
4936
 
4937
+ #: lib/i18n-extra.php:218
4938
  msgid ""
4939
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4940
  "otherwise the antispam could behave erratically after a while."
4942
  "Réglez le niveau de protection sur \"Bas\" uniquement. N'utilisez pas "
4943
  "d'autre niveau, sinon l'anti-spam pourrait se comporter de façon erratique."
4944
 
4945
+ #: lib/i18n-extra.php:219
4946
  msgid ""
4947
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4948
  msgstr ""
4949
  "Videz / effacez votre cache immédiatement après l'activation ou la "
4950
  "désactivation de l'anti-spam."
4951
 
4952
+ #: lib/i18n-extra.php:220
4953
  msgid ""
4954
  "The firewall log displays blocked and sanitised requests as well as some "
4955
  "useful information. It has 6 columns:"
4957
  "Le journal du pare-feu affiche les requêtes HTTP qui ont été bloquées ou "
4958
  "nettoyées ainsi que d'autres informations utiles. Il a six colonnes :"
4959
 
4960
+ #: lib/i18n-extra.php:221
4961
  msgid ""
4962
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4963
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
4968
  "d'un numéro signifie que la règle provient de votre configuration "
4969
  "personnelle de la page \"Politiques du Pare-feu\" ou \"Contrôle d'Accès\"."
4970
 
4971
+ #: lib/i18n-extra.php:222
4972
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4973
  msgstr ""
4974
  "Le journal peut aussi être exporté au format TSV (valeurs séparées par des "
4975
  "tabulations)."
4976
 
4977
+ #: lib/i18n-extra.php:223
4978
  msgid "Enable firewall log"
4979
  msgstr "Activer le journal du pare-feu"
4980
 
4981
+ #: lib/i18n-extra.php:224
4982
  msgid "You can disable/enable the firewall log from this page."
4983
  msgstr ""
4984
  "Vous pouvez activer / désactiver le journal du pare-feu à partir de cette "
4985
  "page."
4986
 
4987
+ #: lib/i18n-extra.php:225
4988
  msgid ""
4989
  "Brute-force attacks will still be written to the firewall log, even if you "
4990
  "disable it."
4992
  "Les attaques par force brute seront toujours enregistrées dans le journal du "
4993
  "pare-feu, même si vous désactivez celui-ci."
4994
 
4995
+ #: lib/i18n-extra.php:226
4996
  msgid "Auto-rotate log"
4997
  msgstr "Rotation automatique du journal"
4998
 
4999
+ #: lib/i18n-extra.php:227
5000
  msgid ""
5001
  "NinjaFirewall will rotate its log automatically on the very first day of "
5002
  "each month. If your site is very busy, you may want to allow it to rotate "
5007
  "effectuée plus tôt, dans le cas où le journal aurait atteint une certaine "
5008
  "taille (Mo)."
5009
 
5010
+ #: lib/i18n-extra.php:228
5011
  msgid ""
5012
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
5013
  "megabytes."
5014
  msgstr "Par défaut, cette taille est fixée à 2 Mo."
5015
 
5016
+ #: lib/i18n-extra.php:229
5017
  msgid ""
5018
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
5019
  msgstr ""
5020
  "Les journaux des mois précédents sont accessibles depuis le menu déroulant "
5021
  "situé au dessus de la fenêtre."
5022
 
5023
+ #: lib/i18n-extra.php:230
5024
  msgid "Syslog"
5025
  msgstr "Syslog"
5026
 
5027
+ #: lib/i18n-extra.php:231
5028
  msgid ""
5029
  "In addition to the firewall log, events can also be redirected to the syslog "
5030
  "server (<code>LOG_USER</code> facility)."
5032
  "En plus d'écrire dans son journal, le pare-feu peut aussi utiliser le "
5033
  "serveur Syslog (catégorie <code>LOG_USER</code>)."
5034
 
5035
+ #: lib/i18n-extra.php:232
5036
  msgid ""
5037
  "If you have a shared hosting account, keep this option disabled as you do "
5038
  "not have any access to the server logs."
5040
  "Si vous avez un hébergement mutualisé, laissez cette option désactivée car "
5041
  "vous n'avez pas accès aux journaux du serveur."
5042
 
5043
+ #: lib/i18n-extra.php:233
5044
  msgid "The logline uses the following format:"
5045
  msgstr "Le format utilisé est le suivant :"
5046
 
5047
+ #: lib/i18n-extra.php:234
5048
  msgid ""
5049
  "BB: the level of severity as it appears in the firewall log. It can be "
5050
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
5055
  "<CODE>MEDIUM</CODE>, <CODE>INFO</CODE>, <CODE>UPLOAD</CODE> ou "
5056
  "<CODE>DEBUG_ON</CODE>."
5057
 
5058
+ #: lib/i18n-extra.php:235
5059
  msgid "CCCCCC: the 7-digit incident ID."
5060
  msgstr "CCCCCC : le numéro d'incident à sept chiffres."
5061
 
5062
+ #: lib/i18n-extra.php:236
5063
  msgid "DD: the user IPv4 or IPv6 address."
5064
  msgstr "DD : L'adresse IPv4 ou IPv6 de l'utilisateur."
5065
 
5066
+ #: lib/i18n-extra.php:237
5067
  msgid "EE: the blog (sub-)domain name."
5068
  msgstr "EE : le nom de (sous-)domaine du blog."
5069
 
5070
+ #: lib/i18n-extra.php:238
5071
  #, php-format
5072
  msgid ""
5073
  "This logging option does not apply to the brute-force protection which can "
5079
  "d'authentification du serveur. Voir le menu de la <a href=\"%s\">Page de "
5080
  "Connexion</a>."
5081
 
5082
+ #: lib/i18n-extra.php:239
5083
  msgid ""
5084
  "Secret key: The secret key will be used to generate your public key. Enter "
5085
  "at least 30 ASCII characters, or use the one randomly created by "
5089
  "de 30 à 100 caractères ASCII, ou bien utilisez la clé générée aléatoirement "
5090
  "par NinjaFirewall."
5091
 
5092
+ #: lib/i18n-extra.php:240
5093
  msgid ""
5094
  "This server IP address: As an additional protection layer, you can restrict "
5095
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
5100
  "à se connecter aux sites distants. Si vous ne souhaitez pas de restriction "
5101
  "d’accès par IP, veuillez entrer le caractère <code>*</code>."
5102
 
5103
+ #: lib/i18n-extra.php:241
5104
  #, php-format
5105
  msgid ""
5106
  "Public key: This is the public key that you will need to upload to each "
5109
  "Clé publique : Vous devez configurer vos sites distants avec cette clé. <a "
5110
  "href=\"%s\">Consultez notre blog</a> pour plus d'info."
5111
 
5112
+ #: lib/i18n-extra.php:242
5113
  msgid ""
5114
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
5115
  "website(s) that you want to remotely access from the main server."
5118
  "NinjaFirewall auxquels vous souhaitez accéder à distance à partir du serveur "
5119
  "principal."
5120
 
5121
+ #: lib/i18n-extra.php:243
5122
  msgid ""
5123
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
5124
  "the menu below if you want to disable it."
5127
  "NinjaFirewall. Si vous souhaitez complètement désactiver cette option, "
5128
  "faites-le ci-dessous."
5129
 
5130
+ #: lib/i18n-extra.php:244
5131
  msgid "Enable Web Filter"
5132
  msgstr "Activer Web Filter"
5133
 
5134
+ #: lib/i18n-extra.php:245
5135
  msgid "A full or partial string."
5136
  msgstr "Chaîne de caractère complète ou partielle."
5137
 
5138
+ #: lib/i18n-extra.php:246
5139
  msgid "From 4 to maximum 150 characters."
5140
  msgstr "De 4 à 150 caractères."
5141
 
5142
+ #: lib/i18n-extra.php:247
5143
  msgid "Any character, except the vertical bar <code>|</code>"
5144
  msgstr "Tout caractère, sauf la barre verticale <code>|</code>"
5145
 
5146
+ #: lib/i18n-extra.php:248
5147
  msgid "Keywords to search:"
5148
  msgstr "Mots-clés recherchés :"
5149
 
5150
+ #: lib/i18n-extra.php:249
5151
  msgid "Case-sensitive search"
5152
  msgstr "Recherche sensible à la casse"
5153
 
5154
+ #: lib/i18n-extra.php:250
5155
  #, php-format
5156
  msgid "Do not send me more than one email alert in a %s interval"
5157
  msgstr "Ne pas envoyer plus d'un e-mail par tranche de %s"
5158
 
5159
+ #: lib/i18n-extra.php:251
5160
  msgid "5-minute"
5161
  msgstr "5 minutes"
5162
 
5163
+ #: lib/i18n-extra.php:252
5164
  msgid "15-minute"
5165
  msgstr "15 minutes"
5166
 
5167
+ #: lib/i18n-extra.php:253
5168
  msgid "30-minute"
5169
  msgstr "30 minutes"
5170
 
5171
+ #: lib/i18n-extra.php:254
5172
  msgid "1-hour"
5173
  msgstr "1 heure"
5174
 
5175
+ #: lib/i18n-extra.php:255
5176
  msgid "3-hour"
5177
  msgstr "3 heures"
5178
 
5179
+ #: lib/i18n-extra.php:256
5180
  msgid "6-hour"
5181
  msgstr "6 heures"
5182
 
5183
+ #: lib/i18n-extra.php:257
5184
  msgid "12-hour"
5185
  msgstr "12 heures"
5186
 
5187
+ #: lib/i18n-extra.php:258
5188
  msgid "24-hour"
5189
  msgstr "24 heures"
5190
 
5191
+ #: lib/i18n-extra.php:259
5192
  msgid ""
5193
  "Clicking the \"Save Web Filter options\" button below will reset the current "
5194
  "timer."
5195
  msgstr "Cliquer sur \"Sauvegarder les options\" réinitialisera le compteur."
5196
 
5197
+ #: lib/i18n-extra.php:260
5198
  msgid "Attach the HTML page output to email alerts"
5199
  msgstr "Joindre la page HTML à l'e-mail"
5200
 
5201
+ #: lib/i18n-extra.php:261
5202
  msgid "Save Web Filter options"
5203
  msgstr "Sauvegarder les options"
5204
 
5205
+ #: lib/i18n-extra.php:262
5206
  msgid "Help Desk:"
5207
  msgstr "Help Desk :"
5208
 
5209
+ #: lib/i18n-extra.php:263
5210
  msgid "The selected log was deleted"
5211
  msgstr "Le journal sélectionné a été supprimé"
5212
 
5213
+ #: lib/i18n-extra.php:264
5214
  msgid "Export"
5215
  msgstr "Exporter"
5216
 
5217
+ #: lib/i18n-extra.php:265
5218
  msgid "Delete"
5219
  msgstr "Supprimer"
5220
 
5221
+ #: lib/i18n-extra.php:266
5222
  msgid "Delete log?"
5223
  msgstr "Supprimer le journal ?"
5224
 
5225
+ #: lib/i18n-extra.php:267
5226
  msgid "Today"
5227
  msgstr "Aujourd'hui"
5228
 
5229
+ #: lib/i18n-extra.php:268
5230
  msgid "Upload"
5231
  msgstr "Téléchargement"
5232
 
5233
+ #: lib/i18n-extra.php:269
5234
  msgid "Info"
5235
  msgstr "Info"
5236
 
5237
+ #: lib/i18n-extra.php:270
5238
  msgid "Debug"
5239
  msgstr "Débogage"
5240
 
5241
+ #: lib/i18n-extra.php:271
5242
  msgid "IP address:"
5243
  msgstr "Adresse IP :"
5244
 
5245
+ #: lib/i18n-extra.php:272
5246
  msgid "e.g., 1.2.3.4"
5247
  msgstr "ex : 1.2.3.4"
5248
 
5249
+ #: lib/i18n-extra.php:273
5250
  msgid "Add IP to blacklist"
5251
  msgstr "Ajouter à la liste noire"
5252
 
5253
+ #: lib/i18n-extra.php:274
5254
  msgid "Add IP to whitelist"
5255
  msgstr "Ajouter à la liste blanche"
5256
 
5257
+ #: lib/i18n-extra.php:275
5258
  msgid "Add"
5259
  msgstr "Ajouter"
5260
 
5261
+ #: lib/i18n-extra.php:276
5262
  msgid "The address wad added to your IP Access Control list."
5263
  msgstr "L'adresse a été ajoutée à votre liste du Contrôle d'accès par IP."
5264
 
5265
+ #: lib/i18n-extra.php:277
5266
  #, php-format
5267
  msgid "1st day of the month, or if bigger than %s MB"
5268
  msgstr "Le 1er de chaque mois, ou si sa taille dépasse %s Mo"
5269
 
5270
+ #: lib/i18n-extra.php:278
5271
  msgid "1st day of the month, regardless of its size"
5272
  msgstr "Le 1er de chaque mois, quelle que soit sa taille"
5273
 
5274
+ #: lib/i18n-extra.php:279
5275
  msgid "Show the most recent"
5276
  msgstr "Afficher les dernières"
5277
 
5278
+ #: lib/i18n-extra.php:280
5279
  msgid "lines"
5280
  msgstr "lignes"
5281
 
5282
+ #: lib/i18n-extra.php:281
5283
  msgid "Write events to the Syslog server too"
5284
  msgstr "Enregistrer aussi les événements dans le journal syslog"
5285
 
5286
+ #: lib/i18n-extra.php:282
5287
  msgid "Your server configuration is not compatible with this option."
5288
  msgstr ""
5289
  "La configuration de votre serveur n'est pas compatible avec cette option."
5290
 
5291
+ #: lib/i18n-extra.php:283
5292
  msgid "See contextual help before enabling this option."
5293
  msgstr "Consultez l'aide contextuelle avant d'activer cette option."
5294
 
5295
+ #: lib/i18n-extra.php:284
5296
  msgid ""
5297
  "The remote server rejected your request. Make sure that you uploaded the "
5298
  "correct public key."
5300
  "Le serveur distant a rejeté votre requête. Veuillez vous assurer que la clé "
5301
  "publique est correcte."
5302
 
5303
+ #: lib/i18n-extra.php:285
5304
  #, php-format
5305
  msgid "The remote server returned the following HTTP error: %s"
5306
  msgstr "Le serveur HTTP a retourné le code d'erreur suivant : %s"
5307
 
5308
+ #: lib/i18n-extra.php:286
5309
  msgid "The requested log does not exist on the remote website."
5310
  msgstr "Le journal demandé n'existe pas sur le site distant."
5311
 
5312
+ #: lib/i18n-extra.php:287
5313
  msgid "The remote website did not return the expected response."
5314
  msgstr "Le site distant n'a pas retourné la réponse attendue."
5315
 
5316
+ #: lib/i18n-extra.php:288
5317
  msgid "Your server does not seem to be compatible with this option."
5318
  msgstr ""
5319
  "La configuration de votre serveur n'est pas compatible avec cette option."
5320
 
5321
+ #: lib/i18n-extra.php:289
5322
  msgid "Load language files from the WordPress repo"
5323
  msgstr "Charger les fichiers de langue depuis le WordPress.org"
5324
 
5325
+ #: lib/i18n-extra.php:290
5326
  #, php-format
5327
  msgid ""
5328
  "If available, NinjaFirewall will download the language files from <a "
5331
  "Si disponible, NinjaFirewall téléchargera le fichier de langue à partir de "
5332
  "<a %s>translate.wordpress.org</a>."
5333
 
5334
+ #: lib/i18n-extra.php:291
5335
  msgid "Error: you do not have any license."
5336
  msgstr "Erreur : vous n'avez pas de licence."
5337
 
5338
+ #: lib/i18n-extra.php:292
5339
  msgid "You have a valid license."
5340
  msgstr "Votre licence est valide."
5341
 
5342
+ #: lib/i18n-extra.php:293
5343
  msgid ""
5344
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
5345
  "try again in a few minutes"
5347
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5348
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5349
 
5350
+ #: lib/i18n-extra.php:294
5351
  msgid ""
5352
  "An error occured while connecting to NinjaFirewall servers. Please try again "
5353
  "in a few minutes"
5355
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5356
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5357
 
5358
+ #: lib/i18n-extra.php:295
5359
  msgid "Enter a valid license to save!"
5360
  msgstr "Veuillez entrer un numéro de licence valide !"
5361
 
5362
+ #: lib/i18n-extra.php:296
5363
  msgid "This is already your current license!"
5364
  msgstr "Cette licence est la même que l'actuelle !"
5365
 
5366
+ #: lib/i18n-extra.php:297
5367
  msgid "Your new license has been accepted and saved."
5368
  msgstr "Votre nouvelle licence a été acceptée et sauvegardée."
5369
 
5370
+ #: lib/i18n-extra.php:298
5371
  msgid "This license is not valid"
5372
  msgstr "Cette licence n'est pas valide"
5373
 
5374
+ #: lib/i18n-extra.php:299
5375
  msgid "WP+ Edition License"
5376
  msgstr "Licence WP+ Edition"
5377
 
5378
+ #: lib/i18n-extra.php:300
5379
  msgid "License Number"
5380
  msgstr "Numéro de Licence"
5381
 
5382
+ #: lib/i18n-extra.php:301
5383
  msgid "No license found"
5384
  msgstr "Aucune licence trouvée"
5385
 
5386
+ #: lib/i18n-extra.php:302
5387
  msgid "Click to check your license validity"
5388
  msgstr "Cliquez pour tester la validité de votre licence"
5389
 
5390
+ #: lib/i18n-extra.php:303
5391
  msgid "Expiration date"
5392
  msgstr "Date d'expiration"
5393
 
5394
+ #: lib/i18n-extra.php:304
5395
  msgid "Unknown expiration date"
5396
  msgstr "Date d'expiration inconnue"
5397
 
5398
+ #: lib/i18n-extra.php:305
5399
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
5400
  msgstr ""
5401
  "Selectionnez \"Cliquez pour tester la validité de votre licence\" pour "
5402
  "tenter de réparer cette erreur."
5403
 
5404
+ #: lib/i18n-extra.php:306
5405
  msgid "Your license will expire soon!"
5406
  msgstr "Votre licence va bientôt expirer !"
5407
 
5408
+ #: lib/i18n-extra.php:307
5409
  msgid "Your license has expired."
5410
  msgstr "Votre licence a expiré."
5411
 
5412
+ #: lib/i18n-extra.php:308
5413
  msgid "License renewal"
5414
  msgstr "Renouvellement de licence"
5415
 
5416
+ #: lib/i18n-extra.php:309
5417
  msgid "Click here to get a license!"
5418
  msgstr "Cliquez ici pour obtenir une licence !"
5419
 
5420
+ #: lib/i18n-extra.php:310
5421
  msgid "Enter your new license and click on the save button"
5422
  msgstr "Entrez votre licence et cliquez sur le bouton pour l'enregistrer"
5423
 
5424
+ #: lib/i18n-extra.php:311
5425
  msgid "Save New License"
5426
  msgstr "Sauvegarder la Licence"
5427
 
5428
+ #: lib/i18n-extra.php:312
5429
  msgid "Allow, but block dangerous files"
5430
  msgstr "Autoriser, mais bloquer les fichiers dangereux"
5431
 
5432
+ #: lib/i18n-extra.php:313
5433
  msgid "See contextual help for the list of files."
5434
  msgstr ""
5435
  "Consultez l'aide contextuelle pour voir la liste des fichiers concernés."
5436
 
5437
+ #: lib/i18n-extra.php:314
5438
  msgid "Apply to ZIP archives file contents"
5439
  msgstr "Appliquer au contenu des fichiers ZIP"
5440
 
5441
+ #: lib/i18n-extra.php:315
5442
  msgid ""
5443
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
5444
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
5448
  "WordPress WP-Cron, sauf si vous avez ajouté leur adresse IP ou URL dans la "
5449
  "section \"Contrôle d'Accès\"."
5450
 
5451
+ #: lib/i18n-extra.php:316
5452
  #, php-format
5453
  msgid ""
5454
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
5465
  "Erreur : Votre fichier .htaccess n'est pas accessible en écriture. Veuillez "
5466
  "modifier ses autorisations : %s"
5467
 
5468
+ #: lib/install.php:110 ninjafirewall.php:651 ninjafirewall.php:655
5469
  #, php-format
5470
  msgid "Error: wrong parameter value (%s)."
5471
  msgstr "Erreur : Mauvais paramètre (%s)."
5743
  msgid "Error: unable to write to the %s configuration file"
5744
  msgstr "Erreur : impossible d’écrire dans le fichier de configuration %s"
5745
 
5746
+ #: lib/logs.php:36 ninjafirewall.php:925
5747
  msgid "Logs"
5748
  msgstr "Journaux"
5749
 
5813
  msgid "Viewing:"
5814
  msgstr "Journal :"
5815
 
5816
+ #: lib/logs_firewall_log.php:142 lib/logs_firewall_log.php:309
5817
  msgid "The selected log is empty."
5818
  msgstr "Le journal sélectionné est vide."
5819
 
5863
  msgid "Delete Public Key"
5864
  msgstr "Supprimer la clé publique"
5865
 
5866
+ #: lib/logs_firewall_log.php:288
5867
  msgid "The requested log does not exist."
5868
  msgstr "Le journal demandé n'existe pas."
5869
 
5870
+ #: lib/logs_firewall_log.php:295
5871
  msgid "Unable to open the log for read operation."
5872
  msgstr "Impossible de lire le journal."
5873
 
5999
  msgid "Error: please enter the custom log format."
6000
  msgstr "Erreur : veuillez entrer le format d'affichage."
6001
 
6002
+ #: lib/monitoring.php:43 ninjafirewall.php:899
6003
  msgid "Monitoring"
6004
  msgstr "Monitoring"
6005
 
6404
  msgid "Save File Guard options"
6405
  msgstr "Sauvegarder les options"
6406
 
6407
+ #: lib/network.php:24 ninjafirewall.php:1186 ninjafirewall.php:1190
6408
  #, php-format
6409
  msgid "You are not allowed to perform this task (%s)."
6410
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche (%s)."
6436
  msgstr "La tâche planifiée s'est arrêtée, redémarrage en cours (%s)"
6437
 
6438
  #: lib/security_rules.php:44 lib/security_rules_update.php:565
6439
+ #: ninjafirewall.php:929
6440
  msgid "Security Rules"
6441
  msgstr "Règles de Sécurité"
6442
 
6730
 
6731
  #: lib/thickbox.php:79
6732
  msgid ""
6733
+ "Warning, it seems that you are running WordPress in a Docker image: "
6734
+ "activating the Full WAF mode may crash your site. Make sure to read the "
6735
+ "following recommendations:"
6736
+ msgstr ""
6737
+ "Attention, il semble que vous utilisiez WordPress dans une image Docker : "
6738
+ "l'activation du mode Full WAF risque de planter votre site. Assurez-vous de "
6739
+ "lire les recommandations suivantes :"
6740
+
6741
+ #: lib/thickbox.php:79
6742
+ msgid "WordPress and Docker image"
6743
+ msgstr "WordPress and Docker image"
6744
+
6745
+ #: lib/thickbox.php:85
6746
+ msgid ""
6747
  "In Full WAF mode, all scripts located inside the blog installation "
6748
  "directories and sub-directories are protected by NinjaFirewall. It gives you "
6749
  "the highest possible level of protection: security without compromise."
6753
  "Cela vous offre le niveau de protection le plus élevé possible : La sécurité "
6754
  "sans aucun compromis."
6755
 
6756
+ #: lib/thickbox.php:87
6757
  #, php-format
6758
  msgid ""
6759
  "It works on most websites right out of the box, or may require %ssome very "
6765
  "principalement en raison de certaines restrictions d'hébergement partagé, il "
6766
  "se peut que l'installation ne puisse pas fonctionner du tout."
6767
 
6768
+ #: lib/thickbox.php:89
6769
  msgid ""
6770
  "If this happened to you, don't worry: you could still run it in WordPress "
6771
  "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
6776
  "tout de même des performances et un niveau de protection très supérieur aux "
6777
  "autres extensions de sécurité pour WordPress disponibles sur le marché."
6778
 
6779
+ #: lib/thickbox.php:163
6780
  msgid "Select your HTTP server and your PHP server API"
6781
  msgstr "Sélectionnez votre serveur HTTP et PHP SAPI"
6782
 
6783
+ #: lib/thickbox.php:174
6784
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
6785
  msgstr "Autre serveur + CGI/FastCGI ou PHP-FPM"
6786
 
6787
+ #: lib/thickbox.php:176
6788
  msgid "View PHPINFO"
6789
  msgstr "Voir PHPINFO"
6790
 
6791
+ #: lib/thickbox.php:208
6792
  msgid "Select the PHP initialization file supported by your server"
6793
  msgstr ""
6794
  "Sélectionnez le type de fichier de configuration PHP utilisé par votre "
6795
  "serveur"
6796
 
6797
+ #: lib/thickbox.php:219
6798
  msgid "Folders protected by NinjaFirewall"
6799
  msgstr "Répertoires protégés par NinjaFirewall"
6800
 
6801
+ #: lib/thickbox.php:221 lib/thickbox.php:368
6802
  msgid "WordPress root directory:"
6803
  msgstr "Répertoire racine de WordPress :"
6804
 
6805
+ #: lib/thickbox.php:226 lib/thickbox.php:373
6806
  msgid ""
6807
  "The following folders will be protected by NinjaFirewall. If you want to "
6808
  "exclude some of them, uncheck them in the list below:"
6810
  "Les dossiers suivants seront protégés par NinjaFirewall. Si vous souhaitez "
6811
  "en exclure certains, décochez-les dans la liste ci-dessous :"
6812
 
6813
+ #: lib/thickbox.php:232
6814
  msgid ""
6815
  "After setting up the Full WAF mode, you could come back to this page to re-"
6816
  "configure it whenever you want."
6818
  "Après avoir configuré le mode Full WAF, vous pourrez revenir sur cette page "
6819
  "pour le reconfigurer quand vous le souhaitez."
6820
 
6821
+ #: lib/thickbox.php:240
6822
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
6823
  msgstr "Laissez NinjaFirewall faire les changements (recommandé)."
6824
 
6825
+ #: lib/thickbox.php:242
6826
  msgid "I want to make the changes myself."
6827
  msgstr "Je veux faire les changements moi-même."
6828
 
6829
+ #: lib/thickbox.php:244
6830
  msgid ""
6831
  "Please make the changes below, then click on the \"Finish Installation\" "
6832
  "button."
6834
  "Veuillez faire les modifications ci-dessous, puis cliquer sur le bouton "
6835
  "\"Finaliser l'installation\"."
6836
 
6837
+ #: lib/thickbox.php:251
6838
  #, php-format
6839
  msgid ""
6840
  "The %s file must be created, and the following lines of code added to it:"
6842
  "Le fichier %s doit être créé, et les lignes suivantes doivent y être "
6843
  "ajoutées :"
6844
 
6845
+ #: lib/thickbox.php:252
6846
  #, php-format
6847
  msgid "The following lines of code must be added to your existing %s file:"
6848
  msgstr "Les lignes suivantes doivent être ajoutées à votre fichier %s :"
6849
 
6850
+ #: lib/thickbox.php:320
6851
  msgid ""
6852
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
6853
  "select your domain, add the following instructions to the \"php.ini Override"
6858
  "section \"php.ini Override\" de l'onglet \"Général\", puis redémarrez "
6859
  "Openlitespeed:"
6860
 
6861
+ #: lib/thickbox.php:327
6862
  msgid ""
6863
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
6864
  "to remove these instructions from your Openlitespeed admin dashboard "
6870
  "<strong>avant</strong> de désinstaller NinjaFirewall, car cet installateur "
6871
  "ne pourra pas le faire à votre place."
6872
 
6873
+ #: lib/thickbox.php:343
6874
  msgid "Enable the sandbox."
6875
  msgstr "Activer l'environnement de test (sandbox)."
6876
 
6877
+ #: lib/thickbox.php:343
6878
  msgid ""
6879
  "If there were a problem during the installation, NinjaFirewall would undo "
6880
  "those changes automatically for you."
6882
  "S'il y avait un problème lors de l'installation, NinjaFirewall annulerait "
6883
  "ces modifications automatiquement pour vous."
6884
 
6885
+ #: lib/thickbox.php:344
6886
  msgid "Finish Installation"
6887
  msgstr "Finaliser l'installation"
6888
 
6889
+ #: lib/thickbox.php:362
6890
  msgid "Configuration"
6891
  msgstr "Configuration"
6892
 
6893
+ #: lib/thickbox.php:366
6894
  msgid "Full WAF mode"
6895
  msgstr "Mode Full WAF"
6896
 
6897
+ #: lib/thickbox.php:380
6898
  msgid "Save Changes"
6899
  msgstr "Sauvegarder les modifications"
6900
 
6901
+ #: lib/thickbox.php:391
6902
  msgid "WordPress WAF mode"
6903
  msgstr "Mode WordPress WAF"
6904
 
6905
+ #: lib/thickbox.php:398
6906
  msgid ""
6907
  "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
6908
  "admin dashboard, click on \"Virtual Host\", select your domain and remove "
6914
  "votre domaine, enlevez la directive \"auto_prepend_file\" de la section "
6915
  "\"php.ini Override\" de l'onglet \"Général\", puis redémarrez Openlitespeed."
6916
 
6917
+ #: lib/thickbox.php:399 lib/thickbox.php:406
6918
  msgid "Downgrade to WordPress WAF mode"
6919
  msgstr "Revenir au mode WordPress WAF"
6920
 
6921
+ #: lib/thickbox.php:403
6922
  msgid "If you want to downgrade to WordPress WAF mode, click the button below."
6923
  msgstr ""
6924
  "Si vous souhaitez revenir au mode WordPress WAF, cliquez sur le bouton ci-"
6925
  "dessous."
6926
 
6927
+ #: lib/thickbox.php:408
6928
  msgid "You may have to wait five minutes for the changes to take effect."
6929
  msgstr ""
6930
  "Vous devrez peut-être attendre cinq minutes pour que les modifications "
6931
  "prennent effet."
6932
 
6933
+ #: lib/thickbox.php:415
6934
  msgid "Cancel and Close"
6935
  msgstr "Annuler et Fermer"
6936
 
6937
+ #: lib/utils.php:188 lib/utils.php:196 lib/utils.php:294
6938
  msgid "N/A"
6939
  msgstr "N/A"
6940
 
6948
  msgid "Attempt to edit a published %s (ID: %s)"
6949
  msgstr "Tentative de modification de %s (ID: %s)"
6950
 
6951
+ #: lib/utils.php:212 lib/utils.php:286
6952
  msgid "Unauthenticated user"
6953
  msgstr "Utilisateur non authentifié"
6954
 
6964
  "NinjaFirewall a bloqué une tentative de modification/création d'une page ou "
6965
  "d'un article par un utilisateur qui n'avait pas les capacités nécessaires :"
6966
 
6967
+ #: lib/utils.php:226 lib/utils.php:306 lib/utils.php:424 lib/utils.php:1255
6968
  msgid "Username:"
6969
  msgstr "Utilisateur :"
6970
 
6972
  msgid "Action:"
6973
  msgstr "Action :"
6974
 
6975
+ #: lib/utils.php:242 lib/utils.php:321 lib/utils.php:437 lib/utils.php:1271
6976
+ #: lib/utils.php:1518
6977
  msgid "A PHP backtrace has been attached to this message for your convenience."
6978
  msgstr ""
6979
  "La pile d'exécution de PHP est jointe à ce message pour votre commodité."
6980
 
6981
+ #: lib/utils.php:244 lib/utils.php:323 lib/utils.php:1273 lib/utils.php:1528
6982
  msgid ""
6983
  "This protection (and notification) can be turned off from NinjaFirewall "
6984
  "\"Firewall Policies\" page."
6986
  "Cette protection (et notification) peut être désactivée à partir de la page "
6987
  "\"Politiques du Pare-feu\" de NinjaFirewall."
6988
 
6989
+ #: lib/utils.php:258 lib/utils.php:259 lib/utils.php:337 lib/utils.php:338
6990
+ #: lib/utils.php:453 lib/utils.php:454 lib/utils.php:1288 lib/utils.php:1289
6991
  msgid "You are not allowed to perform this task."
6992
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche."
6993
 
6994
+ #: lib/utils.php:297
6995
  msgid "Blocked post/page deletion attempt"
6996
  msgstr "Tentative de suppression de page/article bloquée"
6997
 
6998
+ #: lib/utils.php:304
6999
  msgid ""
7000
  "NinjaFirewall has blocked an attempt to delete a post by a user who doesn't "
7001
  "have the right capabilities:"
7003
  "NinjaFirewall a bloqué une tentative de suppression d'une page ou d'un "
7004
  "article par un utilisateur qui n'avait pas les capacités nécessaires :"
7005
 
7006
+ #: lib/utils.php:414
7007
  msgid "Blocked user account creation"
7008
  msgstr "Création de compte d'utilisateur bloquée"
7009
 
7010
+ #: lib/utils.php:421
7011
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
7012
  msgstr ""
7013
  "NinjaFirewall a bloqué une tentative de création d'un compte d'utilisateur :"
7014
 
7015
+ #: lib/utils.php:518
7016
  #, php-format
7017
  msgid "Backup file is corrupted, deleting it (%s)"
7018
  msgstr "Le fichier de sauvegarde est corrompu, suppression en cours (%s)"
7019
 
7020
+ #: lib/utils.php:526
7021
  #, php-format
7022
  msgid ""
7023
  "NinjaFirewall's options are corrupted, restoring them from last known good "
7026
  "Les options de NinjaFirewall sont corrompues, tentative de restauration à "
7027
  "partir du dernier fichier de sauvegarde connu (%s)"
7028
 
7029
+ #: lib/utils.php:532
7030
  msgid ""
7031
  "NinjaFirewall's options are corrupted, restoring their default values (no "
7032
  "valid backup found)"
7034
  "Les options de NinjaFirewall sont corrompues, restauration des valeurs par "
7035
  "défaut (il n'existe pas de fichier de sauvegarde)"
7036
 
7037
+ #: lib/utils.php:758
7038
  msgid ""
7039
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
7040
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
7045
  "concernant le test de la requête de bouclage (ex.: code d’état HTTP 404 ou "
7046
  "401). Vous pouvez l'ignorer en toute sécurité."
7047
 
7048
+ #: lib/utils.php:781 lib/utils.php:785
7049
  msgid "NinjaFirewall error"
7050
  msgstr "NinjaFirewall Erreur"
7051
 
7052
+ #: lib/utils.php:782
7053
  #, php-format
7054
  msgid ""
7055
  "%s directory cannot be created. Please review your installation and ensure "
7058
  "Le répertoire %s ne peut pas être créé. Vérifiez votre installation et "
7059
  "assurez vous que %s n'est pas en lecture seule."
7060
 
7061
+ #: lib/utils.php:786
7062
  #, php-format
7063
  msgid ""
7064
  "%s directory is read-only. Please review your installation and ensure that "
7067
  "Le répertoire %s est en lecture seule. Vérifiez votre installation et les "
7068
  "permissions de %s."
7069
 
7070
+ #: lib/utils.php:801
7071
  msgid "unknown error"
7072
  msgstr "erreur inconnue"
7073
 
7074
+ #: lib/utils.php:803
7075
  msgid "NinjaFirewall fatal error:"
7076
  msgstr "NinjaFirewall erreur fatale :"
7077
 
7078
+ #: lib/utils.php:804
7079
  msgid "Review your installation, your site is not protected."
7080
  msgstr "Vérifiez votre installation, votre site n'est pas protégé."
7081
 
7082
+ #: lib/utils.php:825
7083
  msgid "Alert: WordPress console login"
7084
  msgstr "Alerte : Connexion à WordPress"
7085
 
7086
+ #: lib/utils.php:831
7087
  msgid "Someone just logged in to your WordPress admin console:"
7088
  msgstr "Quelqu'un vient de se connecter à votre Tableau de bord de WordPress:"
7089
 
7090
+ #: lib/utils.php:949 lib/utils.php:976
7091
  msgid "Forbidden access"
7092
  msgstr "Accès interdit"
7093
 
7094
+ #: lib/utils.php:995
7095
  #, php-format
7096
  msgid ""
7097
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
7100
  "<strong>ERREUR</strong>: Identifiant, email ou mot de passe invalide.<br /"
7101
  "><a href=\"%s\">Mot de passe perdu</a> ?"
7102
 
7103
+ #: lib/utils.php:1073
7104
  msgid "[NinjaFirewall] Alert: Database changes detected"
7105
  msgstr "[NinjaFirewall] Alerte: Modification dans la base de données"
7106
 
7107
+ #: lib/utils.php:1074
7108
  msgid ""
7109
  "NinjaFirewall has detected that one or more administrator accounts were "
7110
  "modified in the database:"
7112
  "NinjaFirewall a détecté que un ou plusieurs comptes d'administrateur ont été "
7113
  "modifiés dans la base de données:"
7114
 
7115
+ #: lib/utils.php:1079
7116
  #, php-format
7117
  msgid "Total administrators : %s"
7118
  msgstr "Nombre d'administrateurs : %s"
7119
 
7120
+ #: lib/utils.php:1088
7121
  msgid ""
7122
  "If you cannot see any modifications in the above fields, it is possible that "
7123
  "the administrator password was changed."
7125
  "Si vous ne voyez pas de modifications dans les données ci-dessus, il est "
7126
  "possible que le mot de passe administrateur ait été changé."
7127
 
7128
+ #: lib/utils.php:1241
7129
  msgid "Blocked privilege escalation attempt"
7130
  msgstr "Tentatives d'élévation des privilèges"
7131
 
7132
+ #: lib/utils.php:1249
7133
  msgid ""
7134
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
7135
  "who does not have administrative privileges:"
7137
  "NinjaFirewall a bloqué une tentative de modification de certaines Capacités "
7138
  "par un utilisateur ne disposant pas de privilèges administratifs :"
7139
 
7140
+ #: lib/utils.php:1300
7141
  msgid ""
7142
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
7143
  "whitelisted."
7145
  "La protection de NinjaFirewall contre les attaques par force brute est "
7146
  "activée. Vous êtes temporairement dans la liste blanche."
7147
 
7148
+ #: lib/utils.php:1315
7149
  #, php-format
7150
  msgid ""
7151
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
7158
  "a>. Il a fallu des milliers d'heures pour le développer, mais il suffit "
7159
  "seulement de quelques minutes pour le noter. Merci !"
7160
 
7161
+ #: lib/utils.php:1490
7162
  msgid ""
7163
  "The attempt was blocked and the option was reversed to its original value."
7164
  msgstr ""
7165
  "La tentative a été bloquée et l'option a été remise à sa valeur d'origine."
7166
 
7167
+ #: lib/utils.php:1495
7168
  msgid "Attempt to modify WordPress settings"
7169
  msgstr "Tentative de modification des paramètres de WordPress"
7170
 
7171
+ #: lib/utils.php:1496
7172
  msgid ""
7173
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
7174
  "settings by a user that does not have administrative privileges:"
7177
  "importants de WordPress par un utilisateur ne disposant pas de privilèges "
7178
  "administratifs :"
7179
 
7180
+ #: lib/utils.php:1497 lib/utils.php:1506
7181
  #, php-format
7182
  msgid "Option: %s"
7183
  msgstr "Option: %s"
7184
 
7185
+ #: lib/utils.php:1498
7186
  #, php-format
7187
  msgid "Original value: %s"
7188
  msgstr "Valeur originale : %s"
7189
 
7190
+ #: lib/utils.php:1499
7191
  #, php-format
7192
  msgid "Modified value: %s"
7193
  msgstr "Valeur modifiée : %s"
7194
 
7195
+ #: lib/utils.php:1500 lib/utils.php:1508
7196
  #, php-format
7197
  msgid "Action taken: %s"
7198
  msgstr "Action prise : %s"
7199
 
7200
+ #: lib/utils.php:1504
7201
  msgid "Code injection attempt in WordPress options table"
7202
  msgstr "Tentative d'injection de code dans la table des options de WordPress"
7203
 
7204
+ #: lib/utils.php:1505
7205
  msgid ""
7206
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
7207
  "table by a user that does not have administrative privileges:"
7210
  "options de WordPress par un utilisateur ne disposant pas de privilèges "
7211
  "administratifs :"
7212
 
7213
+ #: lib/utils.php:1507
7214
  #, php-format
7215
  msgid "Code: %s"
7216
  msgstr "Code : %s"
7217
 
7218
+ #: lib/utils.php:1607
7219
  msgid "Important: NinjaFirewall has detected that this is a security update."
7220
  msgstr ""
7221
  "Important : NinjaFirewall a détecté que ceci est un mise à jour de sécurité."
7222
 
7223
+ #: lib/utils.php:1610
7224
  msgid "More info about this warning."
7225
  msgstr "En savoir plus."
7226
 
7227
+ #: lib/utils.php:1633
7228
  #, php-format
7229
  msgid "Cannot send notification, no valid email found (%s)"
7230
  msgstr ""
7231
  "Impossible d'envoyer la notification, aucune adresse e-mail valide n'a été "
7232
  "trouvée (%s)"
7233
 
7234
+ #: lib/utils.php:1658
7235
  #, php-format
7236
  msgid ""
7237
  "If you don't have access to that site any longer, you can remove your email "
7240
  "Si vous n'avez plus accès à ce site, vous pouvez supprimer votre e-mail en "
7241
  "cliquant sur le lien suivant (valide pendant 12 heures) : %s"
7242
 
7243
+ #: lib/utils.php:1684
7244
  #, php-format
7245
  msgid "Error, cannot create the %s folder."
7246
  msgstr "Erreur, impossible de créer le répertoire %s."
7247
 
7248
+ #: lib/utils.php:1685 lib/utils.php:1694 lib/utils.php:1703
7249
  msgid "Check your server permissions and try again."
7250
  msgstr "Vérifiez les autorisations de votre serveur et réessayez."
7251
 
7252
+ #: lib/utils.php:1693
7253
  #, php-format
7254
  msgid "Error, the %s folder is not writable."
7255
  msgstr "Erreur, le répertoire %s est en lecture seule."
7256
 
7257
+ #: lib/utils.php:1702
7258
  #, php-format
7259
  msgid "Error, cannot write %s."
7260
  msgstr "Erreur, impossible d'écrire dans %s."
7283
  msgid "View firewall log"
7284
  msgstr "Voir le journal du pare-feu"
7285
 
7286
+ #: lib/widget.php:115
7287
+ msgid "Latest News from NinTechNet"
7288
+ msgstr "Dernières Articles de NinTechNet"
7289
 
7290
+ #: lib/widget.php:119
7291
  msgid "M jS, Y"
7292
  msgstr "M jS, Y"
7293
 
7294
+ #: lib/widget.php:130
7295
  msgid "More Security News"
7296
  msgstr "Autres Articles sur la Sécurité"
7297
 
7298
+ #: lib/widget.php:130
7299
  msgid "(opens in a new tab)"
7300
  msgstr ""
7301
 
7302
+ #: lib/widget.php:130
7303
  msgid "NinjaFirewall's Home"
7304
  msgstr "Site de NinjaFirewall"
7305
 
7953
  msgid "Error: The HTTP server returned the following error code:"
7954
  msgstr "Erreur : Le serveur HTTP a retourné le code d'erreur suivant :"
7955
 
7956
+ #: ninjafirewall.php:636 ninjafirewall.php:756 ninjafirewall.php:825
7957
  msgid "Error: Security nonces do not match. Reload the page and try again."
7958
  msgstr ""
7959
  "Erreur : Les nonces de sécurité ne correspondent pas. Veuillez recharger "
7960
  "cette page."
7961
 
7962
+ #: ninjafirewall.php:642
7963
  msgid "Error: NinjaFirewall is disabled"
7964
  msgstr "Erreur : NinjaFirewall est désactivé"
7965
 
7966
+ #: ninjafirewall.php:647 ninjafirewall.php:761 ninjafirewall.php:791
7967
  #, php-format
7968
  msgid "Error: missing parameter (%s)."
7969
  msgstr "Erreur : Paramètre manquant (%s)."
7970
 
7971
+ #: ninjafirewall.php:887
7972
  msgid "NinjaFirewall: Dashboard"
7973
  msgstr "NinjaFirewall : Tableau de Bord"
7974
 
7975
+ #: ninjafirewall.php:891
7976
  msgid "NinjaFirewall: Firewall Options"
7977
  msgstr "NinjaFirewall : Options du Pare-feu"
7978
 
7979
+ #: ninjafirewall.php:895
7980
  msgid "NinjaFirewall: Firewall Policies"
7981
  msgstr "NinjaFirewall : Politiques du Pare-feu"
7982
 
7983
+ #: ninjafirewall.php:899
7984
  msgid "NinjaFirewall: Monitoring"
7985
  msgstr "NinjaFirewall : Monitoring"
7986
 
7987
+ #: ninjafirewall.php:909
7988
  msgid "NinjaFirewall: Anti-Malware"
7989
  msgstr "NinjaFirewall : Anti-Malware"
7990
 
7991
+ #: ninjafirewall.php:913
7992
  msgid "NinjaFirewall: Network"
7993
  msgstr "NinjaFirewall : Réseau"
7994
 
7995
+ #: ninjafirewall.php:917
7996
  msgid "NinjaFirewall: Event Notifications"
7997
  msgstr "NinjaFirewall : Notifications d’Événement"
7998
 
7999
+ #: ninjafirewall.php:921
8000
  msgid "NinjaFirewall: Log-in Protection"
8001
  msgstr "NinjaFirewall : Page de Connexion"
8002
 
8003
+ #: ninjafirewall.php:925
8004
  msgid "NinjaFirewall: Logs"
8005
  msgstr "NinjaFirewall : Journaux"
8006
 
8007
+ #: ninjafirewall.php:929
8008
  msgid "NinjaFirewall: Security Rules"
8009
  msgstr "NinjaFirewall : Règles de Sécurité"
8010
 
8011
+ #: ninjafirewall.php:973
8012
  msgid "NinjaFirewall Settings"
8013
  msgstr "Réglages de NinjaFirewall"
8014
 
8015
+ #: ninjafirewall.php:981
8016
  msgid "NinjaFirewall is enabled"
8017
  msgstr "NinjaFirewall est activé"
8018
 
8019
+ #: ninjafirewall.php:1121
8020
  msgid "Access Restricted"
8021
  msgstr "Accès limité"
8022
 
8023
+ #: ninjafirewall.php:1127
8024
  msgid "Settings"
8025
  msgstr "Réglages"
8026
 
8027
+ #: ninjafirewall.php:1128
8028
  msgid "Upgrade to Premium"
8029
  msgstr "Passez Premium !"
8030
 
8031
+ #: ninjafirewall.php:1129
8032
  msgid "Rate it!"
8033
  msgstr "Notez-le !"
8034
 
8035
+ #~ msgid "Cannot check if the PHP INI file is readable: connection error"
8036
+ #~ msgstr ""
8037
+ #~ "Impossible de vérifier si le fichier PHP INI est protégé : erreur de "
8038
+ #~ "connexion"
8039
+
8040
+ #~ msgid "NinjaFirewall Referral Program"
8041
+ #~ msgstr "Programme de parrainage de NinjaFirewall"
8042
+
8043
+ #~ msgid "Referral Program"
8044
+ #~ msgstr "Programme de parrainage"
8045
+
8046
+ #~ msgid "Latest Security News"
8047
+ #~ msgstr "Dernières Articles sur la Sécurité"
8048
+
8049
  #~ msgid ""
8050
  #~ "In the Premium version of NinjaFirewall, the Access Control section "
8051
  #~ "allows you to whitelist WordPress users depending on their roles."
languages/ninjafirewall.pot CHANGED
@@ -2,7 +2,7 @@
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Stable (latest release)\n"
5
- "POT-Creation-Date: 2021-09-17 15:59+0700\n"
6
  "PO-Revision-Date: 2018-04-05 22:52+0700\n"
7
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
8
  "Language-Team: \n"
@@ -19,7 +19,7 @@ msgstr ""
19
  "X-Poedit-SearchPath-0: .\n"
20
  "X-Poedit-SearchPathExcluded-0: /languages\n"
21
 
22
- #: lib/anti_malware.php:24 ninjafirewall.php:914
23
  msgid "Anti-Malware"
24
  msgstr ""
25
 
@@ -98,7 +98,7 @@ msgstr ""
98
  msgid "Your changes have been saved."
99
  msgstr ""
100
 
101
- #: lib/dashboard.php:132 ninjafirewall.php:892
102
  msgid "Dashboard"
103
  msgstr ""
104
 
@@ -403,10 +403,6 @@ msgstr ""
403
  msgid "Help &amp; configuration"
404
  msgstr ""
405
 
406
- #: lib/dashboard.php:515
407
- msgid "Cannot check if the PHP INI file is readable: connection error"
408
- msgstr ""
409
-
410
  #: lib/dashboard_about.php:29
411
  msgid "Our blog:"
412
  msgstr ""
@@ -425,10 +421,6 @@ msgstr ""
425
  msgid "Rate it on WordPress.org!"
426
  msgstr ""
427
 
428
- #: lib/dashboard_about.php:33
429
- msgid "NinjaFirewall Referral Program"
430
- msgstr ""
431
-
432
  #: lib/dashboard_statistics.php:76
433
  msgid "You do not have any stats for the selected month yet."
434
  msgstr ""
@@ -514,8 +506,8 @@ msgstr ""
514
  #: lib/email_sodium.php:169 lib/monitoring_file_check.php:759
515
  #: lib/monitoring_file_check.php:761 lib/monitoring_file_check.php:781
516
  #: lib/monitoring_file_check.php:783 lib/security_rules_update.php:559
517
- #: lib/security_rules_update.php:561 lib/utils.php:225 lib/utils.php:306
518
- #: lib/utils.php:425 lib/utils.php:1038 lib/utils.php:1212 lib/utils.php:1484
519
  msgid "Blog:"
520
  msgstr ""
521
 
@@ -523,14 +515,14 @@ msgstr ""
523
  msgid "Email address:"
524
  msgstr ""
525
 
526
- #: lib/email_sodium.php:171 lib/utils.php:230 lib/utils.php:310
527
- #: lib/utils.php:427 lib/utils.php:1220 lib/utils.php:1485
528
  msgid "User IP:"
529
  msgstr ""
530
 
531
  #: lib/email_sodium.php:172 lib/event_updates.php:157 lib/utils.php:233
532
- #: lib/utils.php:313 lib/utils.php:430 lib/utils.php:1039 lib/utils.php:1223
533
- #: lib/utils.php:1488
534
  msgid "Date:"
535
  msgstr ""
536
 
@@ -561,7 +553,7 @@ msgstr ""
561
  msgid "No"
562
  msgstr ""
563
 
564
- #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:922
565
  msgid "Event Notifications"
566
  msgstr ""
567
 
@@ -745,40 +737,40 @@ msgstr ""
745
  msgid "Save Event Notifications"
746
  msgstr ""
747
 
748
- #: lib/event_notifications.php:476
749
  msgid "[NinjaFirewall] Daily Activity Report"
750
  msgstr ""
751
 
752
- #: lib/event_notifications.php:486
753
  #, php-format
754
  msgid "Daily activity report for: %s"
755
  msgstr ""
756
 
757
- #: lib/event_notifications.php:487
758
  msgid "Date Range Processed: Yesterday"
759
  msgstr ""
760
 
761
- #: lib/event_notifications.php:489
762
  msgid "Blocked threats:"
763
  msgstr ""
764
 
765
- #: lib/event_notifications.php:491
766
  msgid "critical:"
767
  msgstr ""
768
 
769
- #: lib/event_notifications.php:492
770
  msgid "high:"
771
  msgstr ""
772
 
773
- #: lib/event_notifications.php:493
774
  msgid "medium:"
775
  msgstr ""
776
 
777
- #: lib/event_notifications.php:495
778
  msgid "Blocked brute-force attacks:"
779
  msgstr ""
780
 
781
- #: lib/event_notifications.php:496 lib/event_updates.php:219 lib/utils.php:1050
782
  msgid ""
783
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
784
  "\" page."
@@ -840,7 +832,7 @@ msgstr ""
840
  msgid "Theme: %s"
841
  msgstr ""
842
 
843
- #: lib/event_updates.php:217 lib/utils.php:1566
844
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
845
  msgstr ""
846
 
@@ -873,12 +865,12 @@ msgstr ""
873
  msgid "activated"
874
  msgstr ""
875
 
876
- #: lib/events.php:45 lib/events.php:93 lib/events.php:173 lib/events.php:185
877
  msgid "deleted"
878
  msgstr ""
879
 
880
  #: lib/events.php:81 lib/events.php:103 lib/events.php:118 lib/events.php:122
881
- #: lib/events.php:138 lib/events.php:147 lib/events.php:169 lib/events.php:181
882
  msgid "updated"
883
  msgstr ""
884
 
@@ -886,40 +878,40 @@ msgstr ""
886
  msgid "deactivated"
887
  msgstr ""
888
 
889
- #: lib/events.php:130 lib/events.php:151 lib/events.php:165 lib/events.php:177
890
  msgid "installed"
891
  msgstr ""
892
 
893
- #: lib/events.php:134 lib/events.php:155
894
  msgid "uploaded"
895
  msgstr ""
896
 
897
- #: lib/events.php:195
898
  #, php-format
899
  msgid "[NinjaFirewall] Alert: %s"
900
  msgstr ""
901
 
902
- #: lib/events.php:197 lib/events.php:199 lib/utils.php:787
903
  msgid "-Blog:"
904
  msgstr ""
905
 
906
- #: lib/events.php:202
907
  msgid "NinjaFirewall has detected the following activity on your account:"
908
  msgstr ""
909
 
910
- #: lib/events.php:204 lib/utils.php:792
911
  msgid "-User:"
912
  msgstr ""
913
 
914
- #: lib/events.php:205 lib/utils.php:793
915
  msgid "-IP:"
916
  msgstr ""
917
 
918
- #: lib/events.php:206 lib/utils.php:794
919
  msgid "-Date:"
920
  msgstr ""
921
 
922
- #: lib/firewall_options.php:29 ninjafirewall.php:896
923
  msgid "Firewall Options"
924
  msgstr ""
925
 
@@ -1117,7 +1109,7 @@ msgid ""
1117
  "enable NinjaFirewall's Full WAF mode."
1118
  msgstr ""
1119
 
1120
- #: lib/firewall_policies.php:62 ninjafirewall.php:900
1121
  msgid "Firewall Policies"
1122
  msgstr ""
1123
 
@@ -1257,7 +1249,7 @@ msgid ""
1257
  "not have the right capabilities"
1258
  msgstr ""
1259
 
1260
- #: lib/firewall_policies.php:411 lib/thickbox.php:89
1261
  msgid "(recommended)"
1262
  msgstr ""
1263
 
@@ -1617,61 +1609,83 @@ msgstr ""
1617
  msgid "Set %s (Chrome, Opera and Firefox browsers)"
1618
  msgstr ""
1619
 
1620
- #: lib/firewall_policies.php:1018
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1621
  msgid ""
1622
  "Block PHP built-in wrappers in <code>GET</code>, <code>POST</code>, "
1623
  "<code>HTTP_USER_AGENT</code>, <code>HTTP_REFERER</code> and cookies"
1624
  msgstr ""
1625
 
1626
- #: lib/firewall_policies.php:1057
1627
  msgid "Block serialized PHP objects in the following global variables"
1628
  msgstr ""
1629
 
1630
- #: lib/firewall_policies.php:1067 lib/help.php:295
1631
  msgid "Block attempts to override PHP Superglobals"
1632
  msgstr ""
1633
 
1634
- #: lib/firewall_policies.php:1073 lib/help.php:297
1635
  msgid "Hide PHP notice and error messages"
1636
  msgstr ""
1637
 
1638
- #: lib/firewall_policies.php:1079
1639
  msgid "Sanitise <code>PHP_SELF</code>"
1640
  msgstr ""
1641
 
1642
- #: lib/firewall_policies.php:1085
1643
  msgid "Sanitise <code>PATH_TRANSLATED</code>"
1644
  msgstr ""
1645
 
1646
- #: lib/firewall_policies.php:1091
1647
  msgid "Sanitise <code>PATH_INFO</code>"
1648
  msgstr ""
1649
 
1650
- #: lib/firewall_policies.php:1105
1651
  msgid "This option is not compatible with your actual configuration."
1652
  msgstr ""
1653
 
1654
- #: lib/firewall_policies.php:1127 lib/help.php:301
1655
  msgid "Various"
1656
  msgstr ""
1657
 
1658
- #: lib/firewall_policies.php:1130
1659
  msgid "Block the <code>DOCUMENT_ROOT</code> server variable in HTTP request"
1660
  msgstr ""
1661
 
1662
- #: lib/firewall_policies.php:1137 lib/help.php:304
1663
  msgid "Block ASCII character 0x00 (NULL byte)"
1664
  msgstr ""
1665
 
1666
- #: lib/firewall_policies.php:1143 lib/help.php:306
1667
  msgid "Block ASCII control characters 1 to 8 and 14 to 31"
1668
  msgstr ""
1669
 
1670
- #: lib/firewall_policies.php:1156
1671
  msgid "Save Firewall Policies"
1672
  msgstr ""
1673
 
1674
- #: lib/firewall_policies.php:1158
1675
  msgid "Restore Default Values"
1676
  msgstr ""
1677
 
@@ -2475,7 +2489,7 @@ msgid ""
2475
  "package (third-party software, shell script, backdoor etc)."
2476
  msgstr ""
2477
 
2478
- #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:918
2479
  msgid "Network"
2480
  msgstr ""
2481
 
@@ -2511,7 +2525,7 @@ msgid ""
2511
  "theme in order to take full control of your website."
2512
  msgstr ""
2513
 
2514
- #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:926
2515
  msgid "Login Protection"
2516
  msgstr ""
2517
 
@@ -2969,66 +2983,62 @@ msgid "NinjaFirewall: Antispam"
2969
  msgstr ""
2970
 
2971
  #: lib/i18n-extra.php:21
2972
- msgid "Referral Program"
2973
- msgstr ""
2974
-
2975
- #: lib/i18n-extra.php:22
2976
  msgid "License"
2977
  msgstr ""
2978
 
2979
- #: lib/i18n-extra.php:23
2980
  msgid "Enter your NinjaFirewall WP+ license and click on the save button"
2981
  msgstr ""
2982
 
2983
- #: lib/i18n-extra.php:24
2984
  msgid "Don't have a license yet?"
2985
  msgstr ""
2986
 
2987
- #: lib/i18n-extra.php:25
2988
  msgid "Click here to get one"
2989
  msgstr ""
2990
 
2991
- #: lib/i18n-extra.php:26
2992
  msgid "Save License"
2993
  msgstr ""
2994
 
2995
- #: lib/i18n-extra.php:27
2996
  msgid "This license has expired and is no longer valid."
2997
  msgstr ""
2998
 
2999
- #: lib/i18n-extra.php:28
3000
  msgid "Your license is not valid"
3001
  msgstr ""
3002
 
3003
- #: lib/i18n-extra.php:29
3004
  msgid ""
3005
  "An unknown error occurred while connecting to NinjaFirewall servers. Please "
3006
  "try again in a few minutes"
3007
  msgstr ""
3008
 
3009
- #: lib/i18n-extra.php:30
3010
  msgid ""
3011
  "An error occurred while connecting to NinjaFirewall servers. Please try "
3012
  "again in a few minutes"
3013
  msgstr ""
3014
 
3015
- #: lib/i18n-extra.php:31
3016
  msgid "Your NinaFirewall license has expired!"
3017
  msgstr ""
3018
 
3019
- #: lib/i18n-extra.php:32
3020
  msgid "Click here to renew it"
3021
  msgstr ""
3022
 
3023
- #: lib/i18n-extra.php:33
3024
  msgid "Your NinaFirewall license will expire soon!"
3025
  msgstr ""
3026
 
3027
- #: lib/i18n-extra.php:34
3028
  msgid "You do not have a valid NinjaFirewall license"
3029
  msgstr ""
3030
 
3031
- #: lib/i18n-extra.php:35
3032
  #, php-format
3033
  msgid ""
3034
  "The shared memory block seems corrupted. Try to reload this page to fix it "
@@ -3036,12 +3046,12 @@ msgid ""
3036
  "to avoid any problem."
3037
  msgstr ""
3038
 
3039
- #: lib/i18n-extra.php:36
3040
  #, php-format
3041
  msgid "(RAM usage: %s bytes)"
3042
  msgstr ""
3043
 
3044
- #: lib/i18n-extra.php:37
3045
  #, php-format
3046
  msgid ""
3047
  "Unable to access/read the shared memory block. Try to reload this page or, "
@@ -3049,15 +3059,15 @@ msgid ""
3049
  "avoid any problem."
3050
  msgstr ""
3051
 
3052
- #: lib/i18n-extra.php:38
3053
  msgid "Firewall is disabled"
3054
  msgstr ""
3055
 
3056
- #: lib/i18n-extra.php:39
3057
  msgid "Shared memory"
3058
  msgstr ""
3059
 
3060
- #: lib/i18n-extra.php:40
3061
  #, php-format
3062
  msgid ""
3063
  "You are not whitelisted. Ensure that the \"Do not block the following users"
@@ -3066,62 +3076,62 @@ msgid ""
3066
  "from the WordPress administration dashboard."
3067
  msgstr ""
3068
 
3069
- #: lib/i18n-extra.php:41
3070
  #, php-format
3071
  msgid ""
3072
  "<a href=\"%s\">Access Control Source IP</a> is setup to use %s, however your "
3073
  "server does not support that variable. All IP-based directives will fail."
3074
  msgstr ""
3075
 
3076
- #: lib/i18n-extra.php:42
3077
  #, php-format
3078
  msgid "You have a private IP: %s"
3079
  msgstr ""
3080
 
3081
- #: lib/i18n-extra.php:43
3082
  #, php-format
3083
  msgid ""
3084
  "If your site is behind a reverse proxy or a load balancer, ensure that the "
3085
  "<a href=\"%s\">Source IP</a> is setup accordingly."
3086
  msgstr ""
3087
 
3088
- #: lib/i18n-extra.php:44
3089
  #, php-format
3090
  msgid ""
3091
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that the "
3092
  "<a href=\"%s\">Source IP</a> is setup accordingly."
3093
  msgstr ""
3094
 
3095
- #: lib/i18n-extra.php:45
3096
  #, php-format
3097
  msgid ""
3098
  "%s detected: you seem to be using Incapsula CDN services. Ensure that the <a "
3099
  "href=\"%s\">Source IP</a> is setup accordingly."
3100
  msgstr ""
3101
 
3102
- #: lib/i18n-extra.php:46
3103
  msgid "Logging"
3104
  msgstr ""
3105
 
3106
- #: lib/i18n-extra.php:47
3107
  msgid "Logging is disabled."
3108
  msgstr ""
3109
 
3110
- #: lib/i18n-extra.php:48
3111
  msgid "Click here to re-enable it."
3112
  msgstr ""
3113
 
3114
- #: lib/i18n-extra.php:49
3115
  #, php-format
3116
  msgid "Error cannot create the language files directory (%s)"
3117
  msgstr ""
3118
 
3119
- #: lib/i18n-extra.php:50
3120
  #, php-format
3121
  msgid "Error while downloading language file %s (%s)"
3122
  msgstr ""
3123
 
3124
- #: lib/i18n-extra.php:51
3125
  #, php-format
3126
  msgid ""
3127
  "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
@@ -3131,386 +3141,386 @@ msgid ""
3131
  "the Dashboard page%s and enable NinjaFirewall's Full WAF mode."
3132
  msgstr ""
3133
 
3134
- #: lib/i18n-extra.php:52
3135
  msgid "General"
3136
  msgstr ""
3137
 
3138
- #: lib/i18n-extra.php:53
3139
  msgid "Geolocation"
3140
  msgstr ""
3141
 
3142
- #: lib/i18n-extra.php:54
3143
  msgid "IP address"
3144
  msgstr ""
3145
 
3146
- #: lib/i18n-extra.php:55
3147
  msgid "URL address"
3148
  msgstr ""
3149
 
3150
- #: lib/i18n-extra.php:56
3151
  msgid "Bot"
3152
  msgstr ""
3153
 
3154
- #: lib/i18n-extra.php:57
3155
  msgid "User Input"
3156
  msgstr ""
3157
 
3158
- #: lib/i18n-extra.php:58
3159
  msgid "Role-based Access Control"
3160
  msgstr ""
3161
 
3162
- #: lib/i18n-extra.php:59
3163
  msgid "Do not block the following users (must be logged in)"
3164
  msgstr ""
3165
 
3166
- #: lib/i18n-extra.php:60
3167
  msgid "Retrieve visitors IP address from"
3168
  msgstr ""
3169
 
3170
- #: lib/i18n-extra.php:61
3171
  msgid "Other"
3172
  msgstr ""
3173
 
3174
- #: lib/i18n-extra.php:62
3175
  #, php-format
3176
  msgid "Your server does not seem to support the %s variable."
3177
  msgstr ""
3178
 
3179
- #: lib/i18n-extra.php:63
3180
  msgid "HTTP Methods"
3181
  msgstr ""
3182
 
3183
- #: lib/i18n-extra.php:64
3184
  msgid "All Access Control directives should apply to the folowing HTTP methods"
3185
  msgstr ""
3186
 
3187
- #: lib/i18n-extra.php:65
3188
  msgid "Enable Geolocation"
3189
  msgstr ""
3190
 
3191
- #: lib/i18n-extra.php:66
3192
  msgid "Retrieve the ISO 3166 code from"
3193
  msgstr ""
3194
 
3195
- #: lib/i18n-extra.php:67
3196
  msgid "PHP Variable"
3197
  msgstr ""
3198
 
3199
- #: lib/i18n-extra.php:68
3200
  msgid "Block the following ISO 3166 codes"
3201
  msgstr ""
3202
 
3203
- #: lib/i18n-extra.php:69
3204
  #, php-format
3205
  msgid "Total blocked items: %s"
3206
  msgstr ""
3207
 
3208
- #: lib/i18n-extra.php:70
3209
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3210
  msgstr ""
3211
 
3212
- #: lib/i18n-extra.php:71
3213
  msgid "View allowed syntax"
3214
  msgstr ""
3215
 
3216
- #: lib/i18n-extra.php:72
3217
  #, php-format
3218
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3219
  msgstr ""
3220
 
3221
- #: lib/i18n-extra.php:73
3222
  msgid "One item per line."
3223
  msgstr ""
3224
 
3225
- #: lib/i18n-extra.php:74
3226
  msgid ""
3227
  "Leave this field empty if you want geolocation to apply to all your PHP "
3228
  "scripts."
3229
  msgstr ""
3230
 
3231
- #: lib/i18n-extra.php:75
3232
  msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3233
  msgstr ""
3234
 
3235
- #: lib/i18n-extra.php:76
3236
  msgid "Write event to the firewall log"
3237
  msgstr ""
3238
 
3239
- #: lib/i18n-extra.php:77
3240
  msgid "Allow the following IP, CIDR or AS number"
3241
  msgstr ""
3242
 
3243
- #: lib/i18n-extra.php:78
3244
  #, php-format
3245
  msgid "IPv4 address: %s"
3246
  msgstr ""
3247
 
3248
- #: lib/i18n-extra.php:79
3249
  #, php-format
3250
  msgid "IPv4 CIDR: %s"
3251
  msgstr ""
3252
 
3253
- #: lib/i18n-extra.php:80
3254
  #, php-format
3255
  msgid "IPv6 address: %s"
3256
  msgstr ""
3257
 
3258
- #: lib/i18n-extra.php:81
3259
  #, php-format
3260
  msgid "IPv6 CIDR: %s"
3261
  msgstr ""
3262
 
3263
- #: lib/i18n-extra.php:82
3264
  #, php-format
3265
  msgid "Autonomous System number: %s"
3266
  msgstr ""
3267
 
3268
- #: lib/i18n-extra.php:83
3269
  msgid "Whitelist:"
3270
  msgstr ""
3271
 
3272
- #: lib/i18n-extra.php:84
3273
  msgid "Enter one item per line."
3274
  msgstr ""
3275
 
3276
- #: lib/i18n-extra.php:85
3277
  msgid "External Services"
3278
  msgstr ""
3279
 
3280
- #: lib/i18n-extra.php:86
3281
  msgid "Whitelist IP addresses from the following services:"
3282
  msgstr ""
3283
 
3284
- #: lib/i18n-extra.php:87
3285
  msgid "View IP addresses"
3286
  msgstr ""
3287
 
3288
- #: lib/i18n-extra.php:88
3289
  msgid "Block the following IP, CIDR or AS number"
3290
  msgstr ""
3291
 
3292
- #: lib/i18n-extra.php:89
3293
  msgid "Blacklist:"
3294
  msgstr ""
3295
 
3296
- #: lib/i18n-extra.php:90
3297
  msgid "Rate Limiting"
3298
  msgstr ""
3299
 
3300
- #: lib/i18n-extra.php:91
3301
  #, php-format
3302
  msgid ""
3303
  "Block for %s seconds any IP address with more than %s connections within a "
3304
  "%s interval."
3305
  msgstr ""
3306
 
3307
- #: lib/i18n-extra.php:92
3308
  msgid "5-second"
3309
  msgstr ""
3310
 
3311
- #: lib/i18n-extra.php:93
3312
  msgid "10-second"
3313
  msgstr ""
3314
 
3315
- #: lib/i18n-extra.php:94
3316
  msgid "15-second"
3317
  msgstr ""
3318
 
3319
- #: lib/i18n-extra.php:95
3320
  msgid "30-second"
3321
  msgstr ""
3322
 
3323
- #: lib/i18n-extra.php:96
3324
  msgid "Allow access to the following URL"
3325
  msgstr ""
3326
 
3327
- #: lib/i18n-extra.php:97
3328
  #, php-format
3329
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3330
  msgstr ""
3331
 
3332
- #: lib/i18n-extra.php:98
3333
  msgid "Block access to the following URL"
3334
  msgstr ""
3335
 
3336
- #: lib/i18n-extra.php:99
3337
  msgid "Reject the following bots"
3338
  msgstr ""
3339
 
3340
- #: lib/i18n-extra.php:100
3341
  msgid "A full or partial case-insensitive string."
3342
  msgstr ""
3343
 
3344
- #: lib/i18n-extra.php:101
3345
  #, php-format
3346
  msgid "Allowed characters are: %s and %s."
3347
  msgstr ""
3348
 
3349
- #: lib/i18n-extra.php:102
3350
  msgid "Blocked bots:"
3351
  msgstr ""
3352
 
3353
- #: lib/i18n-extra.php:103
3354
  msgid "The default list of bots will be restored. Continue?"
3355
  msgstr ""
3356
 
3357
- #: lib/i18n-extra.php:104
3358
  msgid "Restore default bots list"
3359
  msgstr ""
3360
 
3361
- #: lib/i18n-extra.php:105
3362
  msgid "Do not filter the following user input"
3363
  msgstr ""
3364
 
3365
- #: lib/i18n-extra.php:106
3366
  msgid ""
3367
  "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
3368
  "sensitive input:"
3369
  msgstr ""
3370
 
3371
- #: lib/i18n-extra.php:107
3372
  msgid "Unfiltered input:"
3373
  msgstr ""
3374
 
3375
- #: lib/i18n-extra.php:108
3376
  msgid "Block the request if the following input is present"
3377
  msgstr ""
3378
 
3379
- #: lib/i18n-extra.php:109
3380
  msgid "Blocked input:"
3381
  msgstr ""
3382
 
3383
- #: lib/i18n-extra.php:110
3384
  msgid "Save Access Control directives"
3385
  msgstr ""
3386
 
3387
- #: lib/i18n-extra.php:111
3388
  msgid ""
3389
  "Warning: Your previous secret key was either corrupted or missing. A new "
3390
  "one, as well as a new public key, were created."
3391
  msgstr ""
3392
 
3393
- #: lib/i18n-extra.php:112
3394
  msgid "Enable Centralized Logging"
3395
  msgstr ""
3396
 
3397
- #: lib/i18n-extra.php:113
3398
  msgid "Secret key"
3399
  msgstr ""
3400
 
3401
- #: lib/i18n-extra.php:114
3402
  msgid "From 30 to 100 ASCII printable characters."
3403
  msgstr ""
3404
 
3405
- #: lib/i18n-extra.php:115
3406
  msgid "This server's IP address"
3407
  msgstr ""
3408
 
3409
- #: lib/i18n-extra.php:116
3410
  msgid ""
3411
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
3412
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
3413
  "code> character instead."
3414
  msgstr ""
3415
 
3416
- #: lib/i18n-extra.php:117
3417
  msgid "Public key"
3418
  msgstr ""
3419
 
3420
- #: lib/i18n-extra.php:118
3421
  #, php-format
3422
  msgid ""
3423
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
3424
  "more info."
3425
  msgstr ""
3426
 
3427
- #: lib/i18n-extra.php:119
3428
  msgid "Remote websites URL"
3429
  msgstr ""
3430
 
3431
- #: lib/i18n-extra.php:120
3432
  msgid ""
3433
  "Enter one URL per line, including the protocol (<code>http://</code> or "
3434
  "<code>https://</code>). Only ASCII URLs are accepted."
3435
  msgstr ""
3436
 
3437
- #: lib/i18n-extra.php:121
3438
  msgid "Save Options"
3439
  msgstr ""
3440
 
3441
- #: lib/i18n-extra.php:122
3442
  msgid ""
3443
  "Your changes have been saved. If you are using a caching plugin, do not "
3444
  "forget to clear its cache."
3445
  msgstr ""
3446
 
3447
- #: lib/i18n-extra.php:123
3448
  msgid "Enable antispam protection"
3449
  msgstr ""
3450
 
3451
- #: lib/i18n-extra.php:124
3452
  msgid "Protection level"
3453
  msgstr ""
3454
 
3455
- #: lib/i18n-extra.php:125
3456
  msgid "Low (default)"
3457
  msgstr ""
3458
 
3459
- #: lib/i18n-extra.php:126
3460
  msgid ""
3461
  "If you are using a caching plugin, consult the contextual help before "
3462
  "enabling the antispam."
3463
  msgstr ""
3464
 
3465
- #: lib/i18n-extra.php:127
3466
  msgid "Apply protection to"
3467
  msgstr ""
3468
 
3469
- #: lib/i18n-extra.php:128
3470
  msgid "Comment forms (defaut)"
3471
  msgstr ""
3472
 
3473
- #: lib/i18n-extra.php:129
3474
  msgid "User Registration form"
3475
  msgstr ""
3476
 
3477
- #: lib/i18n-extra.php:130
3478
  msgid "Save Antispam options"
3479
  msgstr ""
3480
 
3481
- #: lib/i18n-extra.php:131
3482
  msgid "Please enable JavaScript"
3483
  msgstr ""
3484
 
3485
- #: lib/i18n-extra.php:132
3486
  msgid "Sorry, this looks like spam to me."
3487
  msgstr ""
3488
 
3489
- #: lib/i18n-extra.php:133
3490
  msgid ""
3491
  "Error: You must be whitelisted in order to use that feature: click on the <a "
3492
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
3493
  "not block the following users\" option is enabled for the Admin/Super Admin."
3494
  msgstr ""
3495
 
3496
- #: lib/i18n-extra.php:134
3497
  msgid ""
3498
  "Your license is valid until the indicated expiration date. If you don't "
3499
  "renew it after this date, NinjaFirewall will keep working and protecting "
3500
  "your website as usual, but updates/upgrades will stop."
3501
  msgstr ""
3502
 
3503
- #: lib/i18n-extra.php:135
3504
  #, php-format
3505
  msgid ""
3506
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
3507
  msgstr ""
3508
 
3509
- #: lib/i18n-extra.php:136
3510
  msgid "Use shared memory"
3511
  msgstr ""
3512
 
3513
- #: lib/i18n-extra.php:137
3514
  msgid ""
3515
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
3516
  "order to speed up all operations. The firewall will no longer need to "
@@ -3520,14 +3530,14 @@ msgid ""
3520
  "processing speed from 25% to 30%, prevent blocking I/O and slow queries."
3521
  msgstr ""
3522
 
3523
- #: lib/i18n-extra.php:138
3524
  msgid ""
3525
  "This option requires that your PHP version was compiled with the <code>--"
3526
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
3527
  "server/hosting environment, it will be disabled."
3528
  msgstr ""
3529
 
3530
- #: lib/i18n-extra.php:139
3531
  #, php-format
3532
  msgid ""
3533
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
@@ -3537,24 +3547,24 @@ msgid ""
3537
  "used by that charset."
3538
  msgstr ""
3539
 
3540
- #: lib/i18n-extra.php:140
3541
  msgid "Language"
3542
  msgstr ""
3543
 
3544
- #: lib/i18n-extra.php:141
3545
  msgid ""
3546
  "When this option is enabled, NinjaFirewall will download, if available, the "
3547
  "corresponding language files from the WordPress repo. Then, every hour, it "
3548
  "will check if there's a new version and will download it."
3549
  msgstr ""
3550
 
3551
- #: lib/i18n-extra.php:142
3552
  msgid ""
3553
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
3554
  "locales because they are already included with NinjaFirewall."
3555
  msgstr ""
3556
 
3557
- #: lib/i18n-extra.php:143
3558
  #, php-format
3559
  msgid ""
3560
  "This options lets you export you current configuration or import it from "
@@ -3564,7 +3574,7 @@ msgid ""
3564
  "configuration, except your current license."
3565
  msgstr ""
3566
 
3567
- #: lib/i18n-extra.php:144
3568
  msgid ""
3569
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
3570
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
@@ -3572,11 +3582,11 @@ msgid ""
3572
  "SVG files containing Javascript/XML events."
3573
  msgstr ""
3574
 
3575
- #: lib/i18n-extra.php:145
3576
  msgid "Maximum allowed file size"
3577
  msgstr ""
3578
 
3579
- #: lib/i18n-extra.php:146
3580
  msgid ""
3581
  "If you allow uploads, you can select the maximum size of an uploaded file. "
3582
  "Any file bigger than this value will be rejected. Note that if your PHP "
@@ -3584,11 +3594,11 @@ msgid ""
3584
  "be used before NinjaFirewall."
3585
  msgstr ""
3586
 
3587
- #: lib/i18n-extra.php:147
3588
  msgid "Decode Base64-encoded <code>POST</code> variable:"
3589
  msgstr ""
3590
 
3591
- #: lib/i18n-extra.php:148
3592
  #, php-format
3593
  msgid ""
3594
  "Object Serialization is a PHP feature used by many applications to generate "
@@ -3599,7 +3609,7 @@ msgid ""
3599
  "request, cookies, user agent and referrer variables."
3600
  msgstr ""
3601
 
3602
- #: lib/i18n-extra.php:149
3603
  msgid ""
3604
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
3605
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
@@ -3608,106 +3618,106 @@ msgid ""
3608
  "is dangerous and should always be rejected."
3609
  msgstr ""
3610
 
3611
- #: lib/i18n-extra.php:150
3612
  msgid ""
3613
  "This option will block any <code>GET</code> or <code>POST</code> request "
3614
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
3615
  "dumpers and various hacker's shell scripts."
3616
  msgstr ""
3617
 
3618
- #: lib/i18n-extra.php:151
3619
  msgid ""
3620
  "Access Control is a powerful set of directives that can be used to allow or "
3621
  "restrict access to your website based on many criteria."
3622
  msgstr ""
3623
 
3624
- #: lib/i18n-extra.php:152
3625
  msgid ""
3626
  "To make better use of them, it is important to understand NinjaFirewall's "
3627
  "directives processing order."
3628
  msgstr ""
3629
 
3630
- #: lib/i18n-extra.php:153
3631
  msgid ""
3632
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
3633
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
3634
  "on your configuration, they can also apply to HTML pages."
3635
  msgstr ""
3636
 
3637
- #: lib/i18n-extra.php:154
3638
  msgid "Processing order:"
3639
  msgstr ""
3640
 
3641
- #: lib/i18n-extra.php:155
3642
  msgid "Incoming HTTP request"
3643
  msgstr ""
3644
 
3645
- #: lib/i18n-extra.php:156
3646
  #, php-format
3647
  msgid "%s file"
3648
  msgstr ""
3649
 
3650
- #: lib/i18n-extra.php:157
3651
  msgid "Login Protection."
3652
  msgstr ""
3653
 
3654
- #: lib/i18n-extra.php:158
3655
  msgid "Access Control (except User Input Access Control):"
3656
  msgstr ""
3657
 
3658
- #: lib/i18n-extra.php:159
3659
  msgid "Role-based Access Control."
3660
  msgstr ""
3661
 
3662
- #: lib/i18n-extra.php:160
3663
  msgid "Allowed IPs."
3664
  msgstr ""
3665
 
3666
- #: lib/i18n-extra.php:161
3667
  msgid "Blocked IPs."
3668
  msgstr ""
3669
 
3670
- #: lib/i18n-extra.php:162
3671
  msgid "Allowed URLs."
3672
  msgstr ""
3673
 
3674
- #: lib/i18n-extra.php:163
3675
  msgid "Blocked URLs."
3676
  msgstr ""
3677
 
3678
- #: lib/i18n-extra.php:164
3679
  msgid "Bot Access Control."
3680
  msgstr ""
3681
 
3682
- #: lib/i18n-extra.php:165
3683
  msgid "Geolocation."
3684
  msgstr ""
3685
 
3686
- #: lib/i18n-extra.php:166
3687
  msgid "Rate Limiting."
3688
  msgstr ""
3689
 
3690
- #: lib/i18n-extra.php:167
3691
  msgid "File Guard."
3692
  msgstr ""
3693
 
3694
- #: lib/i18n-extra.php:168
3695
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
3696
  msgstr ""
3697
 
3698
- #: lib/i18n-extra.php:169
3699
  msgid "Response body"
3700
  msgstr ""
3701
 
3702
- #: lib/i18n-extra.php:170
3703
  msgid "HTTP response headers (Firewall Policies)."
3704
  msgstr ""
3705
 
3706
- #: lib/i18n-extra.php:171
3707
  msgid "Web Filter."
3708
  msgstr ""
3709
 
3710
- #: lib/i18n-extra.php:172
3711
  #, php-format
3712
  msgid ""
3713
  "By default, any logged in WordPress administrator will not be blocked by "
@@ -3719,11 +3729,11 @@ msgid ""
3719
  "enforced."
3720
  msgstr ""
3721
 
3722
- #: lib/i18n-extra.php:173
3723
  msgid "You can also add other users to the whitelist, depending on their role."
3724
  msgstr ""
3725
 
3726
- #: lib/i18n-extra.php:174
3727
  #, php-format
3728
  msgid ""
3729
  "this option should be used if you are behind a reverse proxy, a load "
@@ -3737,25 +3747,25 @@ msgid ""
3737
  "NinjaFirewall will fall back to <code>REMOTE_ADDR</code>."
3738
  msgstr ""
3739
 
3740
- #: lib/i18n-extra.php:175
3741
  msgid ""
3742
  "This option lets you select the HTTP method(s). All Access Control "
3743
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
3744
  "methods."
3745
  msgstr ""
3746
 
3747
- #: lib/i18n-extra.php:176
3748
  msgid ""
3749
  "It does not apply to the \"Firewall Policies\" options, which use their own "
3750
  "ones."
3751
  msgstr ""
3752
 
3753
- #: lib/i18n-extra.php:177
3754
  msgid ""
3755
  "You can filter and block traffic coming from specific countries/territories."
3756
  msgstr ""
3757
 
3758
- #: lib/i18n-extra.php:178
3759
  msgid ""
3760
  "This is the two-letter code that is used to define a country/territory (e."
3761
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
@@ -3763,7 +3773,7 @@ msgid ""
3763
  "your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>)."
3764
  msgstr ""
3765
 
3766
- #: lib/i18n-extra.php:179
3767
  #, php-format
3768
  msgid ""
3769
  "You can add/remove any country/territory from the two listboxes. For more "
@@ -3771,18 +3781,18 @@ msgid ""
3771
  "want to consult <a href=\"%s\">the MaxMind GeoIP online help</a>."
3772
  msgstr ""
3773
 
3774
- #: lib/i18n-extra.php:180
3775
  msgid ""
3776
  "Whether geolocation should apply to the whole site or to specific URLs only "
3777
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
3778
  "it to apply to the whole site."
3779
  msgstr ""
3780
 
3781
- #: lib/i18n-extra.php:181
3782
  msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
3783
  msgstr ""
3784
 
3785
- #: lib/i18n-extra.php:182
3786
  msgid ""
3787
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
3788
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
@@ -3790,48 +3800,48 @@ msgid ""
3790
  "visitors location, simply use that variable."
3791
  msgstr ""
3792
 
3793
- #: lib/i18n-extra.php:183
3794
  msgid ""
3795
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
3796
  "it with 2 hyphens (<code>--</code>)."
3797
  msgstr ""
3798
 
3799
- #: lib/i18n-extra.php:184
3800
  msgid ""
3801
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
3802
  msgstr ""
3803
 
3804
- #: lib/i18n-extra.php:185
3805
  msgid ""
3806
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
3807
  "http://www.maxmind.com"
3808
  msgstr ""
3809
 
3810
- #: lib/i18n-extra.php:186
3811
  msgid "IP / URL / Bot Access Control"
3812
  msgstr ""
3813
 
3814
- #: lib/i18n-extra.php:187
3815
  msgid ""
3816
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
3817
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
3818
  "NinjaFirewall."
3819
  msgstr ""
3820
 
3821
- #: lib/i18n-extra.php:188
3822
  msgid "Full IP:"
3823
  msgstr ""
3824
 
3825
- #: lib/i18n-extra.php:189
3826
  #, php-format
3827
  msgid "IP ranges using CIDR notation: %s or %s."
3828
  msgstr ""
3829
 
3830
- #: lib/i18n-extra.php:190
3831
  msgid "Autonomous System number:"
3832
  msgstr ""
3833
 
3834
- #: lib/i18n-extra.php:191
3835
  msgid ""
3836
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
3837
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
@@ -3844,14 +3854,14 @@ msgid ""
3844
  "turned off."
3845
  msgstr ""
3846
 
3847
- #: lib/i18n-extra.php:192
3848
  msgid ""
3849
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
3850
  "immediately by clicking either the \"Save Access Control Directives\" or "
3851
  "\"Restore Default Values\" buttons at the bottom of this page."
3852
  msgstr ""
3853
 
3854
- #: lib/i18n-extra.php:193
3855
  msgid ""
3856
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
3857
  "IPs even before your blog is loaded, we strongly recommend that you disable "
@@ -3861,43 +3871,43 @@ msgid ""
3861
  "during an attack."
3862
  msgstr ""
3863
 
3864
- #: lib/i18n-extra.php:194
3865
  msgid ""
3866
  "You can permanently allow/block any access to one or more PHP scripts based "
3867
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
3868
  "enter either a full or partial path (case-sensitive)."
3869
  msgstr ""
3870
 
3871
- #: lib/i18n-extra.php:195
3872
  msgid ""
3873
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
3874
  "script located inside a <code>/foo/</code> directory"
3875
  msgstr ""
3876
 
3877
- #: lib/i18n-extra.php:196
3878
  msgid "etc"
3879
  msgstr ""
3880
 
3881
- #: lib/i18n-extra.php:197
3882
  msgid ""
3883
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
3884
  "<code>/foo/</code> directory and its sub-directories."
3885
  msgstr ""
3886
 
3887
- #: lib/i18n-extra.php:198
3888
  msgid ""
3889
  "Note that the \"Firewall Policies\" page already includes restrictions to "
3890
  "some WordPress directories."
3891
  msgstr ""
3892
 
3893
- #: lib/i18n-extra.php:199
3894
  msgid ""
3895
  "You can block bots, scanners and various crawlers based on the "
3896
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
3897
  "partial name (case-insensitive)."
3898
  msgstr ""
3899
 
3900
- #: lib/i18n-extra.php:200
3901
  msgid ""
3902
  "You can select to ignore or block some specific user input. It applies to "
3903
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
@@ -3905,34 +3915,34 @@ msgid ""
3905
  "\"]</code>:"
3906
  msgstr ""
3907
 
3908
- #: lib/i18n-extra.php:201
3909
  msgid ""
3910
  "When an input is added to the \"Unfiltered input\" list, it will not be "
3911
  "filtered or sanitised. All other input present in the request will be "
3912
  "filtered."
3913
  msgstr ""
3914
 
3915
- #: lib/i18n-extra.php:202
3916
  msgid ""
3917
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
3918
  "the request and close the connection if that input is found in the request."
3919
  msgstr ""
3920
 
3921
- #: lib/i18n-extra.php:203
3922
  msgid "Log Event"
3923
  msgstr ""
3924
 
3925
- #: lib/i18n-extra.php:204
3926
  msgid ""
3927
  "You can enable/disable firewall logging for each access control directive "
3928
  "separately."
3929
  msgstr ""
3930
 
3931
- #: lib/i18n-extra.php:205
3932
  msgid "Web Filter"
3933
  msgstr ""
3934
 
3935
- #: lib/i18n-extra.php:206
3936
  msgid ""
3937
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
3938
  "response body (i.e., the output of the HTML page right before it is sent to "
@@ -3942,27 +3952,27 @@ msgid ""
3942
  "hackers shell script, redirections and even errors (PHP/MySQL errors)."
3943
  msgstr ""
3944
 
3945
- #: lib/i18n-extra.php:207
3946
  msgid ""
3947
  "In the case of a positive detection, NinjaFirewall will not block the "
3948
  "response body but will send you an alert by email."
3949
  msgstr ""
3950
 
3951
- #: lib/i18n-extra.php:208
3952
  msgid "Search HTML page for the following keywords"
3953
  msgstr ""
3954
 
3955
- #: lib/i18n-extra.php:209
3956
  msgid ""
3957
  "You can enter any keyword from 4 to 150 characters and select whether the "
3958
  "search will be case sensitive or not."
3959
  msgstr ""
3960
 
3961
- #: lib/i18n-extra.php:210
3962
  msgid "Email Alerts"
3963
  msgstr ""
3964
 
3965
- #: lib/i18n-extra.php:211
3966
  msgid ""
3967
  "You can use the notification throttling option to limit the frequency of "
3968
  "alerts sent to you (and written to the firewall log) and select whether you "
@@ -3971,14 +3981,14 @@ msgid ""
3971
  "in the \"Event Notifications\" menu."
3972
  msgstr ""
3973
 
3974
- #: lib/i18n-extra.php:212
3975
  msgid ""
3976
  "Response body filtering can be resource-intensive. Try to limit the number "
3977
  "of keywords to what you really need (less than 10) and, if possible, prefer "
3978
  "case sensitive to case insensitive filtering."
3979
  msgstr ""
3980
 
3981
- #: lib/i18n-extra.php:213
3982
  msgid ""
3983
  "NinjaFirewall can protect your blog against spam without user interaction (e."
3984
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
@@ -3987,132 +3997,132 @@ msgid ""
3987
  "generate your forms, they will not be protected against spam."
3988
  msgstr ""
3989
 
3990
- #: lib/i18n-extra.php:214
3991
  msgid "Protection level:"
3992
  msgstr ""
3993
 
3994
- #: lib/i18n-extra.php:215
3995
  msgid ""
3996
  "Select the level of protection. In most cases, <strong>Low</strong> should "
3997
  "be enough."
3998
  msgstr ""
3999
 
4000
- #: lib/i18n-extra.php:216
4001
  msgid "Apply protection to:"
4002
  msgstr ""
4003
 
4004
- #: lib/i18n-extra.php:217
4005
  msgid "Whether to protect comment and/or registration forms."
4006
  msgstr ""
4007
 
4008
- #: lib/i18n-extra.php:218
4009
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4010
  msgstr ""
4011
 
4012
- #: lib/i18n-extra.php:219
4013
  msgid ""
4014
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4015
  "otherwise the antispam could behave erratically after a while."
4016
  msgstr ""
4017
 
4018
- #: lib/i18n-extra.php:220
4019
  msgid ""
4020
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4021
  msgstr ""
4022
 
4023
- #: lib/i18n-extra.php:221
4024
  msgid ""
4025
  "The firewall log displays blocked and sanitised requests as well as some "
4026
  "useful information. It has 6 columns:"
4027
  msgstr ""
4028
 
4029
- #: lib/i18n-extra.php:222
4030
  msgid ""
4031
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4032
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
4033
  "rule from the \"Firewall Policies\" or \"Access Control\" pages."
4034
  msgstr ""
4035
 
4036
- #: lib/i18n-extra.php:223
4037
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4038
  msgstr ""
4039
 
4040
- #: lib/i18n-extra.php:224
4041
  msgid "Enable firewall log"
4042
  msgstr ""
4043
 
4044
- #: lib/i18n-extra.php:225
4045
  msgid "You can disable/enable the firewall log from this page."
4046
  msgstr ""
4047
 
4048
- #: lib/i18n-extra.php:226
4049
  msgid ""
4050
  "Brute-force attacks will still be written to the firewall log, even if you "
4051
  "disable it."
4052
  msgstr ""
4053
 
4054
- #: lib/i18n-extra.php:227
4055
  msgid "Auto-rotate log"
4056
  msgstr ""
4057
 
4058
- #: lib/i18n-extra.php:228
4059
  msgid ""
4060
  "NinjaFirewall will rotate its log automatically on the very first day of "
4061
  "each month. If your site is very busy, you may want to allow it to rotate "
4062
  "the log when it reaches a certain size (MB) as well."
4063
  msgstr ""
4064
 
4065
- #: lib/i18n-extra.php:229
4066
  msgid ""
4067
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
4068
  "megabytes."
4069
  msgstr ""
4070
 
4071
- #: lib/i18n-extra.php:230
4072
  msgid ""
4073
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
4074
  msgstr ""
4075
 
4076
- #: lib/i18n-extra.php:231
4077
  msgid "Syslog"
4078
  msgstr ""
4079
 
4080
- #: lib/i18n-extra.php:232
4081
  msgid ""
4082
  "In addition to the firewall log, events can also be redirected to the syslog "
4083
  "server (<code>LOG_USER</code> facility)."
4084
  msgstr ""
4085
 
4086
- #: lib/i18n-extra.php:233
4087
  msgid ""
4088
  "If you have a shared hosting account, keep this option disabled as you do "
4089
  "not have any access to the server logs."
4090
  msgstr ""
4091
 
4092
- #: lib/i18n-extra.php:234
4093
  msgid "The logline uses the following format:"
4094
  msgstr ""
4095
 
4096
- #: lib/i18n-extra.php:235
4097
  msgid ""
4098
  "BB: the level of severity as it appears in the firewall log. It can be "
4099
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
4100
  "CODE>, <CODE>UPLOAD</CODE> or <CODE>DEBUG_ON</CODE>."
4101
  msgstr ""
4102
 
4103
- #: lib/i18n-extra.php:236
4104
  msgid "CCCCCC: the 7-digit incident ID."
4105
  msgstr ""
4106
 
4107
- #: lib/i18n-extra.php:237
4108
  msgid "DD: the user IPv4 or IPv6 address."
4109
  msgstr ""
4110
 
4111
- #: lib/i18n-extra.php:238
4112
  msgid "EE: the blog (sub-)domain name."
4113
  msgstr ""
4114
 
4115
- #: lib/i18n-extra.php:239
4116
  #, php-format
4117
  msgid ""
4118
  "This logging option does not apply to the brute-force protection which can "
@@ -4120,14 +4130,14 @@ msgid ""
4120
  "the <a href=\"%s\">Login Protection</a> page."
4121
  msgstr ""
4122
 
4123
- #: lib/i18n-extra.php:240
4124
  msgid ""
4125
  "Secret key: The secret key will be used to generate your public key. Enter "
4126
  "at least 30 ASCII characters, or use the one randomly created by "
4127
  "NinjaFirewall."
4128
  msgstr ""
4129
 
4130
- #: lib/i18n-extra.php:241
4131
  msgid ""
4132
  "This server IP address: As an additional protection layer, you can restrict "
4133
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
@@ -4135,331 +4145,331 @@ msgid ""
4135
  "character instead."
4136
  msgstr ""
4137
 
4138
- #: lib/i18n-extra.php:242
4139
  #, php-format
4140
  msgid ""
4141
  "Public key: This is the public key that you will need to upload to each "
4142
  "remote website (<a href=\"%s\">consult our blog</a> for more info about it)."
4143
  msgstr ""
4144
 
4145
- #: lib/i18n-extra.php:243
4146
  msgid ""
4147
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4148
  "website(s) that you want to remotely access from the main server."
4149
  msgstr ""
4150
 
4151
- #: lib/i18n-extra.php:244
4152
  msgid ""
4153
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
4154
  "the menu below if you want to disable it."
4155
  msgstr ""
4156
 
4157
- #: lib/i18n-extra.php:245
4158
  msgid "Enable Web Filter"
4159
  msgstr ""
4160
 
4161
- #: lib/i18n-extra.php:246
4162
  msgid "A full or partial string."
4163
  msgstr ""
4164
 
4165
- #: lib/i18n-extra.php:247
4166
  msgid "From 4 to maximum 150 characters."
4167
  msgstr ""
4168
 
4169
- #: lib/i18n-extra.php:248
4170
  msgid "Any character, except the vertical bar <code>|</code>"
4171
  msgstr ""
4172
 
4173
- #: lib/i18n-extra.php:249
4174
  msgid "Keywords to search:"
4175
  msgstr ""
4176
 
4177
- #: lib/i18n-extra.php:250
4178
  msgid "Case-sensitive search"
4179
  msgstr ""
4180
 
4181
- #: lib/i18n-extra.php:251
4182
  #, php-format
4183
  msgid "Do not send me more than one email alert in a %s interval"
4184
  msgstr ""
4185
 
4186
- #: lib/i18n-extra.php:252
4187
  msgid "5-minute"
4188
  msgstr ""
4189
 
4190
- #: lib/i18n-extra.php:253
4191
  msgid "15-minute"
4192
  msgstr ""
4193
 
4194
- #: lib/i18n-extra.php:254
4195
  msgid "30-minute"
4196
  msgstr ""
4197
 
4198
- #: lib/i18n-extra.php:255
4199
  msgid "1-hour"
4200
  msgstr ""
4201
 
4202
- #: lib/i18n-extra.php:256
4203
  msgid "3-hour"
4204
  msgstr ""
4205
 
4206
- #: lib/i18n-extra.php:257
4207
  msgid "6-hour"
4208
  msgstr ""
4209
 
4210
- #: lib/i18n-extra.php:258
4211
  msgid "12-hour"
4212
  msgstr ""
4213
 
4214
- #: lib/i18n-extra.php:259
4215
  msgid "24-hour"
4216
  msgstr ""
4217
 
4218
- #: lib/i18n-extra.php:260
4219
  msgid ""
4220
  "Clicking the \"Save Web Filter options\" button below will reset the current "
4221
  "timer."
4222
  msgstr ""
4223
 
4224
- #: lib/i18n-extra.php:261
4225
  msgid "Attach the HTML page output to email alerts"
4226
  msgstr ""
4227
 
4228
- #: lib/i18n-extra.php:262
4229
  msgid "Save Web Filter options"
4230
  msgstr ""
4231
 
4232
- #: lib/i18n-extra.php:263
4233
  msgid "Help Desk:"
4234
  msgstr ""
4235
 
4236
- #: lib/i18n-extra.php:264
4237
  msgid "The selected log was deleted"
4238
  msgstr ""
4239
 
4240
- #: lib/i18n-extra.php:265
4241
  msgid "Export"
4242
  msgstr ""
4243
 
4244
- #: lib/i18n-extra.php:266
4245
  msgid "Delete"
4246
  msgstr ""
4247
 
4248
- #: lib/i18n-extra.php:267
4249
  msgid "Delete log?"
4250
  msgstr ""
4251
 
4252
- #: lib/i18n-extra.php:268
4253
  msgid "Today"
4254
  msgstr ""
4255
 
4256
- #: lib/i18n-extra.php:269
4257
  msgid "Upload"
4258
  msgstr ""
4259
 
4260
- #: lib/i18n-extra.php:270
4261
  msgid "Info"
4262
  msgstr ""
4263
 
4264
- #: lib/i18n-extra.php:271
4265
  msgid "Debug"
4266
  msgstr ""
4267
 
4268
- #: lib/i18n-extra.php:272
4269
  msgid "IP address:"
4270
  msgstr ""
4271
 
4272
- #: lib/i18n-extra.php:273
4273
  msgid "e.g., 1.2.3.4"
4274
  msgstr ""
4275
 
4276
- #: lib/i18n-extra.php:274
4277
  msgid "Add IP to blacklist"
4278
  msgstr ""
4279
 
4280
- #: lib/i18n-extra.php:275
4281
  msgid "Add IP to whitelist"
4282
  msgstr ""
4283
 
4284
- #: lib/i18n-extra.php:276
4285
  msgid "Add"
4286
  msgstr ""
4287
 
4288
- #: lib/i18n-extra.php:277
4289
  msgid "The address wad added to your IP Access Control list."
4290
  msgstr ""
4291
 
4292
- #: lib/i18n-extra.php:278
4293
  #, php-format
4294
  msgid "1st day of the month, or if bigger than %s MB"
4295
  msgstr ""
4296
 
4297
- #: lib/i18n-extra.php:279
4298
  msgid "1st day of the month, regardless of its size"
4299
  msgstr ""
4300
 
4301
- #: lib/i18n-extra.php:280
4302
  msgid "Show the most recent"
4303
  msgstr ""
4304
 
4305
- #: lib/i18n-extra.php:281
4306
  msgid "lines"
4307
  msgstr ""
4308
 
4309
- #: lib/i18n-extra.php:282
4310
  msgid "Write events to the Syslog server too"
4311
  msgstr ""
4312
 
4313
- #: lib/i18n-extra.php:283
4314
  msgid "Your server configuration is not compatible with this option."
4315
  msgstr ""
4316
 
4317
- #: lib/i18n-extra.php:284
4318
  msgid "See contextual help before enabling this option."
4319
  msgstr ""
4320
 
4321
- #: lib/i18n-extra.php:285
4322
  msgid ""
4323
  "The remote server rejected your request. Make sure that you uploaded the "
4324
  "correct public key."
4325
  msgstr ""
4326
 
4327
- #: lib/i18n-extra.php:286
4328
  #, php-format
4329
  msgid "The remote server returned the following HTTP error: %s"
4330
  msgstr ""
4331
 
4332
- #: lib/i18n-extra.php:287
4333
  msgid "The requested log does not exist on the remote website."
4334
  msgstr ""
4335
 
4336
- #: lib/i18n-extra.php:288
4337
  msgid "The remote website did not return the expected response."
4338
  msgstr ""
4339
 
4340
- #: lib/i18n-extra.php:289
4341
  msgid "Your server does not seem to be compatible with this option."
4342
  msgstr ""
4343
 
4344
- #: lib/i18n-extra.php:290
4345
  msgid "Load language files from the WordPress repo"
4346
  msgstr ""
4347
 
4348
- #: lib/i18n-extra.php:291
4349
  #, php-format
4350
  msgid ""
4351
  "If available, NinjaFirewall will download the language files from <a "
4352
  "%s>translate.wordpress.org</a>."
4353
  msgstr ""
4354
 
4355
- #: lib/i18n-extra.php:292
4356
  msgid "Error: you do not have any license."
4357
  msgstr ""
4358
 
4359
- #: lib/i18n-extra.php:293
4360
  msgid "You have a valid license."
4361
  msgstr ""
4362
 
4363
- #: lib/i18n-extra.php:294
4364
  msgid ""
4365
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
4366
  "try again in a few minutes"
4367
  msgstr ""
4368
 
4369
- #: lib/i18n-extra.php:295
4370
  msgid ""
4371
  "An error occured while connecting to NinjaFirewall servers. Please try again "
4372
  "in a few minutes"
4373
  msgstr ""
4374
 
4375
- #: lib/i18n-extra.php:296
4376
  msgid "Enter a valid license to save!"
4377
  msgstr ""
4378
 
4379
- #: lib/i18n-extra.php:297
4380
  msgid "This is already your current license!"
4381
  msgstr ""
4382
 
4383
- #: lib/i18n-extra.php:298
4384
  msgid "Your new license has been accepted and saved."
4385
  msgstr ""
4386
 
4387
- #: lib/i18n-extra.php:299
4388
  msgid "This license is not valid"
4389
  msgstr ""
4390
 
4391
- #: lib/i18n-extra.php:300
4392
  msgid "WP+ Edition License"
4393
  msgstr ""
4394
 
4395
- #: lib/i18n-extra.php:301
4396
  msgid "License Number"
4397
  msgstr ""
4398
 
4399
- #: lib/i18n-extra.php:302
4400
  msgid "No license found"
4401
  msgstr ""
4402
 
4403
- #: lib/i18n-extra.php:303
4404
  msgid "Click to check your license validity"
4405
  msgstr ""
4406
 
4407
- #: lib/i18n-extra.php:304
4408
  msgid "Expiration date"
4409
  msgstr ""
4410
 
4411
- #: lib/i18n-extra.php:305
4412
  msgid "Unknown expiration date"
4413
  msgstr ""
4414
 
4415
- #: lib/i18n-extra.php:306
4416
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
4417
  msgstr ""
4418
 
4419
- #: lib/i18n-extra.php:307
4420
  msgid "Your license will expire soon!"
4421
  msgstr ""
4422
 
4423
- #: lib/i18n-extra.php:308
4424
  msgid "Your license has expired."
4425
  msgstr ""
4426
 
4427
- #: lib/i18n-extra.php:309
4428
  msgid "License renewal"
4429
  msgstr ""
4430
 
4431
- #: lib/i18n-extra.php:310
4432
  msgid "Click here to get a license!"
4433
  msgstr ""
4434
 
4435
- #: lib/i18n-extra.php:311
4436
  msgid "Enter your new license and click on the save button"
4437
  msgstr ""
4438
 
4439
- #: lib/i18n-extra.php:312
4440
  msgid "Save New License"
4441
  msgstr ""
4442
 
4443
- #: lib/i18n-extra.php:313
4444
  msgid "Allow, but block dangerous files"
4445
  msgstr ""
4446
 
4447
- #: lib/i18n-extra.php:314
4448
  msgid "See contextual help for the list of files."
4449
  msgstr ""
4450
 
4451
- #: lib/i18n-extra.php:315
4452
  msgid "Apply to ZIP archives file contents"
4453
  msgstr ""
4454
 
4455
- #: lib/i18n-extra.php:316
4456
  msgid ""
4457
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
4458
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
4459
  "Control whitelist."
4460
  msgstr ""
4461
 
4462
- #: lib/i18n-extra.php:317
4463
  #, php-format
4464
  msgid ""
4465
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
@@ -4472,7 +4482,7 @@ msgid ""
4472
  "Error: Your .htaccess file is not writable, please change its permissions: %s"
4473
  msgstr ""
4474
 
4475
- #: lib/install.php:110 ninjafirewall.php:656 ninjafirewall.php:660
4476
  #, php-format
4477
  msgid "Error: wrong parameter value (%s)."
4478
  msgstr ""
@@ -4714,7 +4724,7 @@ msgstr ""
4714
  msgid "Error: unable to write to the %s configuration file"
4715
  msgstr ""
4716
 
4717
- #: lib/logs.php:36 ninjafirewall.php:930
4718
  msgid "Logs"
4719
  msgstr ""
4720
 
@@ -4768,7 +4778,7 @@ msgstr ""
4768
  msgid "Viewing:"
4769
  msgstr ""
4770
 
4771
- #: lib/logs_firewall_log.php:142 lib/logs_firewall_log.php:304
4772
  msgid "The selected log is empty."
4773
  msgstr ""
4774
 
@@ -4814,11 +4824,11 @@ msgstr ""
4814
  msgid "Delete Public Key"
4815
  msgstr ""
4816
 
4817
- #: lib/logs_firewall_log.php:283
4818
  msgid "The requested log does not exist."
4819
  msgstr ""
4820
 
4821
- #: lib/logs_firewall_log.php:290
4822
  msgid "Unable to open the log for read operation."
4823
  msgstr ""
4824
 
@@ -4937,7 +4947,7 @@ msgstr ""
4937
  msgid "Error: please enter the custom log format."
4938
  msgstr ""
4939
 
4940
- #: lib/monitoring.php:43 ninjafirewall.php:904
4941
  msgid "Monitoring"
4942
  msgstr ""
4943
 
@@ -5313,7 +5323,7 @@ msgstr ""
5313
  msgid "Save File Guard options"
5314
  msgstr ""
5315
 
5316
- #: lib/network.php:24 ninjafirewall.php:1191 ninjafirewall.php:1195
5317
  #, php-format
5318
  msgid "You are not allowed to perform this task (%s)."
5319
  msgstr ""
@@ -5343,7 +5353,7 @@ msgid "Scheduled task has stopped, restarting it (%s)"
5343
  msgstr ""
5344
 
5345
  #: lib/security_rules.php:44 lib/security_rules_update.php:565
5346
- #: ninjafirewall.php:934
5347
  msgid "Security Rules"
5348
  msgstr ""
5349
 
@@ -5605,12 +5615,23 @@ msgstr ""
5605
 
5606
  #: lib/thickbox.php:79
5607
  msgid ""
 
 
 
 
 
 
 
 
 
 
 
5608
  "In Full WAF mode, all scripts located inside the blog installation "
5609
  "directories and sub-directories are protected by NinjaFirewall. It gives you "
5610
  "the highest possible level of protection: security without compromise."
5611
  msgstr ""
5612
 
5613
- #: lib/thickbox.php:81
5614
  #, php-format
5615
  msgid ""
5616
  "It works on most websites right out of the box, or may require %ssome very "
@@ -5618,82 +5639,82 @@ msgid ""
5618
  "plans restrictions, it may simply not work at all."
5619
  msgstr ""
5620
 
5621
- #: lib/thickbox.php:83
5622
  msgid ""
5623
  "If this happened to you, don't worry: you could still run it in WordPress "
5624
  "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
5625
  "level of protection and performance much higher than other security plugins."
5626
  msgstr ""
5627
 
5628
- #: lib/thickbox.php:157
5629
  msgid "Select your HTTP server and your PHP server API"
5630
  msgstr ""
5631
 
5632
- #: lib/thickbox.php:168
5633
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
5634
  msgstr ""
5635
 
5636
- #: lib/thickbox.php:170
5637
  msgid "View PHPINFO"
5638
  msgstr ""
5639
 
5640
- #: lib/thickbox.php:202
5641
  msgid "Select the PHP initialization file supported by your server"
5642
  msgstr ""
5643
 
5644
- #: lib/thickbox.php:213
5645
  msgid "Folders protected by NinjaFirewall"
5646
  msgstr ""
5647
 
5648
- #: lib/thickbox.php:215 lib/thickbox.php:362
5649
  msgid "WordPress root directory:"
5650
  msgstr ""
5651
 
5652
- #: lib/thickbox.php:220 lib/thickbox.php:367
5653
  msgid ""
5654
  "The following folders will be protected by NinjaFirewall. If you want to "
5655
  "exclude some of them, uncheck them in the list below:"
5656
  msgstr ""
5657
 
5658
- #: lib/thickbox.php:226
5659
  msgid ""
5660
  "After setting up the Full WAF mode, you could come back to this page to re-"
5661
  "configure it whenever you want."
5662
  msgstr ""
5663
 
5664
- #: lib/thickbox.php:234
5665
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
5666
  msgstr ""
5667
 
5668
- #: lib/thickbox.php:236
5669
  msgid "I want to make the changes myself."
5670
  msgstr ""
5671
 
5672
- #: lib/thickbox.php:238
5673
  msgid ""
5674
  "Please make the changes below, then click on the \"Finish Installation\" "
5675
  "button."
5676
  msgstr ""
5677
 
5678
- #: lib/thickbox.php:245
5679
  #, php-format
5680
  msgid ""
5681
  "The %s file must be created, and the following lines of code added to it:"
5682
  msgstr ""
5683
 
5684
- #: lib/thickbox.php:246
5685
  #, php-format
5686
  msgid "The following lines of code must be added to your existing %s file:"
5687
  msgstr ""
5688
 
5689
- #: lib/thickbox.php:314
5690
  msgid ""
5691
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
5692
  "select your domain, add the following instructions to the \"php.ini Override"
5693
  "\" section in the \"General\" tab, and restart Openlitespeed:"
5694
  msgstr ""
5695
 
5696
- #: lib/thickbox.php:321
5697
  msgid ""
5698
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
5699
  "to remove these instructions from your Openlitespeed admin dashboard "
@@ -5701,37 +5722,37 @@ msgid ""
5701
  "could not do it for you."
5702
  msgstr ""
5703
 
5704
- #: lib/thickbox.php:337
5705
  msgid "Enable the sandbox."
5706
  msgstr ""
5707
 
5708
- #: lib/thickbox.php:337
5709
  msgid ""
5710
  "If there were a problem during the installation, NinjaFirewall would undo "
5711
  "those changes automatically for you."
5712
  msgstr ""
5713
 
5714
- #: lib/thickbox.php:338
5715
  msgid "Finish Installation"
5716
  msgstr ""
5717
 
5718
- #: lib/thickbox.php:356
5719
  msgid "Configuration"
5720
  msgstr ""
5721
 
5722
- #: lib/thickbox.php:360
5723
  msgid "Full WAF mode"
5724
  msgstr ""
5725
 
5726
- #: lib/thickbox.php:374
5727
  msgid "Save Changes"
5728
  msgstr ""
5729
 
5730
- #: lib/thickbox.php:385
5731
  msgid "WordPress WAF mode"
5732
  msgstr ""
5733
 
5734
- #: lib/thickbox.php:392
5735
  msgid ""
5736
  "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
5737
  "admin dashboard, click on \"Virtual Host\", select your domain and remove "
@@ -5739,23 +5760,23 @@ msgid ""
5739
  "the \"General\" tab, and restart Openlitespeed."
5740
  msgstr ""
5741
 
5742
- #: lib/thickbox.php:393 lib/thickbox.php:400
5743
  msgid "Downgrade to WordPress WAF mode"
5744
  msgstr ""
5745
 
5746
- #: lib/thickbox.php:397
5747
  msgid "If you want to downgrade to WordPress WAF mode, click the button below."
5748
  msgstr ""
5749
 
5750
- #: lib/thickbox.php:402
5751
  msgid "You may have to wait five minutes for the changes to take effect."
5752
  msgstr ""
5753
 
5754
- #: lib/thickbox.php:409
5755
  msgid "Cancel and Close"
5756
  msgstr ""
5757
 
5758
- #: lib/utils.php:188 lib/utils.php:196 lib/utils.php:295
5759
  msgid "N/A"
5760
  msgstr ""
5761
 
@@ -5769,7 +5790,7 @@ msgstr ""
5769
  msgid "Attempt to edit a published %s (ID: %s)"
5770
  msgstr ""
5771
 
5772
- #: lib/utils.php:212 lib/utils.php:287
5773
  msgid "Unauthenticated user"
5774
  msgstr ""
5775
 
@@ -5783,7 +5804,7 @@ msgid ""
5783
  "doesn't have the right capabilities:"
5784
  msgstr ""
5785
 
5786
- #: lib/utils.php:226 lib/utils.php:307 lib/utils.php:426 lib/utils.php:1216
5787
  msgid "Username:"
5788
  msgstr ""
5789
 
@@ -5791,152 +5812,152 @@ msgstr ""
5791
  msgid "Action:"
5792
  msgstr ""
5793
 
5794
- #: lib/utils.php:242 lib/utils.php:322 lib/utils.php:439 lib/utils.php:1232
5795
- #: lib/utils.php:1480
5796
  msgid "A PHP backtrace has been attached to this message for your convenience."
5797
  msgstr ""
5798
 
5799
- #: lib/utils.php:244 lib/utils.php:324 lib/utils.php:1234 lib/utils.php:1490
5800
  msgid ""
5801
  "This protection (and notification) can be turned off from NinjaFirewall "
5802
  "\"Firewall Policies\" page."
5803
  msgstr ""
5804
 
5805
- #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:339 lib/utils.php:340
5806
- #: lib/utils.php:456 lib/utils.php:457 lib/utils.php:1250 lib/utils.php:1251
5807
  msgid "You are not allowed to perform this task."
5808
  msgstr ""
5809
 
5810
- #: lib/utils.php:298
5811
  msgid "Blocked post/page deletion attempt"
5812
  msgstr ""
5813
 
5814
- #: lib/utils.php:305
5815
  msgid ""
5816
  "NinjaFirewall has blocked an attempt to delete a post by a user who doesn't "
5817
  "have the right capabilities:"
5818
  msgstr ""
5819
 
5820
- #: lib/utils.php:416
5821
  msgid "Blocked user account creation"
5822
  msgstr ""
5823
 
5824
- #: lib/utils.php:423
5825
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
5826
  msgstr ""
5827
 
5828
- #: lib/utils.php:521
5829
  #, php-format
5830
  msgid "Backup file is corrupted, deleting it (%s)"
5831
  msgstr ""
5832
 
5833
- #: lib/utils.php:529
5834
  #, php-format
5835
  msgid ""
5836
  "NinjaFirewall's options are corrupted, restoring them from last known good "
5837
  "backup file (%s)"
5838
  msgstr ""
5839
 
5840
- #: lib/utils.php:535
5841
  msgid ""
5842
  "NinjaFirewall's options are corrupted, restoring their default values (no "
5843
  "valid backup found)"
5844
  msgstr ""
5845
 
5846
- #: lib/utils.php:718
5847
  msgid ""
5848
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
5849
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
5850
  "HTTP status code). You can safely ignore it."
5851
  msgstr ""
5852
 
5853
- #: lib/utils.php:741 lib/utils.php:745
5854
  msgid "NinjaFirewall error"
5855
  msgstr ""
5856
 
5857
- #: lib/utils.php:742
5858
  #, php-format
5859
  msgid ""
5860
  "%s directory cannot be created. Please review your installation and ensure "
5861
  "that %s is writable."
5862
  msgstr ""
5863
 
5864
- #: lib/utils.php:746
5865
  #, php-format
5866
  msgid ""
5867
  "%s directory is read-only. Please review your installation and ensure that "
5868
  "%s is writable."
5869
  msgstr ""
5870
 
5871
- #: lib/utils.php:761
5872
  msgid "unknown error"
5873
  msgstr ""
5874
 
5875
- #: lib/utils.php:763
5876
  msgid "NinjaFirewall fatal error:"
5877
  msgstr ""
5878
 
5879
- #: lib/utils.php:764
5880
  msgid "Review your installation, your site is not protected."
5881
  msgstr ""
5882
 
5883
- #: lib/utils.php:785
5884
  msgid "Alert: WordPress console login"
5885
  msgstr ""
5886
 
5887
- #: lib/utils.php:791
5888
  msgid "Someone just logged in to your WordPress admin console:"
5889
  msgstr ""
5890
 
5891
- #: lib/utils.php:910 lib/utils.php:937
5892
  msgid "Forbidden access"
5893
  msgstr ""
5894
 
5895
- #: lib/utils.php:956
5896
  #, php-format
5897
  msgid ""
5898
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
5899
  "href=\"%s\">Lost your password</a>?"
5900
  msgstr ""
5901
 
5902
- #: lib/utils.php:1034
5903
  msgid "[NinjaFirewall] Alert: Database changes detected"
5904
  msgstr ""
5905
 
5906
- #: lib/utils.php:1035
5907
  msgid ""
5908
  "NinjaFirewall has detected that one or more administrator accounts were "
5909
  "modified in the database:"
5910
  msgstr ""
5911
 
5912
- #: lib/utils.php:1040
5913
  #, php-format
5914
  msgid "Total administrators : %s"
5915
  msgstr ""
5916
 
5917
- #: lib/utils.php:1049
5918
  msgid ""
5919
  "If you cannot see any modifications in the above fields, it is possible that "
5920
  "the administrator password was changed."
5921
  msgstr ""
5922
 
5923
- #: lib/utils.php:1202
5924
  msgid "Blocked privilege escalation attempt"
5925
  msgstr ""
5926
 
5927
- #: lib/utils.php:1210
5928
  msgid ""
5929
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
5930
  "who does not have administrative privileges:"
5931
  msgstr ""
5932
 
5933
- #: lib/utils.php:1262
5934
  msgid ""
5935
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
5936
  "whitelisted."
5937
  msgstr ""
5938
 
5939
- #: lib/utils.php:1277
5940
  #, php-format
5941
  msgid ""
5942
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
@@ -5945,91 +5966,91 @@ msgid ""
5945
  "rate it. Thank you!"
5946
  msgstr ""
5947
 
5948
- #: lib/utils.php:1452
5949
  msgid ""
5950
  "The attempt was blocked and the option was reversed to its original value."
5951
  msgstr ""
5952
 
5953
- #: lib/utils.php:1457
5954
  msgid "Attempt to modify WordPress settings"
5955
  msgstr ""
5956
 
5957
- #: lib/utils.php:1458
5958
  msgid ""
5959
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
5960
  "settings by a user that does not have administrative privileges:"
5961
  msgstr ""
5962
 
5963
- #: lib/utils.php:1459 lib/utils.php:1468
5964
  #, php-format
5965
  msgid "Option: %s"
5966
  msgstr ""
5967
 
5968
- #: lib/utils.php:1460
5969
  #, php-format
5970
  msgid "Original value: %s"
5971
  msgstr ""
5972
 
5973
- #: lib/utils.php:1461
5974
  #, php-format
5975
  msgid "Modified value: %s"
5976
  msgstr ""
5977
 
5978
- #: lib/utils.php:1462 lib/utils.php:1470
5979
  #, php-format
5980
  msgid "Action taken: %s"
5981
  msgstr ""
5982
 
5983
- #: lib/utils.php:1466
5984
  msgid "Code injection attempt in WordPress options table"
5985
  msgstr ""
5986
 
5987
- #: lib/utils.php:1467
5988
  msgid ""
5989
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
5990
  "table by a user that does not have administrative privileges:"
5991
  msgstr ""
5992
 
5993
- #: lib/utils.php:1469
5994
  #, php-format
5995
  msgid "Code: %s"
5996
  msgstr ""
5997
 
5998
- #: lib/utils.php:1565
5999
  msgid "Important: NinjaFirewall has detected that this is a security update."
6000
  msgstr ""
6001
 
6002
- #: lib/utils.php:1568
6003
  msgid "More info about this warning."
6004
  msgstr ""
6005
 
6006
- #: lib/utils.php:1591
6007
  #, php-format
6008
  msgid "Cannot send notification, no valid email found (%s)"
6009
  msgstr ""
6010
 
6011
- #: lib/utils.php:1616
6012
  #, php-format
6013
  msgid ""
6014
  "If you don't have access to that site any longer, you can remove your email "
6015
  "by clicking the following link (valid for 12 hours): %s"
6016
  msgstr ""
6017
 
6018
- #: lib/utils.php:1642
6019
  #, php-format
6020
  msgid "Error, cannot create the %s folder."
6021
  msgstr ""
6022
 
6023
- #: lib/utils.php:1643 lib/utils.php:1652 lib/utils.php:1661
6024
  msgid "Check your server permissions and try again."
6025
  msgstr ""
6026
 
6027
- #: lib/utils.php:1651
6028
  #, php-format
6029
  msgid "Error, the %s folder is not writable."
6030
  msgstr ""
6031
 
6032
- #: lib/utils.php:1660
6033
  #, php-format
6034
  msgid "Error, cannot write %s."
6035
  msgstr ""
@@ -6058,23 +6079,23 @@ msgstr ""
6058
  msgid "View firewall log"
6059
  msgstr ""
6060
 
6061
- #: lib/widget.php:134
6062
- msgid "Latest Security News"
6063
  msgstr ""
6064
 
6065
- #: lib/widget.php:138
6066
  msgid "M jS, Y"
6067
  msgstr ""
6068
 
6069
- #: lib/widget.php:149
6070
  msgid "More Security News"
6071
  msgstr ""
6072
 
6073
- #: lib/widget.php:149
6074
  msgid "(opens in a new tab)"
6075
  msgstr ""
6076
 
6077
- #: lib/widget.php:149
6078
  msgid "NinjaFirewall's Home"
6079
  msgstr ""
6080
 
@@ -6571,79 +6592,79 @@ msgstr ""
6571
  msgid "Error: The HTTP server returned the following error code:"
6572
  msgstr ""
6573
 
6574
- #: ninjafirewall.php:641 ninjafirewall.php:761 ninjafirewall.php:830
6575
  msgid "Error: Security nonces do not match. Reload the page and try again."
6576
  msgstr ""
6577
 
6578
- #: ninjafirewall.php:647
6579
  msgid "Error: NinjaFirewall is disabled"
6580
  msgstr ""
6581
 
6582
- #: ninjafirewall.php:652 ninjafirewall.php:766 ninjafirewall.php:796
6583
  #, php-format
6584
  msgid "Error: missing parameter (%s)."
6585
  msgstr ""
6586
 
6587
- #: ninjafirewall.php:892
6588
  msgid "NinjaFirewall: Dashboard"
6589
  msgstr ""
6590
 
6591
- #: ninjafirewall.php:896
6592
  msgid "NinjaFirewall: Firewall Options"
6593
  msgstr ""
6594
 
6595
- #: ninjafirewall.php:900
6596
  msgid "NinjaFirewall: Firewall Policies"
6597
  msgstr ""
6598
 
6599
- #: ninjafirewall.php:904
6600
  msgid "NinjaFirewall: Monitoring"
6601
  msgstr ""
6602
 
6603
- #: ninjafirewall.php:914
6604
  msgid "NinjaFirewall: Anti-Malware"
6605
  msgstr ""
6606
 
6607
- #: ninjafirewall.php:918
6608
  msgid "NinjaFirewall: Network"
6609
  msgstr ""
6610
 
6611
- #: ninjafirewall.php:922
6612
  msgid "NinjaFirewall: Event Notifications"
6613
  msgstr ""
6614
 
6615
- #: ninjafirewall.php:926
6616
  msgid "NinjaFirewall: Log-in Protection"
6617
  msgstr ""
6618
 
6619
- #: ninjafirewall.php:930
6620
  msgid "NinjaFirewall: Logs"
6621
  msgstr ""
6622
 
6623
- #: ninjafirewall.php:934
6624
  msgid "NinjaFirewall: Security Rules"
6625
  msgstr ""
6626
 
6627
- #: ninjafirewall.php:978
6628
  msgid "NinjaFirewall Settings"
6629
  msgstr ""
6630
 
6631
- #: ninjafirewall.php:986
6632
  msgid "NinjaFirewall is enabled"
6633
  msgstr ""
6634
 
6635
- #: ninjafirewall.php:1126
6636
  msgid "Access Restricted"
6637
  msgstr ""
6638
 
6639
- #: ninjafirewall.php:1132
6640
  msgid "Settings"
6641
  msgstr ""
6642
 
6643
- #: ninjafirewall.php:1133
6644
  msgid "Upgrade to Premium"
6645
  msgstr ""
6646
 
6647
- #: ninjafirewall.php:1134
6648
  msgid "Rate it!"
6649
  msgstr ""
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Stable (latest release)\n"
5
+ "POT-Creation-Date: 2022-02-03 17:19+0700\n"
6
  "PO-Revision-Date: 2018-04-05 22:52+0700\n"
7
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
8
  "Language-Team: \n"
19
  "X-Poedit-SearchPath-0: .\n"
20
  "X-Poedit-SearchPathExcluded-0: /languages\n"
21
 
22
+ #: lib/anti_malware.php:24 ninjafirewall.php:909
23
  msgid "Anti-Malware"
24
  msgstr ""
25
 
98
  msgid "Your changes have been saved."
99
  msgstr ""
100
 
101
+ #: lib/dashboard.php:132 ninjafirewall.php:887
102
  msgid "Dashboard"
103
  msgstr ""
104
 
403
  msgid "Help &amp; configuration"
404
  msgstr ""
405
 
 
 
 
 
406
  #: lib/dashboard_about.php:29
407
  msgid "Our blog:"
408
  msgstr ""
421
  msgid "Rate it on WordPress.org!"
422
  msgstr ""
423
 
 
 
 
 
424
  #: lib/dashboard_statistics.php:76
425
  msgid "You do not have any stats for the selected month yet."
426
  msgstr ""
506
  #: lib/email_sodium.php:169 lib/monitoring_file_check.php:759
507
  #: lib/monitoring_file_check.php:761 lib/monitoring_file_check.php:781
508
  #: lib/monitoring_file_check.php:783 lib/security_rules_update.php:559
509
+ #: lib/security_rules_update.php:561 lib/utils.php:225 lib/utils.php:305
510
+ #: lib/utils.php:423 lib/utils.php:1077 lib/utils.php:1251 lib/utils.php:1522
511
  msgid "Blog:"
512
  msgstr ""
513
 
515
  msgid "Email address:"
516
  msgstr ""
517
 
518
+ #: lib/email_sodium.php:171 lib/utils.php:230 lib/utils.php:309
519
+ #: lib/utils.php:425 lib/utils.php:1259 lib/utils.php:1523
520
  msgid "User IP:"
521
  msgstr ""
522
 
523
  #: lib/email_sodium.php:172 lib/event_updates.php:157 lib/utils.php:233
524
+ #: lib/utils.php:312 lib/utils.php:428 lib/utils.php:1078 lib/utils.php:1262
525
+ #: lib/utils.php:1526
526
  msgid "Date:"
527
  msgstr ""
528
 
553
  msgid "No"
554
  msgstr ""
555
 
556
+ #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:917
557
  msgid "Event Notifications"
558
  msgstr ""
559
 
737
  msgid "Save Event Notifications"
738
  msgstr ""
739
 
740
+ #: lib/event_notifications.php:484
741
  msgid "[NinjaFirewall] Daily Activity Report"
742
  msgstr ""
743
 
744
+ #: lib/event_notifications.php:494
745
  #, php-format
746
  msgid "Daily activity report for: %s"
747
  msgstr ""
748
 
749
+ #: lib/event_notifications.php:495
750
  msgid "Date Range Processed: Yesterday"
751
  msgstr ""
752
 
753
+ #: lib/event_notifications.php:497
754
  msgid "Blocked threats:"
755
  msgstr ""
756
 
757
+ #: lib/event_notifications.php:499
758
  msgid "critical:"
759
  msgstr ""
760
 
761
+ #: lib/event_notifications.php:500
762
  msgid "high:"
763
  msgstr ""
764
 
765
+ #: lib/event_notifications.php:501
766
  msgid "medium:"
767
  msgstr ""
768
 
769
+ #: lib/event_notifications.php:503
770
  msgid "Blocked brute-force attacks:"
771
  msgstr ""
772
 
773
+ #: lib/event_notifications.php:504 lib/event_updates.php:219 lib/utils.php:1089
774
  msgid ""
775
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
776
  "\" page."
832
  msgid "Theme: %s"
833
  msgstr ""
834
 
835
+ #: lib/event_updates.php:217 lib/utils.php:1608
836
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
837
  msgstr ""
838
 
865
  msgid "activated"
866
  msgstr ""
867
 
868
+ #: lib/events.php:45 lib/events.php:93 lib/events.php:175 lib/events.php:187
869
  msgid "deleted"
870
  msgstr ""
871
 
872
  #: lib/events.php:81 lib/events.php:103 lib/events.php:118 lib/events.php:122
873
+ #: lib/events.php:140 lib/events.php:149 lib/events.php:171 lib/events.php:183
874
  msgid "updated"
875
  msgstr ""
876
 
878
  msgid "deactivated"
879
  msgstr ""
880
 
881
+ #: lib/events.php:130 lib/events.php:153 lib/events.php:167 lib/events.php:179
882
  msgid "installed"
883
  msgstr ""
884
 
885
+ #: lib/events.php:135 lib/events.php:157
886
  msgid "uploaded"
887
  msgstr ""
888
 
889
+ #: lib/events.php:197
890
  #, php-format
891
  msgid "[NinjaFirewall] Alert: %s"
892
  msgstr ""
893
 
894
+ #: lib/events.php:199 lib/events.php:201 lib/utils.php:827
895
  msgid "-Blog:"
896
  msgstr ""
897
 
898
+ #: lib/events.php:204
899
  msgid "NinjaFirewall has detected the following activity on your account:"
900
  msgstr ""
901
 
902
+ #: lib/events.php:206 lib/utils.php:832
903
  msgid "-User:"
904
  msgstr ""
905
 
906
+ #: lib/events.php:207 lib/utils.php:833
907
  msgid "-IP:"
908
  msgstr ""
909
 
910
+ #: lib/events.php:208 lib/utils.php:834
911
  msgid "-Date:"
912
  msgstr ""
913
 
914
+ #: lib/firewall_options.php:29 ninjafirewall.php:891
915
  msgid "Firewall Options"
916
  msgstr ""
917
 
1109
  "enable NinjaFirewall's Full WAF mode."
1110
  msgstr ""
1111
 
1112
+ #: lib/firewall_policies.php:62 ninjafirewall.php:895
1113
  msgid "Firewall Policies"
1114
  msgstr ""
1115
 
1249
  "not have the right capabilities"
1250
  msgstr ""
1251
 
1252
+ #: lib/firewall_policies.php:411 lib/thickbox.php:95
1253
  msgid "(recommended)"
1254
  msgstr ""
1255
 
1609
  msgid "Set %s (Chrome, Opera and Firefox browsers)"
1610
  msgstr ""
1611
 
1612
+ #: lib/firewall_policies.php:992
1613
+ msgid "Custom HTTP headers"
1614
+ msgstr ""
1615
+
1616
+ #: lib/firewall_policies.php:995
1617
+ msgid ""
1618
+ "You can enter one or more custom HTTP headers. The format is <code>header: "
1619
+ "value</code>, one per line."
1620
+ msgstr ""
1621
+
1622
+ #: lib/firewall_policies.php:1000
1623
+ msgid "HTTP headers test"
1624
+ msgstr ""
1625
+
1626
+ #: lib/firewall_policies.php:1002
1627
+ msgid "View your website's HTTP response headers"
1628
+ msgstr ""
1629
+
1630
+ #: lib/firewall_policies.php:1005
1631
+ msgid "Make sure to save your changes before running the test."
1632
+ msgstr ""
1633
+
1634
+ #: lib/firewall_policies.php:1047
1635
  msgid ""
1636
  "Block PHP built-in wrappers in <code>GET</code>, <code>POST</code>, "
1637
  "<code>HTTP_USER_AGENT</code>, <code>HTTP_REFERER</code> and cookies"
1638
  msgstr ""
1639
 
1640
+ #: lib/firewall_policies.php:1086
1641
  msgid "Block serialized PHP objects in the following global variables"
1642
  msgstr ""
1643
 
1644
+ #: lib/firewall_policies.php:1096 lib/help.php:295
1645
  msgid "Block attempts to override PHP Superglobals"
1646
  msgstr ""
1647
 
1648
+ #: lib/firewall_policies.php:1102 lib/help.php:297
1649
  msgid "Hide PHP notice and error messages"
1650
  msgstr ""
1651
 
1652
+ #: lib/firewall_policies.php:1108
1653
  msgid "Sanitise <code>PHP_SELF</code>"
1654
  msgstr ""
1655
 
1656
+ #: lib/firewall_policies.php:1114
1657
  msgid "Sanitise <code>PATH_TRANSLATED</code>"
1658
  msgstr ""
1659
 
1660
+ #: lib/firewall_policies.php:1120
1661
  msgid "Sanitise <code>PATH_INFO</code>"
1662
  msgstr ""
1663
 
1664
+ #: lib/firewall_policies.php:1134
1665
  msgid "This option is not compatible with your actual configuration."
1666
  msgstr ""
1667
 
1668
+ #: lib/firewall_policies.php:1156 lib/help.php:301
1669
  msgid "Various"
1670
  msgstr ""
1671
 
1672
+ #: lib/firewall_policies.php:1159
1673
  msgid "Block the <code>DOCUMENT_ROOT</code> server variable in HTTP request"
1674
  msgstr ""
1675
 
1676
+ #: lib/firewall_policies.php:1166 lib/help.php:304
1677
  msgid "Block ASCII character 0x00 (NULL byte)"
1678
  msgstr ""
1679
 
1680
+ #: lib/firewall_policies.php:1172 lib/help.php:306
1681
  msgid "Block ASCII control characters 1 to 8 and 14 to 31"
1682
  msgstr ""
1683
 
1684
+ #: lib/firewall_policies.php:1185
1685
  msgid "Save Firewall Policies"
1686
  msgstr ""
1687
 
1688
+ #: lib/firewall_policies.php:1187
1689
  msgid "Restore Default Values"
1690
  msgstr ""
1691
 
2489
  "package (third-party software, shell script, backdoor etc)."
2490
  msgstr ""
2491
 
2492
+ #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:913
2493
  msgid "Network"
2494
  msgstr ""
2495
 
2525
  "theme in order to take full control of your website."
2526
  msgstr ""
2527
 
2528
+ #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:921
2529
  msgid "Login Protection"
2530
  msgstr ""
2531
 
2983
  msgstr ""
2984
 
2985
  #: lib/i18n-extra.php:21
 
 
 
 
2986
  msgid "License"
2987
  msgstr ""
2988
 
2989
+ #: lib/i18n-extra.php:22
2990
  msgid "Enter your NinjaFirewall WP+ license and click on the save button"
2991
  msgstr ""
2992
 
2993
+ #: lib/i18n-extra.php:23
2994
  msgid "Don't have a license yet?"
2995
  msgstr ""
2996
 
2997
+ #: lib/i18n-extra.php:24
2998
  msgid "Click here to get one"
2999
  msgstr ""
3000
 
3001
+ #: lib/i18n-extra.php:25
3002
  msgid "Save License"
3003
  msgstr ""
3004
 
3005
+ #: lib/i18n-extra.php:26
3006
  msgid "This license has expired and is no longer valid."
3007
  msgstr ""
3008
 
3009
+ #: lib/i18n-extra.php:27
3010
  msgid "Your license is not valid"
3011
  msgstr ""
3012
 
3013
+ #: lib/i18n-extra.php:28
3014
  msgid ""
3015
  "An unknown error occurred while connecting to NinjaFirewall servers. Please "
3016
  "try again in a few minutes"
3017
  msgstr ""
3018
 
3019
+ #: lib/i18n-extra.php:29
3020
  msgid ""
3021
  "An error occurred while connecting to NinjaFirewall servers. Please try "
3022
  "again in a few minutes"
3023
  msgstr ""
3024
 
3025
+ #: lib/i18n-extra.php:30
3026
  msgid "Your NinaFirewall license has expired!"
3027
  msgstr ""
3028
 
3029
+ #: lib/i18n-extra.php:31
3030
  msgid "Click here to renew it"
3031
  msgstr ""
3032
 
3033
+ #: lib/i18n-extra.php:32
3034
  msgid "Your NinaFirewall license will expire soon!"
3035
  msgstr ""
3036
 
3037
+ #: lib/i18n-extra.php:33
3038
  msgid "You do not have a valid NinjaFirewall license"
3039
  msgstr ""
3040
 
3041
+ #: lib/i18n-extra.php:34
3042
  #, php-format
3043
  msgid ""
3044
  "The shared memory block seems corrupted. Try to reload this page to fix it "
3046
  "to avoid any problem."
3047
  msgstr ""
3048
 
3049
+ #: lib/i18n-extra.php:35
3050
  #, php-format
3051
  msgid "(RAM usage: %s bytes)"
3052
  msgstr ""
3053
 
3054
+ #: lib/i18n-extra.php:36
3055
  #, php-format
3056
  msgid ""
3057
  "Unable to access/read the shared memory block. Try to reload this page or, "
3059
  "avoid any problem."
3060
  msgstr ""
3061
 
3062
+ #: lib/i18n-extra.php:37
3063
  msgid "Firewall is disabled"
3064
  msgstr ""
3065
 
3066
+ #: lib/i18n-extra.php:38
3067
  msgid "Shared memory"
3068
  msgstr ""
3069
 
3070
+ #: lib/i18n-extra.php:39
3071
  #, php-format
3072
  msgid ""
3073
  "You are not whitelisted. Ensure that the \"Do not block the following users"
3076
  "from the WordPress administration dashboard."
3077
  msgstr ""
3078
 
3079
+ #: lib/i18n-extra.php:40
3080
  #, php-format
3081
  msgid ""
3082
  "<a href=\"%s\">Access Control Source IP</a> is setup to use %s, however your "
3083
  "server does not support that variable. All IP-based directives will fail."
3084
  msgstr ""
3085
 
3086
+ #: lib/i18n-extra.php:41
3087
  #, php-format
3088
  msgid "You have a private IP: %s"
3089
  msgstr ""
3090
 
3091
+ #: lib/i18n-extra.php:42
3092
  #, php-format
3093
  msgid ""
3094
  "If your site is behind a reverse proxy or a load balancer, ensure that the "
3095
  "<a href=\"%s\">Source IP</a> is setup accordingly."
3096
  msgstr ""
3097
 
3098
+ #: lib/i18n-extra.php:43
3099
  #, php-format
3100
  msgid ""
3101
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that the "
3102
  "<a href=\"%s\">Source IP</a> is setup accordingly."
3103
  msgstr ""
3104
 
3105
+ #: lib/i18n-extra.php:44
3106
  #, php-format
3107
  msgid ""
3108
  "%s detected: you seem to be using Incapsula CDN services. Ensure that the <a "
3109
  "href=\"%s\">Source IP</a> is setup accordingly."
3110
  msgstr ""
3111
 
3112
+ #: lib/i18n-extra.php:45
3113
  msgid "Logging"
3114
  msgstr ""
3115
 
3116
+ #: lib/i18n-extra.php:46
3117
  msgid "Logging is disabled."
3118
  msgstr ""
3119
 
3120
+ #: lib/i18n-extra.php:47
3121
  msgid "Click here to re-enable it."
3122
  msgstr ""
3123
 
3124
+ #: lib/i18n-extra.php:48
3125
  #, php-format
3126
  msgid "Error cannot create the language files directory (%s)"
3127
  msgstr ""
3128
 
3129
+ #: lib/i18n-extra.php:49
3130
  #, php-format
3131
  msgid "Error while downloading language file %s (%s)"
3132
  msgstr ""
3133
 
3134
+ #: lib/i18n-extra.php:50
3135
  #, php-format
3136
  msgid ""
3137
  "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
3141
  "the Dashboard page%s and enable NinjaFirewall's Full WAF mode."
3142
  msgstr ""
3143
 
3144
+ #: lib/i18n-extra.php:51
3145
  msgid "General"
3146
  msgstr ""
3147
 
3148
+ #: lib/i18n-extra.php:52
3149
  msgid "Geolocation"
3150
  msgstr ""
3151
 
3152
+ #: lib/i18n-extra.php:53
3153
  msgid "IP address"
3154
  msgstr ""
3155
 
3156
+ #: lib/i18n-extra.php:54
3157
  msgid "URL address"
3158
  msgstr ""
3159
 
3160
+ #: lib/i18n-extra.php:55
3161
  msgid "Bot"
3162
  msgstr ""
3163
 
3164
+ #: lib/i18n-extra.php:56
3165
  msgid "User Input"
3166
  msgstr ""
3167
 
3168
+ #: lib/i18n-extra.php:57
3169
  msgid "Role-based Access Control"
3170
  msgstr ""
3171
 
3172
+ #: lib/i18n-extra.php:58
3173
  msgid "Do not block the following users (must be logged in)"
3174
  msgstr ""
3175
 
3176
+ #: lib/i18n-extra.php:59
3177
  msgid "Retrieve visitors IP address from"
3178
  msgstr ""
3179
 
3180
+ #: lib/i18n-extra.php:60
3181
  msgid "Other"
3182
  msgstr ""
3183
 
3184
+ #: lib/i18n-extra.php:61
3185
  #, php-format
3186
  msgid "Your server does not seem to support the %s variable."
3187
  msgstr ""
3188
 
3189
+ #: lib/i18n-extra.php:62
3190
  msgid "HTTP Methods"
3191
  msgstr ""
3192
 
3193
+ #: lib/i18n-extra.php:63
3194
  msgid "All Access Control directives should apply to the folowing HTTP methods"
3195
  msgstr ""
3196
 
3197
+ #: lib/i18n-extra.php:64
3198
  msgid "Enable Geolocation"
3199
  msgstr ""
3200
 
3201
+ #: lib/i18n-extra.php:65
3202
  msgid "Retrieve the ISO 3166 code from"
3203
  msgstr ""
3204
 
3205
+ #: lib/i18n-extra.php:66
3206
  msgid "PHP Variable"
3207
  msgstr ""
3208
 
3209
+ #: lib/i18n-extra.php:67
3210
  msgid "Block the following ISO 3166 codes"
3211
  msgstr ""
3212
 
3213
+ #: lib/i18n-extra.php:68
3214
  #, php-format
3215
  msgid "Total blocked items: %s"
3216
  msgstr ""
3217
 
3218
+ #: lib/i18n-extra.php:69
3219
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3220
  msgstr ""
3221
 
3222
+ #: lib/i18n-extra.php:70
3223
  msgid "View allowed syntax"
3224
  msgstr ""
3225
 
3226
+ #: lib/i18n-extra.php:71
3227
  #, php-format
3228
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3229
  msgstr ""
3230
 
3231
+ #: lib/i18n-extra.php:72
3232
  msgid "One item per line."
3233
  msgstr ""
3234
 
3235
+ #: lib/i18n-extra.php:73
3236
  msgid ""
3237
  "Leave this field empty if you want geolocation to apply to all your PHP "
3238
  "scripts."
3239
  msgstr ""
3240
 
3241
+ #: lib/i18n-extra.php:74
3242
  msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3243
  msgstr ""
3244
 
3245
+ #: lib/i18n-extra.php:75
3246
  msgid "Write event to the firewall log"
3247
  msgstr ""
3248
 
3249
+ #: lib/i18n-extra.php:76
3250
  msgid "Allow the following IP, CIDR or AS number"
3251
  msgstr ""
3252
 
3253
+ #: lib/i18n-extra.php:77
3254
  #, php-format
3255
  msgid "IPv4 address: %s"
3256
  msgstr ""
3257
 
3258
+ #: lib/i18n-extra.php:78
3259
  #, php-format
3260
  msgid "IPv4 CIDR: %s"
3261
  msgstr ""
3262
 
3263
+ #: lib/i18n-extra.php:79
3264
  #, php-format
3265
  msgid "IPv6 address: %s"
3266
  msgstr ""
3267
 
3268
+ #: lib/i18n-extra.php:80
3269
  #, php-format
3270
  msgid "IPv6 CIDR: %s"
3271
  msgstr ""
3272
 
3273
+ #: lib/i18n-extra.php:81
3274
  #, php-format
3275
  msgid "Autonomous System number: %s"
3276
  msgstr ""
3277
 
3278
+ #: lib/i18n-extra.php:82
3279
  msgid "Whitelist:"
3280
  msgstr ""
3281
 
3282
+ #: lib/i18n-extra.php:83
3283
  msgid "Enter one item per line."
3284
  msgstr ""
3285
 
3286
+ #: lib/i18n-extra.php:84
3287
  msgid "External Services"
3288
  msgstr ""
3289
 
3290
+ #: lib/i18n-extra.php:85
3291
  msgid "Whitelist IP addresses from the following services:"
3292
  msgstr ""
3293
 
3294
+ #: lib/i18n-extra.php:86
3295
  msgid "View IP addresses"
3296
  msgstr ""
3297
 
3298
+ #: lib/i18n-extra.php:87
3299
  msgid "Block the following IP, CIDR or AS number"
3300
  msgstr ""
3301
 
3302
+ #: lib/i18n-extra.php:88
3303
  msgid "Blacklist:"
3304
  msgstr ""
3305
 
3306
+ #: lib/i18n-extra.php:89
3307
  msgid "Rate Limiting"
3308
  msgstr ""
3309
 
3310
+ #: lib/i18n-extra.php:90
3311
  #, php-format
3312
  msgid ""
3313
  "Block for %s seconds any IP address with more than %s connections within a "
3314
  "%s interval."
3315
  msgstr ""
3316
 
3317
+ #: lib/i18n-extra.php:91
3318
  msgid "5-second"
3319
  msgstr ""
3320
 
3321
+ #: lib/i18n-extra.php:92
3322
  msgid "10-second"
3323
  msgstr ""
3324
 
3325
+ #: lib/i18n-extra.php:93
3326
  msgid "15-second"
3327
  msgstr ""
3328
 
3329
+ #: lib/i18n-extra.php:94
3330
  msgid "30-second"
3331
  msgstr ""
3332
 
3333
+ #: lib/i18n-extra.php:95
3334
  msgid "Allow access to the following URL"
3335
  msgstr ""
3336
 
3337
+ #: lib/i18n-extra.php:96
3338
  #, php-format
3339
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3340
  msgstr ""
3341
 
3342
+ #: lib/i18n-extra.php:97
3343
  msgid "Block access to the following URL"
3344
  msgstr ""
3345
 
3346
+ #: lib/i18n-extra.php:98
3347
  msgid "Reject the following bots"
3348
  msgstr ""
3349
 
3350
+ #: lib/i18n-extra.php:99
3351
  msgid "A full or partial case-insensitive string."
3352
  msgstr ""
3353
 
3354
+ #: lib/i18n-extra.php:100
3355
  #, php-format
3356
  msgid "Allowed characters are: %s and %s."
3357
  msgstr ""
3358
 
3359
+ #: lib/i18n-extra.php:101
3360
  msgid "Blocked bots:"
3361
  msgstr ""
3362
 
3363
+ #: lib/i18n-extra.php:102
3364
  msgid "The default list of bots will be restored. Continue?"
3365
  msgstr ""
3366
 
3367
+ #: lib/i18n-extra.php:103
3368
  msgid "Restore default bots list"
3369
  msgstr ""
3370
 
3371
+ #: lib/i18n-extra.php:104
3372
  msgid "Do not filter the following user input"
3373
  msgstr ""
3374
 
3375
+ #: lib/i18n-extra.php:105
3376
  msgid ""
3377
  "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
3378
  "sensitive input:"
3379
  msgstr ""
3380
 
3381
+ #: lib/i18n-extra.php:106
3382
  msgid "Unfiltered input:"
3383
  msgstr ""
3384
 
3385
+ #: lib/i18n-extra.php:107
3386
  msgid "Block the request if the following input is present"
3387
  msgstr ""
3388
 
3389
+ #: lib/i18n-extra.php:108
3390
  msgid "Blocked input:"
3391
  msgstr ""
3392
 
3393
+ #: lib/i18n-extra.php:109
3394
  msgid "Save Access Control directives"
3395
  msgstr ""
3396
 
3397
+ #: lib/i18n-extra.php:110
3398
  msgid ""
3399
  "Warning: Your previous secret key was either corrupted or missing. A new "
3400
  "one, as well as a new public key, were created."
3401
  msgstr ""
3402
 
3403
+ #: lib/i18n-extra.php:111
3404
  msgid "Enable Centralized Logging"
3405
  msgstr ""
3406
 
3407
+ #: lib/i18n-extra.php:112
3408
  msgid "Secret key"
3409
  msgstr ""
3410
 
3411
+ #: lib/i18n-extra.php:113
3412
  msgid "From 30 to 100 ASCII printable characters."
3413
  msgstr ""
3414
 
3415
+ #: lib/i18n-extra.php:114
3416
  msgid "This server's IP address"
3417
  msgstr ""
3418
 
3419
+ #: lib/i18n-extra.php:115
3420
  msgid ""
3421
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
3422
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
3423
  "code> character instead."
3424
  msgstr ""
3425
 
3426
+ #: lib/i18n-extra.php:116
3427
  msgid "Public key"
3428
  msgstr ""
3429
 
3430
+ #: lib/i18n-extra.php:117
3431
  #, php-format
3432
  msgid ""
3433
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
3434
  "more info."
3435
  msgstr ""
3436
 
3437
+ #: lib/i18n-extra.php:118
3438
  msgid "Remote websites URL"
3439
  msgstr ""
3440
 
3441
+ #: lib/i18n-extra.php:119
3442
  msgid ""
3443
  "Enter one URL per line, including the protocol (<code>http://</code> or "
3444
  "<code>https://</code>). Only ASCII URLs are accepted."
3445
  msgstr ""
3446
 
3447
+ #: lib/i18n-extra.php:120
3448
  msgid "Save Options"
3449
  msgstr ""
3450
 
3451
+ #: lib/i18n-extra.php:121
3452
  msgid ""
3453
  "Your changes have been saved. If you are using a caching plugin, do not "
3454
  "forget to clear its cache."
3455
  msgstr ""
3456
 
3457
+ #: lib/i18n-extra.php:122
3458
  msgid "Enable antispam protection"
3459
  msgstr ""
3460
 
3461
+ #: lib/i18n-extra.php:123
3462
  msgid "Protection level"
3463
  msgstr ""
3464
 
3465
+ #: lib/i18n-extra.php:124
3466
  msgid "Low (default)"
3467
  msgstr ""
3468
 
3469
+ #: lib/i18n-extra.php:125
3470
  msgid ""
3471
  "If you are using a caching plugin, consult the contextual help before "
3472
  "enabling the antispam."
3473
  msgstr ""
3474
 
3475
+ #: lib/i18n-extra.php:126
3476
  msgid "Apply protection to"
3477
  msgstr ""
3478
 
3479
+ #: lib/i18n-extra.php:127
3480
  msgid "Comment forms (defaut)"
3481
  msgstr ""
3482
 
3483
+ #: lib/i18n-extra.php:128
3484
  msgid "User Registration form"
3485
  msgstr ""
3486
 
3487
+ #: lib/i18n-extra.php:129
3488
  msgid "Save Antispam options"
3489
  msgstr ""
3490
 
3491
+ #: lib/i18n-extra.php:130
3492
  msgid "Please enable JavaScript"
3493
  msgstr ""
3494
 
3495
+ #: lib/i18n-extra.php:131
3496
  msgid "Sorry, this looks like spam to me."
3497
  msgstr ""
3498
 
3499
+ #: lib/i18n-extra.php:132
3500
  msgid ""
3501
  "Error: You must be whitelisted in order to use that feature: click on the <a "
3502
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
3503
  "not block the following users\" option is enabled for the Admin/Super Admin."
3504
  msgstr ""
3505
 
3506
+ #: lib/i18n-extra.php:133
3507
  msgid ""
3508
  "Your license is valid until the indicated expiration date. If you don't "
3509
  "renew it after this date, NinjaFirewall will keep working and protecting "
3510
  "your website as usual, but updates/upgrades will stop."
3511
  msgstr ""
3512
 
3513
+ #: lib/i18n-extra.php:134
3514
  #, php-format
3515
  msgid ""
3516
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
3517
  msgstr ""
3518
 
3519
+ #: lib/i18n-extra.php:135
3520
  msgid "Use shared memory"
3521
  msgstr ""
3522
 
3523
+ #: lib/i18n-extra.php:136
3524
  msgid ""
3525
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
3526
  "order to speed up all operations. The firewall will no longer need to "
3530
  "processing speed from 25% to 30%, prevent blocking I/O and slow queries."
3531
  msgstr ""
3532
 
3533
+ #: lib/i18n-extra.php:137
3534
  msgid ""
3535
  "This option requires that your PHP version was compiled with the <code>--"
3536
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
3537
  "server/hosting environment, it will be disabled."
3538
  msgstr ""
3539
 
3540
+ #: lib/i18n-extra.php:138
3541
  #, php-format
3542
  msgid ""
3543
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
3547
  "used by that charset."
3548
  msgstr ""
3549
 
3550
+ #: lib/i18n-extra.php:139
3551
  msgid "Language"
3552
  msgstr ""
3553
 
3554
+ #: lib/i18n-extra.php:140
3555
  msgid ""
3556
  "When this option is enabled, NinjaFirewall will download, if available, the "
3557
  "corresponding language files from the WordPress repo. Then, every hour, it "
3558
  "will check if there's a new version and will download it."
3559
  msgstr ""
3560
 
3561
+ #: lib/i18n-extra.php:141
3562
  msgid ""
3563
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
3564
  "locales because they are already included with NinjaFirewall."
3565
  msgstr ""
3566
 
3567
+ #: lib/i18n-extra.php:142
3568
  #, php-format
3569
  msgid ""
3570
  "This options lets you export you current configuration or import it from "
3574
  "configuration, except your current license."
3575
  msgstr ""
3576
 
3577
+ #: lib/i18n-extra.php:143
3578
  msgid ""
3579
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
3580
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
3582
  "SVG files containing Javascript/XML events."
3583
  msgstr ""
3584
 
3585
+ #: lib/i18n-extra.php:144
3586
  msgid "Maximum allowed file size"
3587
  msgstr ""
3588
 
3589
+ #: lib/i18n-extra.php:145
3590
  msgid ""
3591
  "If you allow uploads, you can select the maximum size of an uploaded file. "
3592
  "Any file bigger than this value will be rejected. Note that if your PHP "
3594
  "be used before NinjaFirewall."
3595
  msgstr ""
3596
 
3597
+ #: lib/i18n-extra.php:146
3598
  msgid "Decode Base64-encoded <code>POST</code> variable:"
3599
  msgstr ""
3600
 
3601
+ #: lib/i18n-extra.php:147
3602
  #, php-format
3603
  msgid ""
3604
  "Object Serialization is a PHP feature used by many applications to generate "
3609
  "request, cookies, user agent and referrer variables."
3610
  msgstr ""
3611
 
3612
+ #: lib/i18n-extra.php:148
3613
  msgid ""
3614
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
3615
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
3618
  "is dangerous and should always be rejected."
3619
  msgstr ""
3620
 
3621
+ #: lib/i18n-extra.php:149
3622
  msgid ""
3623
  "This option will block any <code>GET</code> or <code>POST</code> request "
3624
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
3625
  "dumpers and various hacker's shell scripts."
3626
  msgstr ""
3627
 
3628
+ #: lib/i18n-extra.php:150
3629
  msgid ""
3630
  "Access Control is a powerful set of directives that can be used to allow or "
3631
  "restrict access to your website based on many criteria."
3632
  msgstr ""
3633
 
3634
+ #: lib/i18n-extra.php:151
3635
  msgid ""
3636
  "To make better use of them, it is important to understand NinjaFirewall's "
3637
  "directives processing order."
3638
  msgstr ""
3639
 
3640
+ #: lib/i18n-extra.php:152
3641
  msgid ""
3642
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
3643
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
3644
  "on your configuration, they can also apply to HTML pages."
3645
  msgstr ""
3646
 
3647
+ #: lib/i18n-extra.php:153
3648
  msgid "Processing order:"
3649
  msgstr ""
3650
 
3651
+ #: lib/i18n-extra.php:154
3652
  msgid "Incoming HTTP request"
3653
  msgstr ""
3654
 
3655
+ #: lib/i18n-extra.php:155
3656
  #, php-format
3657
  msgid "%s file"
3658
  msgstr ""
3659
 
3660
+ #: lib/i18n-extra.php:156
3661
  msgid "Login Protection."
3662
  msgstr ""
3663
 
3664
+ #: lib/i18n-extra.php:157
3665
  msgid "Access Control (except User Input Access Control):"
3666
  msgstr ""
3667
 
3668
+ #: lib/i18n-extra.php:158
3669
  msgid "Role-based Access Control."
3670
  msgstr ""
3671
 
3672
+ #: lib/i18n-extra.php:159
3673
  msgid "Allowed IPs."
3674
  msgstr ""
3675
 
3676
+ #: lib/i18n-extra.php:160
3677
  msgid "Blocked IPs."
3678
  msgstr ""
3679
 
3680
+ #: lib/i18n-extra.php:161
3681
  msgid "Allowed URLs."
3682
  msgstr ""
3683
 
3684
+ #: lib/i18n-extra.php:162
3685
  msgid "Blocked URLs."
3686
  msgstr ""
3687
 
3688
+ #: lib/i18n-extra.php:163
3689
  msgid "Bot Access Control."
3690
  msgstr ""
3691
 
3692
+ #: lib/i18n-extra.php:164
3693
  msgid "Geolocation."
3694
  msgstr ""
3695
 
3696
+ #: lib/i18n-extra.php:165
3697
  msgid "Rate Limiting."
3698
  msgstr ""
3699
 
3700
+ #: lib/i18n-extra.php:166
3701
  msgid "File Guard."
3702
  msgstr ""
3703
 
3704
+ #: lib/i18n-extra.php:167
3705
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
3706
  msgstr ""
3707
 
3708
+ #: lib/i18n-extra.php:168
3709
  msgid "Response body"
3710
  msgstr ""
3711
 
3712
+ #: lib/i18n-extra.php:169
3713
  msgid "HTTP response headers (Firewall Policies)."
3714
  msgstr ""
3715
 
3716
+ #: lib/i18n-extra.php:170
3717
  msgid "Web Filter."
3718
  msgstr ""
3719
 
3720
+ #: lib/i18n-extra.php:171
3721
  #, php-format
3722
  msgid ""
3723
  "By default, any logged in WordPress administrator will not be blocked by "
3729
  "enforced."
3730
  msgstr ""
3731
 
3732
+ #: lib/i18n-extra.php:172
3733
  msgid "You can also add other users to the whitelist, depending on their role."
3734
  msgstr ""
3735
 
3736
+ #: lib/i18n-extra.php:173
3737
  #, php-format
3738
  msgid ""
3739
  "this option should be used if you are behind a reverse proxy, a load "
3747
  "NinjaFirewall will fall back to <code>REMOTE_ADDR</code>."
3748
  msgstr ""
3749
 
3750
+ #: lib/i18n-extra.php:174
3751
  msgid ""
3752
  "This option lets you select the HTTP method(s). All Access Control "
3753
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
3754
  "methods."
3755
  msgstr ""
3756
 
3757
+ #: lib/i18n-extra.php:175
3758
  msgid ""
3759
  "It does not apply to the \"Firewall Policies\" options, which use their own "
3760
  "ones."
3761
  msgstr ""
3762
 
3763
+ #: lib/i18n-extra.php:176
3764
  msgid ""
3765
  "You can filter and block traffic coming from specific countries/territories."
3766
  msgstr ""
3767
 
3768
+ #: lib/i18n-extra.php:177
3769
  msgid ""
3770
  "This is the two-letter code that is used to define a country/territory (e."
3771
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
3773
  "your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>)."
3774
  msgstr ""
3775
 
3776
+ #: lib/i18n-extra.php:178
3777
  #, php-format
3778
  msgid ""
3779
  "You can add/remove any country/territory from the two listboxes. For more "
3781
  "want to consult <a href=\"%s\">the MaxMind GeoIP online help</a>."
3782
  msgstr ""
3783
 
3784
+ #: lib/i18n-extra.php:179
3785
  msgid ""
3786
  "Whether geolocation should apply to the whole site or to specific URLs only "
3787
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
3788
  "it to apply to the whole site."
3789
  msgstr ""
3790
 
3791
+ #: lib/i18n-extra.php:180
3792
  msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
3793
  msgstr ""
3794
 
3795
+ #: lib/i18n-extra.php:181
3796
  msgid ""
3797
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
3798
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
3800
  "visitors location, simply use that variable."
3801
  msgstr ""
3802
 
3803
+ #: lib/i18n-extra.php:182
3804
  msgid ""
3805
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
3806
  "it with 2 hyphens (<code>--</code>)."
3807
  msgstr ""
3808
 
3809
+ #: lib/i18n-extra.php:183
3810
  msgid ""
3811
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
3812
  msgstr ""
3813
 
3814
+ #: lib/i18n-extra.php:184
3815
  msgid ""
3816
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
3817
  "http://www.maxmind.com"
3818
  msgstr ""
3819
 
3820
+ #: lib/i18n-extra.php:185
3821
  msgid "IP / URL / Bot Access Control"
3822
  msgstr ""
3823
 
3824
+ #: lib/i18n-extra.php:186
3825
  msgid ""
3826
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
3827
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
3828
  "NinjaFirewall."
3829
  msgstr ""
3830
 
3831
+ #: lib/i18n-extra.php:187
3832
  msgid "Full IP:"
3833
  msgstr ""
3834
 
3835
+ #: lib/i18n-extra.php:188
3836
  #, php-format
3837
  msgid "IP ranges using CIDR notation: %s or %s."
3838
  msgstr ""
3839
 
3840
+ #: lib/i18n-extra.php:189
3841
  msgid "Autonomous System number:"
3842
  msgstr ""
3843
 
3844
+ #: lib/i18n-extra.php:190
3845
  msgid ""
3846
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
3847
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
3854
  "turned off."
3855
  msgstr ""
3856
 
3857
+ #: lib/i18n-extra.php:191
3858
  msgid ""
3859
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
3860
  "immediately by clicking either the \"Save Access Control Directives\" or "
3861
  "\"Restore Default Values\" buttons at the bottom of this page."
3862
  msgstr ""
3863
 
3864
+ #: lib/i18n-extra.php:192
3865
  msgid ""
3866
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
3867
  "IPs even before your blog is loaded, we strongly recommend that you disable "
3871
  "during an attack."
3872
  msgstr ""
3873
 
3874
+ #: lib/i18n-extra.php:193
3875
  msgid ""
3876
  "You can permanently allow/block any access to one or more PHP scripts based "
3877
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
3878
  "enter either a full or partial path (case-sensitive)."
3879
  msgstr ""
3880
 
3881
+ #: lib/i18n-extra.php:194
3882
  msgid ""
3883
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
3884
  "script located inside a <code>/foo/</code> directory"
3885
  msgstr ""
3886
 
3887
+ #: lib/i18n-extra.php:195
3888
  msgid "etc"
3889
  msgstr ""
3890
 
3891
+ #: lib/i18n-extra.php:196
3892
  msgid ""
3893
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
3894
  "<code>/foo/</code> directory and its sub-directories."
3895
  msgstr ""
3896
 
3897
+ #: lib/i18n-extra.php:197
3898
  msgid ""
3899
  "Note that the \"Firewall Policies\" page already includes restrictions to "
3900
  "some WordPress directories."
3901
  msgstr ""
3902
 
3903
+ #: lib/i18n-extra.php:198
3904
  msgid ""
3905
  "You can block bots, scanners and various crawlers based on the "
3906
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
3907
  "partial name (case-insensitive)."
3908
  msgstr ""
3909
 
3910
+ #: lib/i18n-extra.php:199
3911
  msgid ""
3912
  "You can select to ignore or block some specific user input. It applies to "
3913
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
3915
  "\"]</code>:"
3916
  msgstr ""
3917
 
3918
+ #: lib/i18n-extra.php:200
3919
  msgid ""
3920
  "When an input is added to the \"Unfiltered input\" list, it will not be "
3921
  "filtered or sanitised. All other input present in the request will be "
3922
  "filtered."
3923
  msgstr ""
3924
 
3925
+ #: lib/i18n-extra.php:201
3926
  msgid ""
3927
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
3928
  "the request and close the connection if that input is found in the request."
3929
  msgstr ""
3930
 
3931
+ #: lib/i18n-extra.php:202
3932
  msgid "Log Event"
3933
  msgstr ""
3934
 
3935
+ #: lib/i18n-extra.php:203
3936
  msgid ""
3937
  "You can enable/disable firewall logging for each access control directive "
3938
  "separately."
3939
  msgstr ""
3940
 
3941
+ #: lib/i18n-extra.php:204
3942
  msgid "Web Filter"
3943
  msgstr ""
3944
 
3945
+ #: lib/i18n-extra.php:205
3946
  msgid ""
3947
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
3948
  "response body (i.e., the output of the HTML page right before it is sent to "
3952
  "hackers shell script, redirections and even errors (PHP/MySQL errors)."
3953
  msgstr ""
3954
 
3955
+ #: lib/i18n-extra.php:206
3956
  msgid ""
3957
  "In the case of a positive detection, NinjaFirewall will not block the "
3958
  "response body but will send you an alert by email."
3959
  msgstr ""
3960
 
3961
+ #: lib/i18n-extra.php:207
3962
  msgid "Search HTML page for the following keywords"
3963
  msgstr ""
3964
 
3965
+ #: lib/i18n-extra.php:208
3966
  msgid ""
3967
  "You can enter any keyword from 4 to 150 characters and select whether the "
3968
  "search will be case sensitive or not."
3969
  msgstr ""
3970
 
3971
+ #: lib/i18n-extra.php:209
3972
  msgid "Email Alerts"
3973
  msgstr ""
3974
 
3975
+ #: lib/i18n-extra.php:210
3976
  msgid ""
3977
  "You can use the notification throttling option to limit the frequency of "
3978
  "alerts sent to you (and written to the firewall log) and select whether you "
3981
  "in the \"Event Notifications\" menu."
3982
  msgstr ""
3983
 
3984
+ #: lib/i18n-extra.php:211
3985
  msgid ""
3986
  "Response body filtering can be resource-intensive. Try to limit the number "
3987
  "of keywords to what you really need (less than 10) and, if possible, prefer "
3988
  "case sensitive to case insensitive filtering."
3989
  msgstr ""
3990
 
3991
+ #: lib/i18n-extra.php:212
3992
  msgid ""
3993
  "NinjaFirewall can protect your blog against spam without user interaction (e."
3994
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
3997
  "generate your forms, they will not be protected against spam."
3998
  msgstr ""
3999
 
4000
+ #: lib/i18n-extra.php:213
4001
  msgid "Protection level:"
4002
  msgstr ""
4003
 
4004
+ #: lib/i18n-extra.php:214
4005
  msgid ""
4006
  "Select the level of protection. In most cases, <strong>Low</strong> should "
4007
  "be enough."
4008
  msgstr ""
4009
 
4010
+ #: lib/i18n-extra.php:215
4011
  msgid "Apply protection to:"
4012
  msgstr ""
4013
 
4014
+ #: lib/i18n-extra.php:216
4015
  msgid "Whether to protect comment and/or registration forms."
4016
  msgstr ""
4017
 
4018
+ #: lib/i18n-extra.php:217
4019
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4020
  msgstr ""
4021
 
4022
+ #: lib/i18n-extra.php:218
4023
  msgid ""
4024
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4025
  "otherwise the antispam could behave erratically after a while."
4026
  msgstr ""
4027
 
4028
+ #: lib/i18n-extra.php:219
4029
  msgid ""
4030
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4031
  msgstr ""
4032
 
4033
+ #: lib/i18n-extra.php:220
4034
  msgid ""
4035
  "The firewall log displays blocked and sanitised requests as well as some "
4036
  "useful information. It has 6 columns:"
4037
  msgstr ""
4038
 
4039
+ #: lib/i18n-extra.php:221
4040
  msgid ""
4041
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4042
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
4043
  "rule from the \"Firewall Policies\" or \"Access Control\" pages."
4044
  msgstr ""
4045
 
4046
+ #: lib/i18n-extra.php:222
4047
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4048
  msgstr ""
4049
 
4050
+ #: lib/i18n-extra.php:223
4051
  msgid "Enable firewall log"
4052
  msgstr ""
4053
 
4054
+ #: lib/i18n-extra.php:224
4055
  msgid "You can disable/enable the firewall log from this page."
4056
  msgstr ""
4057
 
4058
+ #: lib/i18n-extra.php:225
4059
  msgid ""
4060
  "Brute-force attacks will still be written to the firewall log, even if you "
4061
  "disable it."
4062
  msgstr ""
4063
 
4064
+ #: lib/i18n-extra.php:226
4065
  msgid "Auto-rotate log"
4066
  msgstr ""
4067
 
4068
+ #: lib/i18n-extra.php:227
4069
  msgid ""
4070
  "NinjaFirewall will rotate its log automatically on the very first day of "
4071
  "each month. If your site is very busy, you may want to allow it to rotate "
4072
  "the log when it reaches a certain size (MB) as well."
4073
  msgstr ""
4074
 
4075
+ #: lib/i18n-extra.php:228
4076
  msgid ""
4077
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
4078
  "megabytes."
4079
  msgstr ""
4080
 
4081
+ #: lib/i18n-extra.php:229
4082
  msgid ""
4083
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
4084
  msgstr ""
4085
 
4086
+ #: lib/i18n-extra.php:230
4087
  msgid "Syslog"
4088
  msgstr ""
4089
 
4090
+ #: lib/i18n-extra.php:231
4091
  msgid ""
4092
  "In addition to the firewall log, events can also be redirected to the syslog "
4093
  "server (<code>LOG_USER</code> facility)."
4094
  msgstr ""
4095
 
4096
+ #: lib/i18n-extra.php:232
4097
  msgid ""
4098
  "If you have a shared hosting account, keep this option disabled as you do "
4099
  "not have any access to the server logs."
4100
  msgstr ""
4101
 
4102
+ #: lib/i18n-extra.php:233
4103
  msgid "The logline uses the following format:"
4104
  msgstr ""
4105
 
4106
+ #: lib/i18n-extra.php:234
4107
  msgid ""
4108
  "BB: the level of severity as it appears in the firewall log. It can be "
4109
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
4110
  "CODE>, <CODE>UPLOAD</CODE> or <CODE>DEBUG_ON</CODE>."
4111
  msgstr ""
4112
 
4113
+ #: lib/i18n-extra.php:235
4114
  msgid "CCCCCC: the 7-digit incident ID."
4115
  msgstr ""
4116
 
4117
+ #: lib/i18n-extra.php:236
4118
  msgid "DD: the user IPv4 or IPv6 address."
4119
  msgstr ""
4120
 
4121
+ #: lib/i18n-extra.php:237
4122
  msgid "EE: the blog (sub-)domain name."
4123
  msgstr ""
4124
 
4125
+ #: lib/i18n-extra.php:238
4126
  #, php-format
4127
  msgid ""
4128
  "This logging option does not apply to the brute-force protection which can "
4130
  "the <a href=\"%s\">Login Protection</a> page."
4131
  msgstr ""
4132
 
4133
+ #: lib/i18n-extra.php:239
4134
  msgid ""
4135
  "Secret key: The secret key will be used to generate your public key. Enter "
4136
  "at least 30 ASCII characters, or use the one randomly created by "
4137
  "NinjaFirewall."
4138
  msgstr ""
4139
 
4140
+ #: lib/i18n-extra.php:240
4141
  msgid ""
4142
  "This server IP address: As an additional protection layer, you can restrict "
4143
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
4145
  "character instead."
4146
  msgstr ""
4147
 
4148
+ #: lib/i18n-extra.php:241
4149
  #, php-format
4150
  msgid ""
4151
  "Public key: This is the public key that you will need to upload to each "
4152
  "remote website (<a href=\"%s\">consult our blog</a> for more info about it)."
4153
  msgstr ""
4154
 
4155
+ #: lib/i18n-extra.php:242
4156
  msgid ""
4157
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4158
  "website(s) that you want to remotely access from the main server."
4159
  msgstr ""
4160
 
4161
+ #: lib/i18n-extra.php:243
4162
  msgid ""
4163
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
4164
  "the menu below if you want to disable it."
4165
  msgstr ""
4166
 
4167
+ #: lib/i18n-extra.php:244
4168
  msgid "Enable Web Filter"
4169
  msgstr ""
4170
 
4171
+ #: lib/i18n-extra.php:245
4172
  msgid "A full or partial string."
4173
  msgstr ""
4174
 
4175
+ #: lib/i18n-extra.php:246
4176
  msgid "From 4 to maximum 150 characters."
4177
  msgstr ""
4178
 
4179
+ #: lib/i18n-extra.php:247
4180
  msgid "Any character, except the vertical bar <code>|</code>"
4181
  msgstr ""
4182
 
4183
+ #: lib/i18n-extra.php:248
4184
  msgid "Keywords to search:"
4185
  msgstr ""
4186
 
4187
+ #: lib/i18n-extra.php:249
4188
  msgid "Case-sensitive search"
4189
  msgstr ""
4190
 
4191
+ #: lib/i18n-extra.php:250
4192
  #, php-format
4193
  msgid "Do not send me more than one email alert in a %s interval"
4194
  msgstr ""
4195
 
4196
+ #: lib/i18n-extra.php:251
4197
  msgid "5-minute"
4198
  msgstr ""
4199
 
4200
+ #: lib/i18n-extra.php:252
4201
  msgid "15-minute"
4202
  msgstr ""
4203
 
4204
+ #: lib/i18n-extra.php:253
4205
  msgid "30-minute"
4206
  msgstr ""
4207
 
4208
+ #: lib/i18n-extra.php:254
4209
  msgid "1-hour"
4210
  msgstr ""
4211
 
4212
+ #: lib/i18n-extra.php:255
4213
  msgid "3-hour"
4214
  msgstr ""
4215
 
4216
+ #: lib/i18n-extra.php:256
4217
  msgid "6-hour"
4218
  msgstr ""
4219
 
4220
+ #: lib/i18n-extra.php:257
4221
  msgid "12-hour"
4222
  msgstr ""
4223
 
4224
+ #: lib/i18n-extra.php:258
4225
  msgid "24-hour"
4226
  msgstr ""
4227
 
4228
+ #: lib/i18n-extra.php:259
4229
  msgid ""
4230
  "Clicking the \"Save Web Filter options\" button below will reset the current "
4231
  "timer."
4232
  msgstr ""
4233
 
4234
+ #: lib/i18n-extra.php:260
4235
  msgid "Attach the HTML page output to email alerts"
4236
  msgstr ""
4237
 
4238
+ #: lib/i18n-extra.php:261
4239
  msgid "Save Web Filter options"
4240
  msgstr ""
4241
 
4242
+ #: lib/i18n-extra.php:262
4243
  msgid "Help Desk:"
4244
  msgstr ""
4245
 
4246
+ #: lib/i18n-extra.php:263
4247
  msgid "The selected log was deleted"
4248
  msgstr ""
4249
 
4250
+ #: lib/i18n-extra.php:264
4251
  msgid "Export"
4252
  msgstr ""
4253
 
4254
+ #: lib/i18n-extra.php:265
4255
  msgid "Delete"
4256
  msgstr ""
4257
 
4258
+ #: lib/i18n-extra.php:266
4259
  msgid "Delete log?"
4260
  msgstr ""
4261
 
4262
+ #: lib/i18n-extra.php:267
4263
  msgid "Today"
4264
  msgstr ""
4265
 
4266
+ #: lib/i18n-extra.php:268
4267
  msgid "Upload"
4268
  msgstr ""
4269
 
4270
+ #: lib/i18n-extra.php:269
4271
  msgid "Info"
4272
  msgstr ""
4273
 
4274
+ #: lib/i18n-extra.php:270
4275
  msgid "Debug"
4276
  msgstr ""
4277
 
4278
+ #: lib/i18n-extra.php:271
4279
  msgid "IP address:"
4280
  msgstr ""
4281
 
4282
+ #: lib/i18n-extra.php:272
4283
  msgid "e.g., 1.2.3.4"
4284
  msgstr ""
4285
 
4286
+ #: lib/i18n-extra.php:273
4287
  msgid "Add IP to blacklist"
4288
  msgstr ""
4289
 
4290
+ #: lib/i18n-extra.php:274
4291
  msgid "Add IP to whitelist"
4292
  msgstr ""
4293
 
4294
+ #: lib/i18n-extra.php:275
4295
  msgid "Add"
4296
  msgstr ""
4297
 
4298
+ #: lib/i18n-extra.php:276
4299
  msgid "The address wad added to your IP Access Control list."
4300
  msgstr ""
4301
 
4302
+ #: lib/i18n-extra.php:277
4303
  #, php-format
4304
  msgid "1st day of the month, or if bigger than %s MB"
4305
  msgstr ""
4306
 
4307
+ #: lib/i18n-extra.php:278
4308
  msgid "1st day of the month, regardless of its size"
4309
  msgstr ""
4310
 
4311
+ #: lib/i18n-extra.php:279
4312
  msgid "Show the most recent"
4313
  msgstr ""
4314
 
4315
+ #: lib/i18n-extra.php:280
4316
  msgid "lines"
4317
  msgstr ""
4318
 
4319
+ #: lib/i18n-extra.php:281
4320
  msgid "Write events to the Syslog server too"
4321
  msgstr ""
4322
 
4323
+ #: lib/i18n-extra.php:282
4324
  msgid "Your server configuration is not compatible with this option."
4325
  msgstr ""
4326
 
4327
+ #: lib/i18n-extra.php:283
4328
  msgid "See contextual help before enabling this option."
4329
  msgstr ""
4330
 
4331
+ #: lib/i18n-extra.php:284
4332
  msgid ""
4333
  "The remote server rejected your request. Make sure that you uploaded the "
4334
  "correct public key."
4335
  msgstr ""
4336
 
4337
+ #: lib/i18n-extra.php:285
4338
  #, php-format
4339
  msgid "The remote server returned the following HTTP error: %s"
4340
  msgstr ""
4341
 
4342
+ #: lib/i18n-extra.php:286
4343
  msgid "The requested log does not exist on the remote website."
4344
  msgstr ""
4345
 
4346
+ #: lib/i18n-extra.php:287
4347
  msgid "The remote website did not return the expected response."
4348
  msgstr ""
4349
 
4350
+ #: lib/i18n-extra.php:288
4351
  msgid "Your server does not seem to be compatible with this option."
4352
  msgstr ""
4353
 
4354
+ #: lib/i18n-extra.php:289
4355
  msgid "Load language files from the WordPress repo"
4356
  msgstr ""
4357
 
4358
+ #: lib/i18n-extra.php:290
4359
  #, php-format
4360
  msgid ""
4361
  "If available, NinjaFirewall will download the language files from <a "
4362
  "%s>translate.wordpress.org</a>."
4363
  msgstr ""
4364
 
4365
+ #: lib/i18n-extra.php:291
4366
  msgid "Error: you do not have any license."
4367
  msgstr ""
4368
 
4369
+ #: lib/i18n-extra.php:292
4370
  msgid "You have a valid license."
4371
  msgstr ""
4372
 
4373
+ #: lib/i18n-extra.php:293
4374
  msgid ""
4375
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
4376
  "try again in a few minutes"
4377
  msgstr ""
4378
 
4379
+ #: lib/i18n-extra.php:294
4380
  msgid ""
4381
  "An error occured while connecting to NinjaFirewall servers. Please try again "
4382
  "in a few minutes"
4383
  msgstr ""
4384
 
4385
+ #: lib/i18n-extra.php:295
4386
  msgid "Enter a valid license to save!"
4387
  msgstr ""
4388
 
4389
+ #: lib/i18n-extra.php:296
4390
  msgid "This is already your current license!"
4391
  msgstr ""
4392
 
4393
+ #: lib/i18n-extra.php:297
4394
  msgid "Your new license has been accepted and saved."
4395
  msgstr ""
4396
 
4397
+ #: lib/i18n-extra.php:298
4398
  msgid "This license is not valid"
4399
  msgstr ""
4400
 
4401
+ #: lib/i18n-extra.php:299
4402
  msgid "WP+ Edition License"
4403
  msgstr ""
4404
 
4405
+ #: lib/i18n-extra.php:300
4406
  msgid "License Number"
4407
  msgstr ""
4408
 
4409
+ #: lib/i18n-extra.php:301
4410
  msgid "No license found"
4411
  msgstr ""
4412
 
4413
+ #: lib/i18n-extra.php:302
4414
  msgid "Click to check your license validity"
4415
  msgstr ""
4416
 
4417
+ #: lib/i18n-extra.php:303
4418
  msgid "Expiration date"
4419
  msgstr ""
4420
 
4421
+ #: lib/i18n-extra.php:304
4422
  msgid "Unknown expiration date"
4423
  msgstr ""
4424
 
4425
+ #: lib/i18n-extra.php:305
4426
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
4427
  msgstr ""
4428
 
4429
+ #: lib/i18n-extra.php:306
4430
  msgid "Your license will expire soon!"
4431
  msgstr ""
4432
 
4433
+ #: lib/i18n-extra.php:307
4434
  msgid "Your license has expired."
4435
  msgstr ""
4436
 
4437
+ #: lib/i18n-extra.php:308
4438
  msgid "License renewal"
4439
  msgstr ""
4440
 
4441
+ #: lib/i18n-extra.php:309
4442
  msgid "Click here to get a license!"
4443
  msgstr ""
4444
 
4445
+ #: lib/i18n-extra.php:310
4446
  msgid "Enter your new license and click on the save button"
4447
  msgstr ""
4448
 
4449
+ #: lib/i18n-extra.php:311
4450
  msgid "Save New License"
4451
  msgstr ""
4452
 
4453
+ #: lib/i18n-extra.php:312
4454
  msgid "Allow, but block dangerous files"
4455
  msgstr ""
4456
 
4457
+ #: lib/i18n-extra.php:313
4458
  msgid "See contextual help for the list of files."
4459
  msgstr ""
4460
 
4461
+ #: lib/i18n-extra.php:314
4462
  msgid "Apply to ZIP archives file contents"
4463
  msgstr ""
4464
 
4465
+ #: lib/i18n-extra.php:315
4466
  msgid ""
4467
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
4468
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
4469
  "Control whitelist."
4470
  msgstr ""
4471
 
4472
+ #: lib/i18n-extra.php:316
4473
  #, php-format
4474
  msgid ""
4475
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
4482
  "Error: Your .htaccess file is not writable, please change its permissions: %s"
4483
  msgstr ""
4484
 
4485
+ #: lib/install.php:110 ninjafirewall.php:651 ninjafirewall.php:655
4486
  #, php-format
4487
  msgid "Error: wrong parameter value (%s)."
4488
  msgstr ""
4724
  msgid "Error: unable to write to the %s configuration file"
4725
  msgstr ""
4726
 
4727
+ #: lib/logs.php:36 ninjafirewall.php:925
4728
  msgid "Logs"
4729
  msgstr ""
4730
 
4778
  msgid "Viewing:"
4779
  msgstr ""
4780
 
4781
+ #: lib/logs_firewall_log.php:142 lib/logs_firewall_log.php:309
4782
  msgid "The selected log is empty."
4783
  msgstr ""
4784
 
4824
  msgid "Delete Public Key"
4825
  msgstr ""
4826
 
4827
+ #: lib/logs_firewall_log.php:288
4828
  msgid "The requested log does not exist."
4829
  msgstr ""
4830
 
4831
+ #: lib/logs_firewall_log.php:295
4832
  msgid "Unable to open the log for read operation."
4833
  msgstr ""
4834
 
4947
  msgid "Error: please enter the custom log format."
4948
  msgstr ""
4949
 
4950
+ #: lib/monitoring.php:43 ninjafirewall.php:899
4951
  msgid "Monitoring"
4952
  msgstr ""
4953
 
5323
  msgid "Save File Guard options"
5324
  msgstr ""
5325
 
5326
+ #: lib/network.php:24 ninjafirewall.php:1186 ninjafirewall.php:1190
5327
  #, php-format
5328
  msgid "You are not allowed to perform this task (%s)."
5329
  msgstr ""
5353
  msgstr ""
5354
 
5355
  #: lib/security_rules.php:44 lib/security_rules_update.php:565
5356
+ #: ninjafirewall.php:929
5357
  msgid "Security Rules"
5358
  msgstr ""
5359
 
5615
 
5616
  #: lib/thickbox.php:79
5617
  msgid ""
5618
+ "Warning, it seems that you are running WordPress in a Docker image: "
5619
+ "activating the Full WAF mode may crash your site. Make sure to read the "
5620
+ "following recommendations:"
5621
+ msgstr ""
5622
+
5623
+ #: lib/thickbox.php:79
5624
+ msgid "WordPress and Docker image"
5625
+ msgstr ""
5626
+
5627
+ #: lib/thickbox.php:85
5628
+ msgid ""
5629
  "In Full WAF mode, all scripts located inside the blog installation "
5630
  "directories and sub-directories are protected by NinjaFirewall. It gives you "
5631
  "the highest possible level of protection: security without compromise."
5632
  msgstr ""
5633
 
5634
+ #: lib/thickbox.php:87
5635
  #, php-format
5636
  msgid ""
5637
  "It works on most websites right out of the box, or may require %ssome very "
5639
  "plans restrictions, it may simply not work at all."
5640
  msgstr ""
5641
 
5642
+ #: lib/thickbox.php:89
5643
  msgid ""
5644
  "If this happened to you, don't worry: you could still run it in WordPress "
5645
  "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
5646
  "level of protection and performance much higher than other security plugins."
5647
  msgstr ""
5648
 
5649
+ #: lib/thickbox.php:163
5650
  msgid "Select your HTTP server and your PHP server API"
5651
  msgstr ""
5652
 
5653
+ #: lib/thickbox.php:174
5654
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
5655
  msgstr ""
5656
 
5657
+ #: lib/thickbox.php:176
5658
  msgid "View PHPINFO"
5659
  msgstr ""
5660
 
5661
+ #: lib/thickbox.php:208
5662
  msgid "Select the PHP initialization file supported by your server"
5663
  msgstr ""
5664
 
5665
+ #: lib/thickbox.php:219
5666
  msgid "Folders protected by NinjaFirewall"
5667
  msgstr ""
5668
 
5669
+ #: lib/thickbox.php:221 lib/thickbox.php:368
5670
  msgid "WordPress root directory:"
5671
  msgstr ""
5672
 
5673
+ #: lib/thickbox.php:226 lib/thickbox.php:373
5674
  msgid ""
5675
  "The following folders will be protected by NinjaFirewall. If you want to "
5676
  "exclude some of them, uncheck them in the list below:"
5677
  msgstr ""
5678
 
5679
+ #: lib/thickbox.php:232
5680
  msgid ""
5681
  "After setting up the Full WAF mode, you could come back to this page to re-"
5682
  "configure it whenever you want."
5683
  msgstr ""
5684
 
5685
+ #: lib/thickbox.php:240
5686
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
5687
  msgstr ""
5688
 
5689
+ #: lib/thickbox.php:242
5690
  msgid "I want to make the changes myself."
5691
  msgstr ""
5692
 
5693
+ #: lib/thickbox.php:244
5694
  msgid ""
5695
  "Please make the changes below, then click on the \"Finish Installation\" "
5696
  "button."
5697
  msgstr ""
5698
 
5699
+ #: lib/thickbox.php:251
5700
  #, php-format
5701
  msgid ""
5702
  "The %s file must be created, and the following lines of code added to it:"
5703
  msgstr ""
5704
 
5705
+ #: lib/thickbox.php:252
5706
  #, php-format
5707
  msgid "The following lines of code must be added to your existing %s file:"
5708
  msgstr ""
5709
 
5710
+ #: lib/thickbox.php:320
5711
  msgid ""
5712
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
5713
  "select your domain, add the following instructions to the \"php.ini Override"
5714
  "\" section in the \"General\" tab, and restart Openlitespeed:"
5715
  msgstr ""
5716
 
5717
+ #: lib/thickbox.php:327
5718
  msgid ""
5719
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
5720
  "to remove these instructions from your Openlitespeed admin dashboard "
5722
  "could not do it for you."
5723
  msgstr ""
5724
 
5725
+ #: lib/thickbox.php:343
5726
  msgid "Enable the sandbox."
5727
  msgstr ""
5728
 
5729
+ #: lib/thickbox.php:343
5730
  msgid ""
5731
  "If there were a problem during the installation, NinjaFirewall would undo "
5732
  "those changes automatically for you."
5733
  msgstr ""
5734
 
5735
+ #: lib/thickbox.php:344
5736
  msgid "Finish Installation"
5737
  msgstr ""
5738
 
5739
+ #: lib/thickbox.php:362
5740
  msgid "Configuration"
5741
  msgstr ""
5742
 
5743
+ #: lib/thickbox.php:366
5744
  msgid "Full WAF mode"
5745
  msgstr ""
5746
 
5747
+ #: lib/thickbox.php:380
5748
  msgid "Save Changes"
5749
  msgstr ""
5750
 
5751
+ #: lib/thickbox.php:391
5752
  msgid "WordPress WAF mode"
5753
  msgstr ""
5754
 
5755
+ #: lib/thickbox.php:398
5756
  msgid ""
5757
  "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
5758
  "admin dashboard, click on \"Virtual Host\", select your domain and remove "
5760
  "the \"General\" tab, and restart Openlitespeed."
5761
  msgstr ""
5762
 
5763
+ #: lib/thickbox.php:399 lib/thickbox.php:406
5764
  msgid "Downgrade to WordPress WAF mode"
5765
  msgstr ""
5766
 
5767
+ #: lib/thickbox.php:403
5768
  msgid "If you want to downgrade to WordPress WAF mode, click the button below."
5769
  msgstr ""
5770
 
5771
+ #: lib/thickbox.php:408
5772
  msgid "You may have to wait five minutes for the changes to take effect."
5773
  msgstr ""
5774
 
5775
+ #: lib/thickbox.php:415
5776
  msgid "Cancel and Close"
5777
  msgstr ""
5778
 
5779
+ #: lib/utils.php:188 lib/utils.php:196 lib/utils.php:294
5780
  msgid "N/A"
5781
  msgstr ""
5782
 
5790
  msgid "Attempt to edit a published %s (ID: %s)"
5791
  msgstr ""
5792
 
5793
+ #: lib/utils.php:212 lib/utils.php:286
5794
  msgid "Unauthenticated user"
5795
  msgstr ""
5796
 
5804
  "doesn't have the right capabilities:"
5805
  msgstr ""
5806
 
5807
+ #: lib/utils.php:226 lib/utils.php:306 lib/utils.php:424 lib/utils.php:1255
5808
  msgid "Username:"
5809
  msgstr ""
5810
 
5812
  msgid "Action:"
5813
  msgstr ""
5814
 
5815
+ #: lib/utils.php:242 lib/utils.php:321 lib/utils.php:437 lib/utils.php:1271
5816
+ #: lib/utils.php:1518
5817
  msgid "A PHP backtrace has been attached to this message for your convenience."
5818
  msgstr ""
5819
 
5820
+ #: lib/utils.php:244 lib/utils.php:323 lib/utils.php:1273 lib/utils.php:1528
5821
  msgid ""
5822
  "This protection (and notification) can be turned off from NinjaFirewall "
5823
  "\"Firewall Policies\" page."
5824
  msgstr ""
5825
 
5826
+ #: lib/utils.php:258 lib/utils.php:259 lib/utils.php:337 lib/utils.php:338
5827
+ #: lib/utils.php:453 lib/utils.php:454 lib/utils.php:1288 lib/utils.php:1289
5828
  msgid "You are not allowed to perform this task."
5829
  msgstr ""
5830
 
5831
+ #: lib/utils.php:297
5832
  msgid "Blocked post/page deletion attempt"
5833
  msgstr ""
5834
 
5835
+ #: lib/utils.php:304
5836
  msgid ""
5837
  "NinjaFirewall has blocked an attempt to delete a post by a user who doesn't "
5838
  "have the right capabilities:"
5839
  msgstr ""
5840
 
5841
+ #: lib/utils.php:414
5842
  msgid "Blocked user account creation"
5843
  msgstr ""
5844
 
5845
+ #: lib/utils.php:421
5846
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
5847
  msgstr ""
5848
 
5849
+ #: lib/utils.php:518
5850
  #, php-format
5851
  msgid "Backup file is corrupted, deleting it (%s)"
5852
  msgstr ""
5853
 
5854
+ #: lib/utils.php:526
5855
  #, php-format
5856
  msgid ""
5857
  "NinjaFirewall's options are corrupted, restoring them from last known good "
5858
  "backup file (%s)"
5859
  msgstr ""
5860
 
5861
+ #: lib/utils.php:532
5862
  msgid ""
5863
  "NinjaFirewall's options are corrupted, restoring their default values (no "
5864
  "valid backup found)"
5865
  msgstr ""
5866
 
5867
+ #: lib/utils.php:758
5868
  msgid ""
5869
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
5870
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
5871
  "HTTP status code). You can safely ignore it."
5872
  msgstr ""
5873
 
5874
+ #: lib/utils.php:781 lib/utils.php:785
5875
  msgid "NinjaFirewall error"
5876
  msgstr ""
5877
 
5878
+ #: lib/utils.php:782
5879
  #, php-format
5880
  msgid ""
5881
  "%s directory cannot be created. Please review your installation and ensure "
5882
  "that %s is writable."
5883
  msgstr ""
5884
 
5885
+ #: lib/utils.php:786
5886
  #, php-format
5887
  msgid ""
5888
  "%s directory is read-only. Please review your installation and ensure that "
5889
  "%s is writable."
5890
  msgstr ""
5891
 
5892
+ #: lib/utils.php:801
5893
  msgid "unknown error"
5894
  msgstr ""
5895
 
5896
+ #: lib/utils.php:803
5897
  msgid "NinjaFirewall fatal error:"
5898
  msgstr ""
5899
 
5900
+ #: lib/utils.php:804
5901
  msgid "Review your installation, your site is not protected."
5902
  msgstr ""
5903
 
5904
+ #: lib/utils.php:825
5905
  msgid "Alert: WordPress console login"
5906
  msgstr ""
5907
 
5908
+ #: lib/utils.php:831
5909
  msgid "Someone just logged in to your WordPress admin console:"
5910
  msgstr ""
5911
 
5912
+ #: lib/utils.php:949 lib/utils.php:976
5913
  msgid "Forbidden access"
5914
  msgstr ""
5915
 
5916
+ #: lib/utils.php:995
5917
  #, php-format
5918
  msgid ""
5919
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
5920
  "href=\"%s\">Lost your password</a>?"
5921
  msgstr ""
5922
 
5923
+ #: lib/utils.php:1073
5924
  msgid "[NinjaFirewall] Alert: Database changes detected"
5925
  msgstr ""
5926
 
5927
+ #: lib/utils.php:1074
5928
  msgid ""
5929
  "NinjaFirewall has detected that one or more administrator accounts were "
5930
  "modified in the database:"
5931
  msgstr ""
5932
 
5933
+ #: lib/utils.php:1079
5934
  #, php-format
5935
  msgid "Total administrators : %s"
5936
  msgstr ""
5937
 
5938
+ #: lib/utils.php:1088
5939
  msgid ""
5940
  "If you cannot see any modifications in the above fields, it is possible that "
5941
  "the administrator password was changed."
5942
  msgstr ""
5943
 
5944
+ #: lib/utils.php:1241
5945
  msgid "Blocked privilege escalation attempt"
5946
  msgstr ""
5947
 
5948
+ #: lib/utils.php:1249
5949
  msgid ""
5950
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
5951
  "who does not have administrative privileges:"
5952
  msgstr ""
5953
 
5954
+ #: lib/utils.php:1300
5955
  msgid ""
5956
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
5957
  "whitelisted."
5958
  msgstr ""
5959
 
5960
+ #: lib/utils.php:1315
5961
  #, php-format
5962
  msgid ""
5963
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
5966
  "rate it. Thank you!"
5967
  msgstr ""
5968
 
5969
+ #: lib/utils.php:1490
5970
  msgid ""
5971
  "The attempt was blocked and the option was reversed to its original value."
5972
  msgstr ""
5973
 
5974
+ #: lib/utils.php:1495
5975
  msgid "Attempt to modify WordPress settings"
5976
  msgstr ""
5977
 
5978
+ #: lib/utils.php:1496
5979
  msgid ""
5980
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
5981
  "settings by a user that does not have administrative privileges:"
5982
  msgstr ""
5983
 
5984
+ #: lib/utils.php:1497 lib/utils.php:1506
5985
  #, php-format
5986
  msgid "Option: %s"
5987
  msgstr ""
5988
 
5989
+ #: lib/utils.php:1498
5990
  #, php-format
5991
  msgid "Original value: %s"
5992
  msgstr ""
5993
 
5994
+ #: lib/utils.php:1499
5995
  #, php-format
5996
  msgid "Modified value: %s"
5997
  msgstr ""
5998
 
5999
+ #: lib/utils.php:1500 lib/utils.php:1508
6000
  #, php-format
6001
  msgid "Action taken: %s"
6002
  msgstr ""
6003
 
6004
+ #: lib/utils.php:1504
6005
  msgid "Code injection attempt in WordPress options table"
6006
  msgstr ""
6007
 
6008
+ #: lib/utils.php:1505
6009
  msgid ""
6010
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
6011
  "table by a user that does not have administrative privileges:"
6012
  msgstr ""
6013
 
6014
+ #: lib/utils.php:1507
6015
  #, php-format
6016
  msgid "Code: %s"
6017
  msgstr ""
6018
 
6019
+ #: lib/utils.php:1607
6020
  msgid "Important: NinjaFirewall has detected that this is a security update."
6021
  msgstr ""
6022
 
6023
+ #: lib/utils.php:1610
6024
  msgid "More info about this warning."
6025
  msgstr ""
6026
 
6027
+ #: lib/utils.php:1633
6028
  #, php-format
6029
  msgid "Cannot send notification, no valid email found (%s)"
6030
  msgstr ""
6031
 
6032
+ #: lib/utils.php:1658
6033
  #, php-format
6034
  msgid ""
6035
  "If you don't have access to that site any longer, you can remove your email "
6036
  "by clicking the following link (valid for 12 hours): %s"
6037
  msgstr ""
6038
 
6039
+ #: lib/utils.php:1684
6040
  #, php-format
6041
  msgid "Error, cannot create the %s folder."
6042
  msgstr ""
6043
 
6044
+ #: lib/utils.php:1685 lib/utils.php:1694 lib/utils.php:1703
6045
  msgid "Check your server permissions and try again."
6046
  msgstr ""
6047
 
6048
+ #: lib/utils.php:1693
6049
  #, php-format
6050
  msgid "Error, the %s folder is not writable."
6051
  msgstr ""
6052
 
6053
+ #: lib/utils.php:1702
6054
  #, php-format
6055
  msgid "Error, cannot write %s."
6056
  msgstr ""
6079
  msgid "View firewall log"
6080
  msgstr ""
6081
 
6082
+ #: lib/widget.php:115
6083
+ msgid "Latest News from NinTechNet"
6084
  msgstr ""
6085
 
6086
+ #: lib/widget.php:119
6087
  msgid "M jS, Y"
6088
  msgstr ""
6089
 
6090
+ #: lib/widget.php:130
6091
  msgid "More Security News"
6092
  msgstr ""
6093
 
6094
+ #: lib/widget.php:130
6095
  msgid "(opens in a new tab)"
6096
  msgstr ""
6097
 
6098
+ #: lib/widget.php:130
6099
  msgid "NinjaFirewall's Home"
6100
  msgstr ""
6101
 
6592
  msgid "Error: The HTTP server returned the following error code:"
6593
  msgstr ""
6594
 
6595
+ #: ninjafirewall.php:636 ninjafirewall.php:756 ninjafirewall.php:825
6596
  msgid "Error: Security nonces do not match. Reload the page and try again."
6597
  msgstr ""
6598
 
6599
+ #: ninjafirewall.php:642
6600
  msgid "Error: NinjaFirewall is disabled"
6601
  msgstr ""
6602
 
6603
+ #: ninjafirewall.php:647 ninjafirewall.php:761 ninjafirewall.php:791
6604
  #, php-format
6605
  msgid "Error: missing parameter (%s)."
6606
  msgstr ""
6607
 
6608
+ #: ninjafirewall.php:887
6609
  msgid "NinjaFirewall: Dashboard"
6610
  msgstr ""
6611
 
6612
+ #: ninjafirewall.php:891
6613
  msgid "NinjaFirewall: Firewall Options"
6614
  msgstr ""
6615
 
6616
+ #: ninjafirewall.php:895
6617
  msgid "NinjaFirewall: Firewall Policies"
6618
  msgstr ""
6619
 
6620
+ #: ninjafirewall.php:899
6621
  msgid "NinjaFirewall: Monitoring"
6622
  msgstr ""
6623
 
6624
+ #: ninjafirewall.php:909
6625
  msgid "NinjaFirewall: Anti-Malware"
6626
  msgstr ""
6627
 
6628
+ #: ninjafirewall.php:913
6629
  msgid "NinjaFirewall: Network"
6630
  msgstr ""
6631
 
6632
+ #: ninjafirewall.php:917
6633
  msgid "NinjaFirewall: Event Notifications"
6634
  msgstr ""
6635
 
6636
+ #: ninjafirewall.php:921
6637
  msgid "NinjaFirewall: Log-in Protection"
6638
  msgstr ""
6639
 
6640
+ #: ninjafirewall.php:925
6641
  msgid "NinjaFirewall: Logs"
6642
  msgstr ""
6643
 
6644
+ #: ninjafirewall.php:929
6645
  msgid "NinjaFirewall: Security Rules"
6646
  msgstr ""
6647
 
6648
+ #: ninjafirewall.php:973
6649
  msgid "NinjaFirewall Settings"
6650
  msgstr ""
6651
 
6652
+ #: ninjafirewall.php:981
6653
  msgid "NinjaFirewall is enabled"
6654
  msgstr ""
6655
 
6656
+ #: ninjafirewall.php:1121
6657
  msgid "Access Restricted"
6658
  msgstr ""
6659
 
6660
+ #: ninjafirewall.php:1127
6661
  msgid "Settings"
6662
  msgstr ""
6663
 
6664
+ #: ninjafirewall.php:1128
6665
  msgid "Upgrade to Premium"
6666
  msgstr ""
6667
 
6668
+ #: ninjafirewall.php:1129
6669
  msgid "Rate it!"
6670
  msgstr ""
lib/dashboard_about.php CHANGED
@@ -30,7 +30,6 @@ if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
30
  <li><?php esc_html_e('Stay informed about the latest vulnerabilities in WordPress plugins and themes:', 'ninjafirewall') ?> <a href="https://twitter.com/nintechnet">https://twitter.com/nintechnet</a></li>
31
  <li><a href="https://blog.nintechnet.com/ninjafirewall-general-data-protection-regulation-compliance/"><?php esc_html_e('GDPR Compliance', 'ninjafirewall') ?></a></li>
32
  <li><a href="https://wordpress.org/support/view/plugin-reviews/ninjafirewall?rate=5#postform"><?php esc_html_e('Rate it on WordPress.org!', 'ninjafirewall') ?></a> <img style="vertical-align:middle" src="<?php echo plugins_url() ?>/ninjafirewall/images/rate.png" /></li>
33
- <li><a href="https://nintechnet.com/referral/"><?php esc_html_e('NinjaFirewall Referral Program', 'ninjafirewall') ?></a></li>
34
  </ul>
35
  </font>
36
  </div>
30
  <li><?php esc_html_e('Stay informed about the latest vulnerabilities in WordPress plugins and themes:', 'ninjafirewall') ?> <a href="https://twitter.com/nintechnet">https://twitter.com/nintechnet</a></li>
31
  <li><a href="https://blog.nintechnet.com/ninjafirewall-general-data-protection-regulation-compliance/"><?php esc_html_e('GDPR Compliance', 'ninjafirewall') ?></a></li>
32
  <li><a href="https://wordpress.org/support/view/plugin-reviews/ninjafirewall?rate=5#postform"><?php esc_html_e('Rate it on WordPress.org!', 'ninjafirewall') ?></a> <img style="vertical-align:middle" src="<?php echo plugins_url() ?>/ninjafirewall/images/rate.png" /></li>
 
33
  </ul>
34
  </font>
35
  </div>
lib/event_notifications.php CHANGED
@@ -413,9 +413,17 @@ function nf_daily_report() {
413
  }
414
 
415
  // Make sure we didn't send it already (if WP-Cron is ran twice by mistake)
416
- $nf_transient = get_transient( 'nfw_dailyreport' );
 
 
 
 
417
  if ( $nf_transient == false || $nf_transient < time() ) {
418
- set_transient( 'nfw_dailyreport', time() + 300, 300 );
 
 
 
 
419
 
420
  $logstats = array();
421
  $logstats = nf_daily_report_log();
@@ -434,9 +442,9 @@ function nf_daily_report_log() {
434
  } else {
435
  $cur_month_log = date('Y-m');
436
  }
437
- $previous_day = strtotime( date('Y-m-d 00:00:01', strtotime("-1 day")) );
438
- $log_file = NFW_LOG_DIR . '/nfwlog/firewall_' . $cur_month_log;
439
- $logstats = array( 0 => 0, 1 => 0, 2 => 0, 3 => 0, 5 => 0);
440
 
441
  $glob = glob($log_file . "*.php");
442
  if ( is_array($glob)) {
413
  }
414
 
415
  // Make sure we didn't send it already (if WP-Cron is ran twice by mistake)
416
+ if ( is_multisite() ) {
417
+ $nf_transient = get_site_transient( 'nfw_dailyreport' );
418
+ } else {
419
+ $nf_transient = get_transient( 'nfw_dailyreport' );
420
+ }
421
  if ( $nf_transient == false || $nf_transient < time() ) {
422
+ if ( is_multisite() ) {
423
+ set_site_transient( 'nfw_dailyreport', time() + 3600, 3600 );
424
+ } else {
425
+ set_transient( 'nfw_dailyreport', time() + 3600, 3600 );
426
+ }
427
 
428
  $logstats = array();
429
  $logstats = nf_daily_report_log();
442
  } else {
443
  $cur_month_log = date('Y-m');
444
  }
445
+ $previous_day = strtotime( date('Y-m-d 00:00:01', strtotime("-1 day")) );
446
+ $log_file = NFW_LOG_DIR . '/nfwlog/firewall_' . $cur_month_log;
447
+ $logstats = array( 0 => 0, 1 => 0, 2 => 0, 3 => 0, 5 => 0);
448
 
449
  $glob = glob($log_file . "*.php");
450
  if ( is_array($glob)) {
lib/events.php CHANGED
@@ -23,12 +23,12 @@ function nfw_sys_events() {
23
 
24
  $nfw_options = nfw_get_option( 'nfw_options' );
25
 
26
- $script = $_SERVER['SCRIPT_NAME'];
27
- $label_name = __('Name:', 'ninjafirewall');
28
- $label_plugin = __('Plugin', 'ninjafirewall');
29
- $label_theme = __('Theme', 'ninjafirewall');
30
- $label_version = __('Version:', 'ninjafirewall');
31
- $alert_action = 0;
32
 
33
  // themes.php
34
  if ( strpos( $script, '/themes.php' ) !== FALSE ) {
@@ -36,14 +36,14 @@ function nfw_sys_events() {
36
  if ( current_user_can( 'switch_themes' ) && isset( $_GET['action'] ) ) {
37
 
38
  if ( $_GET['action'] == 'activate' && ! empty( $nfw_options['a_23'] ) ) {
39
- $theme = wp_get_theme( $_GET['stylesheet'] );
40
- $alert_action = sprintf( '%s %s', $label_theme, __('activated', 'ninjafirewall') );
41
- $alert_item = sprintf( '%s %s', $label_name, $theme );
42
 
43
  } elseif ( $_GET['action'] == 'delete' && current_user_can( 'delete_themes' ) && ! empty( $nfw_options['a_24'] ) ) {
44
- $theme = wp_get_theme( $_GET['stylesheet'] );
45
- $alert_action = sprintf( '%s %s', $label_theme, __('deleted', 'ninjafirewall') );
46
- $alert_item = sprintf( '%s %s', $label_name, $theme );
47
  }
48
  }
49
 
@@ -70,38 +70,38 @@ function nfw_sys_events() {
70
  }
71
 
72
  if ( $_REQUEST['action'] == 'activate' && ! empty( $nfw_options['a_13'] ) ) {
73
- $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
74
- $alert_item = sprintf( '%s %s', $label_name, $plugin );
75
 
76
  } elseif ( $_REQUEST['action'] == 'activate-selected' && ! empty( $nfw_options['a_13'] ) ) {
77
- $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
78
- $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
79
 
80
  } elseif ( $_REQUEST['action'] == 'update-selected' && ! empty( $nfw_options['a_14'] ) ) {
81
- $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
82
- $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
83
 
84
  } elseif ( $_REQUEST['action'] == 'deactivate' && current_user_can( 'deactivate_plugin' ) && ! empty( $nfw_options['a_15'] ) ) {
85
- $alert_action = sprintf( '%s %s', $label_plugin, __('deactivated', 'ninjafirewall') );
86
- $alert_item = sprintf( '%s %s', $label_name, $plugin );
87
 
88
  } elseif ( $_REQUEST['action'] == 'deactivate-selected' && current_user_can( 'deactivate_plugin' ) && ! empty( $nfw_options['a_15'] ) ) {
89
- $alert_action = sprintf( '%s %s', $label_plugin, __('deactivated', 'ninjafirewall') );
90
- $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
91
 
92
  } elseif ( $_REQUEST['action'] == 'delete-selected' && current_user_can( 'delete_plugins' ) && ! empty( $nfw_options['a_16'] ) ) {
93
- $alert_action = sprintf( '%s %s', $label_plugin, __('deleted', 'ninjafirewall') );
94
- $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
95
  }
96
 
97
  // update-core.php (only used for WP updates)
98
  } elseif ( strpos($_SERVER['SCRIPT_NAME'], '/update-core.php' ) !== FALSE ) {
99
 
100
- if (! isset( $_GET['action'] ) ) { return; }
101
 
102
  if ( $_GET['action'] == 'do-core-upgrade' && current_user_can( 'update_core' ) && ! empty( $nfw_options['a_31'] ) ) {
103
- $alert_action = sprintf( '%s %s', 'WordPress', __('updated', 'ninjafirewall') );
104
- $alert_item = sprintf( '%s %s', $label_version, @$_POST['version'] );
105
  }
106
 
107
  // update.php
@@ -111,49 +111,51 @@ function nfw_sys_events() {
111
 
112
  if ( $_GET['action'] == 'update-selected' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
113
  if ( isset( $_GET['plugins'] ) ) {
114
- $plugin = $_GET['plugins'];
115
  } elseif ( isset( $_POST['checked'] ) ) {
116
- $plugin = nfw_implode( ", ", $_POST['checked'] );
117
  }
118
- $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
119
- $alert_item = sprintf( '%s %s', $label_name, $plugin );
120
 
121
  } elseif ( $_GET['action'] == 'upgrade-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
122
- $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
123
- $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
124
 
125
  } elseif ( $_GET['action'] == 'activate-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_13'] ) ) {
126
- $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
127
- $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
128
 
129
  } elseif ( $_GET['action'] == 'install-plugin' && current_user_can( 'install_plugins' ) && ! empty( $nfw_options['a_12'] ) ) {
130
- $alert_action = sprintf( '%s %s', $label_plugin, __('installed', 'ninjafirewall') );
131
- $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
132
 
133
  } elseif ( $_GET['action'] == 'upload-plugin' && current_user_can( 'upload_plugins' ) && ! empty( $nfw_options['a_11'] ) ) {
134
- $alert_action = sprintf( '%s %s', $label_plugin, __('uploaded', 'ninjafirewall') );
135
- $alert_item = sprintf( '%s %s', $label_name, @$_FILES['pluginzip']['name'] );
 
 
136
 
137
  } elseif ( $_GET['action'] == 'upgrade-theme' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
138
- $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
139
- $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['theme'] );
140
 
141
  } elseif ( $_GET['action'] == 'update-selected-themes' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
142
  if ( isset( $_GET['themes'] ) ) {
143
- $theme = nfw_implode( ", ", $_GET['themes'] );
144
  } elseif ( isset( $_POST['checked'] ) ) {
145
- $theme = nfw_implode( ", ", $_POST['checked'] );
146
  }
147
- $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
148
- $alert_item = sprintf( '%s %s', $label_name, $theme );
149
 
150
  } elseif ( $_GET['action'] == 'install-theme' && current_user_can( 'install_themes' ) && ! empty( $nfw_options['a_22'] ) ) {
151
- $alert_action = sprintf( '%s %s', $label_theme, __('installed', 'ninjafirewall') );
152
- $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['theme'] );
153
 
154
  } elseif ( $_GET['action'] == 'upload-theme' && current_user_can( 'upload_themes' ) && ! empty( $nfw_options['a_21'] ) ) {
155
- $alert_action = sprintf( '%s %s', $label_theme, __('uploaded', 'ninjafirewall') );
156
- $alert_item = sprintf( '%s %s', $label_name, @$_FILES['themezip']['name'] );
157
  }
158
 
159
  // AJAX actions
@@ -162,28 +164,28 @@ function nfw_sys_events() {
162
  if (! isset( $_REQUEST['action'] ) ) { return; }
163
 
164
  if ( $_REQUEST['action'] == 'install-theme' && current_user_can( 'install_themes' ) && ! empty( $nfw_options['a_22'] ) ) {
165
- $alert_action = sprintf( '%s %s', $label_theme, __('installed', 'ninjafirewall') );
166
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
167
 
168
  } elseif ( $_REQUEST['action'] == 'update-theme' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
169
- $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
170
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
171
 
172
  } elseif ( $_REQUEST['action'] == 'delete-theme' && current_user_can( 'delete_themes' ) && ! empty( $nfw_options['a_24'] ) ) {
173
- $alert_action = sprintf( '%s %s', $label_theme, __('deleted', 'ninjafirewall') );
174
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
175
 
176
  } elseif ( $_REQUEST['action'] == 'install-plugin' && current_user_can( 'install_plugins' ) && ! empty( $nfw_options['a_12'] ) ) {
177
- $alert_action = sprintf( '%s %s', $label_plugin, __('installed', 'ninjafirewall') );
178
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
179
 
180
  } elseif ( $_REQUEST['action'] == 'update-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
181
- $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
182
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['plugin'] );
183
 
184
  } elseif ( $_REQUEST['action'] == 'delete-plugin' && current_user_can( 'delete_plugins' ) && ! empty( $nfw_options['a_16'] ) ) {
185
- $alert_action = sprintf( '%s %s', $label_plugin, __('deleted', 'ninjafirewall') );
186
- $alert_item = sprintf( '%s %s', $label_name, @$_POST['plugin'] );
187
  }
188
  }
189
 
23
 
24
  $nfw_options = nfw_get_option( 'nfw_options' );
25
 
26
+ $script = $_SERVER['SCRIPT_NAME'];
27
+ $label_name = __('Name:', 'ninjafirewall');
28
+ $label_plugin = __('Plugin', 'ninjafirewall');
29
+ $label_theme = __('Theme', 'ninjafirewall');
30
+ $label_version = __('Version:', 'ninjafirewall');
31
+ $alert_action = 0;
32
 
33
  // themes.php
34
  if ( strpos( $script, '/themes.php' ) !== FALSE ) {
36
  if ( current_user_can( 'switch_themes' ) && isset( $_GET['action'] ) ) {
37
 
38
  if ( $_GET['action'] == 'activate' && ! empty( $nfw_options['a_23'] ) ) {
39
+ $theme = wp_get_theme( $_GET['stylesheet'] );
40
+ $alert_action = sprintf( '%s %s', $label_theme, __('activated', 'ninjafirewall') );
41
+ $alert_item = sprintf( '%s %s', $label_name, $theme );
42
 
43
  } elseif ( $_GET['action'] == 'delete' && current_user_can( 'delete_themes' ) && ! empty( $nfw_options['a_24'] ) ) {
44
+ $theme = wp_get_theme( $_GET['stylesheet'] );
45
+ $alert_action = sprintf( '%s %s', $label_theme, __('deleted', 'ninjafirewall') );
46
+ $alert_item = sprintf( '%s %s', $label_name, $theme );
47
  }
48
  }
49
 
70
  }
71
 
72
  if ( $_REQUEST['action'] == 'activate' && ! empty( $nfw_options['a_13'] ) ) {
73
+ $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
74
+ $alert_item = sprintf( '%s %s', $label_name, $plugin );
75
 
76
  } elseif ( $_REQUEST['action'] == 'activate-selected' && ! empty( $nfw_options['a_13'] ) ) {
77
+ $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
78
+ $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
79
 
80
  } elseif ( $_REQUEST['action'] == 'update-selected' && ! empty( $nfw_options['a_14'] ) ) {
81
+ $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
82
+ $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
83
 
84
  } elseif ( $_REQUEST['action'] == 'deactivate' && current_user_can( 'deactivate_plugin' ) && ! empty( $nfw_options['a_15'] ) ) {
85
+ $alert_action = sprintf( '%s %s', $label_plugin, __('deactivated', 'ninjafirewall') );
86
+ $alert_item = sprintf( '%s %s', $label_name, $plugin );
87
 
88
  } elseif ( $_REQUEST['action'] == 'deactivate-selected' && current_user_can( 'deactivate_plugin' ) && ! empty( $nfw_options['a_15'] ) ) {
89
+ $alert_action = sprintf( '%s %s', $label_plugin, __('deactivated', 'ninjafirewall') );
90
+ $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
91
 
92
  } elseif ( $_REQUEST['action'] == 'delete-selected' && current_user_can( 'delete_plugins' ) && ! empty( $nfw_options['a_16'] ) ) {
93
+ $alert_action = sprintf( '%s %s', $label_plugin, __('deleted', 'ninjafirewall') );
94
+ $alert_item = sprintf( '%s %s', $label_name, $plugin_list );
95
  }
96
 
97
  // update-core.php (only used for WP updates)
98
  } elseif ( strpos($_SERVER['SCRIPT_NAME'], '/update-core.php' ) !== FALSE ) {
99
 
100
+ if (! isset( $_GET['action'] ) || empty( $_POST['upgrade'] ) ) { return; }
101
 
102
  if ( $_GET['action'] == 'do-core-upgrade' && current_user_can( 'update_core' ) && ! empty( $nfw_options['a_31'] ) ) {
103
+ $alert_action = sprintf( '%s %s', 'WordPress', __('updated', 'ninjafirewall') );
104
+ $alert_item = sprintf( '%s %s', $label_version, @$_POST['version'] );
105
  }
106
 
107
  // update.php
111
 
112
  if ( $_GET['action'] == 'update-selected' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
113
  if ( isset( $_GET['plugins'] ) ) {
114
+ $plugin = $_GET['plugins'];
115
  } elseif ( isset( $_POST['checked'] ) ) {
116
+ $plugin = nfw_implode( ", ", $_POST['checked'] );
117
  }
118
+ $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
119
+ $alert_item = sprintf( '%s %s', $label_name, $plugin );
120
 
121
  } elseif ( $_GET['action'] == 'upgrade-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
122
+ $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
123
+ $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
124
 
125
  } elseif ( $_GET['action'] == 'activate-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_13'] ) ) {
126
+ $alert_action = sprintf( '%s %s', $label_plugin, __('activated', 'ninjafirewall') );
127
+ $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
128
 
129
  } elseif ( $_GET['action'] == 'install-plugin' && current_user_can( 'install_plugins' ) && ! empty( $nfw_options['a_12'] ) ) {
130
+ $alert_action = sprintf( '%s %s', $label_plugin, __('installed', 'ninjafirewall') );
131
+ $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['plugin'] );
132
 
133
  } elseif ( $_GET['action'] == 'upload-plugin' && current_user_can( 'upload_plugins' ) && ! empty( $nfw_options['a_11'] ) ) {
134
+ if ( isset( $_FILES['pluginzip']['name'] ) ) {
135
+ $alert_action = sprintf( '%s %s', $label_plugin, __('uploaded', 'ninjafirewall') );
136
+ $alert_item = sprintf( '%s %s', $label_name, $_FILES['pluginzip']['name'] );
137
+ }
138
 
139
  } elseif ( $_GET['action'] == 'upgrade-theme' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
140
+ $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
141
+ $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['theme'] );
142
 
143
  } elseif ( $_GET['action'] == 'update-selected-themes' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
144
  if ( isset( $_GET['themes'] ) ) {
145
+ $theme = nfw_implode( ", ", $_GET['themes'] );
146
  } elseif ( isset( $_POST['checked'] ) ) {
147
+ $theme = nfw_implode( ", ", $_POST['checked'] );
148
  }
149
+ $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
150
+ $alert_item = sprintf( '%s %s', $label_name, $theme );
151
 
152
  } elseif ( $_GET['action'] == 'install-theme' && current_user_can( 'install_themes' ) && ! empty( $nfw_options['a_22'] ) ) {
153
+ $alert_action = sprintf( '%s %s', $label_theme, __('installed', 'ninjafirewall') );
154
+ $alert_item = sprintf( '%s %s', $label_name, @$_REQUEST['theme'] );
155
 
156
  } elseif ( $_GET['action'] == 'upload-theme' && current_user_can( 'upload_themes' ) && ! empty( $nfw_options['a_21'] ) ) {
157
+ $alert_action = sprintf( '%s %s', $label_theme, __('uploaded', 'ninjafirewall') );
158
+ $alert_item = sprintf( '%s %s', $label_name, @$_FILES['themezip']['name'] );
159
  }
160
 
161
  // AJAX actions
164
  if (! isset( $_REQUEST['action'] ) ) { return; }
165
 
166
  if ( $_REQUEST['action'] == 'install-theme' && current_user_can( 'install_themes' ) && ! empty( $nfw_options['a_22'] ) ) {
167
+ $alert_action = sprintf( '%s %s', $label_theme, __('installed', 'ninjafirewall') );
168
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
169
 
170
  } elseif ( $_REQUEST['action'] == 'update-theme' && current_user_can( 'update_themes' ) && ! empty( $nfw_options['a_25'] ) ) {
171
+ $alert_action = sprintf( '%s %s', $label_theme, __('updated', 'ninjafirewall') );
172
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
173
 
174
  } elseif ( $_REQUEST['action'] == 'delete-theme' && current_user_can( 'delete_themes' ) && ! empty( $nfw_options['a_24'] ) ) {
175
+ $alert_action = sprintf( '%s %s', $label_theme, __('deleted', 'ninjafirewall') );
176
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
177
 
178
  } elseif ( $_REQUEST['action'] == 'install-plugin' && current_user_can( 'install_plugins' ) && ! empty( $nfw_options['a_12'] ) ) {
179
+ $alert_action = sprintf( '%s %s', $label_plugin, __('installed', 'ninjafirewall') );
180
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['slug'] );
181
 
182
  } elseif ( $_REQUEST['action'] == 'update-plugin' && current_user_can( 'update_plugins' ) && ! empty( $nfw_options['a_14'] ) ) {
183
+ $alert_action = sprintf( '%s %s', $label_plugin, __('updated', 'ninjafirewall') );
184
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['plugin'] );
185
 
186
  } elseif ( $_REQUEST['action'] == 'delete-plugin' && current_user_can( 'delete_plugins' ) && ! empty( $nfw_options['a_16'] ) ) {
187
+ $alert_action = sprintf( '%s %s', $label_plugin, __('deleted', 'ninjafirewall') );
188
+ $alert_item = sprintf( '%s %s', $label_name, @$_POST['plugin'] );
189
  }
190
  }
191
 
lib/firewall.php CHANGED
@@ -28,6 +28,9 @@ if ( @file_exists($nfw_['file'] = dirname($_SERVER['DOCUMENT_ROOT']) .'/.htninja
28
  @file_exists($nfw_['file'] = $_SERVER['DOCUMENT_ROOT'] .'/.htninja') ) {
29
  $nfw_['res'] = @include_once $nfw_['file'];
30
  if ( $nfw_['res'] == 'ALLOW' ) {
 
 
 
31
  nfw_quit( 20 );
32
  return;
33
  }
@@ -106,13 +109,21 @@ if ( empty($nfw_['nfw_options']['enabled']) ) {
106
 
107
  include_once 'custom_firewall.php';
108
 
109
- if (! empty($nfw_['nfw_options']['response_headers']) && function_exists('header_register_callback')) {
110
- define('NFW_RESHEADERS', $nfw_['nfw_options']['response_headers']);
111
- if (! empty( $nfw_['nfw_options']['response_headers'][6] ) && ! empty( $nfw_['nfw_options']['csp_frontend_data'] ) ) {
112
- define( 'CSP_FRONTEND_DATA', $nfw_['nfw_options']['csp_frontend_data']);
 
 
 
 
 
 
 
 
113
  }
114
- if (! empty( $nfw_['nfw_options']['response_headers'][7] ) && ! empty( $nfw_['nfw_options']['csp_backend_data'] ) ) {
115
- define( 'CSP_BACKEND_DATA', $nfw_['nfw_options']['csp_backend_data'] );
116
  }
117
  header_register_callback('nfw_response_headers');
118
  }
@@ -1822,6 +1833,10 @@ function nfw_check_dbhost() {
1822
 
1823
  function nfw_response_headers() {
1824
 
 
 
 
 
1825
  if (! defined('NFW_RESHEADERS') ) { return; }
1826
  $NFW_RESHEADERS = NFW_RESHEADERS;
1827
  // NFW_RESHEADERS:
@@ -1964,6 +1979,16 @@ function nfw_response_headers() {
1964
  }
1965
  header('Strict-Transport-Security: '. $max_age);
1966
  }
 
 
 
1967
 
 
 
 
 
 
 
 
1968
  // =====================================================================
1969
  // EOF
28
  @file_exists($nfw_['file'] = $_SERVER['DOCUMENT_ROOT'] .'/.htninja') ) {
29
  $nfw_['res'] = @include_once $nfw_['file'];
30
  if ( $nfw_['res'] == 'ALLOW' ) {
31
+ if (! defined( 'NFW_UWL' ) ) {
32
+ define('NFW_UWL', true);
33
+ }
34
  nfw_quit( 20 );
35
  return;
36
  }
109
 
110
  include_once 'custom_firewall.php';
111
 
112
+ // HTTP response headers
113
+ if ( (! empty( $nfw_['nfw_options']['response_headers'] ) || ! empty($nfw_['nfw_options']['custom_headers']) )
114
+ && function_exists('header_register_callback') ) {
115
+
116
+ if (! empty( $nfw_['nfw_options']['response_headers'] ) ) {
117
+ define('NFW_RESHEADERS', $nfw_['nfw_options']['response_headers']);
118
+ if (! empty( $nfw_['nfw_options']['response_headers'][6] ) && ! empty( $nfw_['nfw_options']['csp_frontend_data'] ) ) {
119
+ define( 'CSP_FRONTEND_DATA', $nfw_['nfw_options']['csp_frontend_data']);
120
+ }
121
+ if (! empty( $nfw_['nfw_options']['response_headers'][7] ) && ! empty( $nfw_['nfw_options']['csp_backend_data'] ) ) {
122
+ define( 'CSP_BACKEND_DATA', $nfw_['nfw_options']['csp_backend_data'] );
123
+ }
124
  }
125
+ if (! empty( $nfw_['nfw_options']['custom_headers'] ) ) {
126
+ define('NFW_CUSTHEADERS', $nfw_['nfw_options']['custom_headers']);
127
  }
128
  header_register_callback('nfw_response_headers');
129
  }
1833
 
1834
  function nfw_response_headers() {
1835
 
1836
+ if ( defined('NFW_CUSTHEADERS') ) {
1837
+ nfw_custom_headers();
1838
+ }
1839
+
1840
  if (! defined('NFW_RESHEADERS') ) { return; }
1841
  $NFW_RESHEADERS = NFW_RESHEADERS;
1842
  // NFW_RESHEADERS:
1979
  }
1980
  header('Strict-Transport-Security: '. $max_age);
1981
  }
1982
+ // =====================================================================
1983
+
1984
+ function nfw_custom_headers() {
1985
 
1986
+ $headers = json_decode( NFW_CUSTHEADERS, true );
1987
+ if (! empty( $headers ) ) {
1988
+ foreach( $headers as $key => $value ) {
1989
+ header( "$key: $value" );
1990
+ }
1991
+ }
1992
+ }
1993
  // =====================================================================
1994
  // EOF
lib/firewall_policies.php CHANGED
@@ -406,7 +406,7 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
406
  <p><label><input<?php echo $reg_user ?> type="checkbox" name="nfw_options[disallow_creation]" value="1"<?php checked( $disallow_creation, 1 ) ?>>&nbsp;<?php _e('Block user accounts creation', 'ninjafirewall') ?></label></p>
407
  <p><label><input <?php disabled( $disabled, 1 ) ?>type="checkbox" name="nfw_options[disallow_privesc]" value="1"<?php checked( $disallow_privesc, 1 ) ?>>&nbsp;<?php _e('Block attempts to gain administrative privileges', 'ninjafirewall'); echo $main_site; ?></label></p>
408
  <?php echo $msg ?>
409
- <p style="margin-left:20px"><label><input<?php echo $reg_site ?> <?php disabled( $disabled_mu, 1 ) ?>type="checkbox" name="nfw_options[disallow_privesc_mu]" value="1"<?php checked( $disallow_privesc_mu, 1 ) ?>>&nbsp;<?php _e('Apply to all subsites in the network', 'ninjafirewall'); echo $network_only; ?></label></p>
410
 
411
  <p><label><input type="checkbox" name="nfw_options[disallow_publish]" value="1"<?php checked( $disallow_publish, 1 ) ?>>&nbsp;<?php echo _e('Block attempts to publish, edit or delete a published post by users who do not have the right capabilities', 'ninjafirewall') ?> <?php _e('(recommended)', 'ninjafirewall') ?></label></p>
412
  </td>
@@ -934,7 +934,7 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
934
  <td>
935
  <?php nfw_toggle_switch( 'info', 'nfw_options[csp_frontend]', $yes, $no, 'small', $nfw_options['response_headers'][6], $err, 'onclick="nfwjs_csp_onoff(\'csp1_switch\',\'csp1\');"', 'csp1_switch' ) ?>
936
  <br />
937
- <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="nfw_options[csp_frontend_data]" id="csp1" class="large-text code" rows="8"<?php readonly( $err, 1 ); readonly( $nfw_options['response_headers'][6], 0 ) ?>><?php echo htmlspecialchars( $nfw_options['csp_frontend_data'] ) ?></textarea>
938
  <p class="description"><?php _e('This CSP header will apply to the website frontend only.', 'ninjafirewall') ?></p>
939
  </td>
940
  </tr>
@@ -943,7 +943,7 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
943
  <td>
944
  <?php nfw_toggle_switch( 'info', 'nfw_options[csp_backend]', $yes, $no, 'small', $nfw_options['response_headers'][7], $err, 'onclick="nfwjs_csp_onoff(\'csp2_switch\',\'csp2\');"', 'csp2_switch' ) ?>
945
  <br />
946
- <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="nfw_options[csp_backend_data]" id="csp2" class="large-text code" rows="8"<?php readonly( $err, 1 ); readonly( $nfw_options['response_headers'][7], 0 ) ?>><?php echo htmlspecialchars( $nfw_options['csp_backend_data'] ) ?></textarea>
947
  <p class="description"><?php _e('This CSP header will apply to the WordPress admin dashboard only.', 'ninjafirewall') ?></p>
948
  <?php echo $err_msg ?>
949
  </td>
@@ -976,6 +976,35 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
976
  </select>
977
  </td>
978
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
979
  </table>
980
 
981
  <br /><br />
@@ -1334,6 +1363,26 @@ function nf_sub_policies_save() {
1334
  }
1335
  }
1336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1337
 
1338
  if ( empty( $_POST['nfw_options']['cookies_scan']) ) {
1339
  $nfw_options['cookies_scan'] = 0;
@@ -1670,6 +1719,7 @@ function nf_sub_policies_default() {
1670
  unset( $nfw_options['csp_backend_data'] );
1671
  $nfw_options['csp_frontend_data'] = '';
1672
  }
 
1673
  $nfw_options['cookies_scan'] = 1;
1674
  $nfw_options['cookies_sanitise'] = 0;
1675
  $nfw_options['ua_scan'] = 1;
406
  <p><label><input<?php echo $reg_user ?> type="checkbox" name="nfw_options[disallow_creation]" value="1"<?php checked( $disallow_creation, 1 ) ?>>&nbsp;<?php _e('Block user accounts creation', 'ninjafirewall') ?></label></p>
407
  <p><label><input <?php disabled( $disabled, 1 ) ?>type="checkbox" name="nfw_options[disallow_privesc]" value="1"<?php checked( $disallow_privesc, 1 ) ?>>&nbsp;<?php _e('Block attempts to gain administrative privileges', 'ninjafirewall'); echo $main_site; ?></label></p>
408
  <?php echo $msg ?>
409
+ <p style="margin-left:20px"><label><input<?php echo $reg_site ?> <?php disabled( $disabled_mu, 1 ) ?> type="checkbox" name="nfw_options[disallow_privesc_mu]" value="1"<?php checked( $disallow_privesc_mu, 1 ) ?>>&nbsp;<?php _e('Apply to all subsites in the network', 'ninjafirewall'); echo $network_only; ?></label></p>
410
 
411
  <p><label><input type="checkbox" name="nfw_options[disallow_publish]" value="1"<?php checked( $disallow_publish, 1 ) ?>>&nbsp;<?php echo _e('Block attempts to publish, edit or delete a published post by users who do not have the right capabilities', 'ninjafirewall') ?> <?php _e('(recommended)', 'ninjafirewall') ?></label></p>
412
  </td>
934
  <td>
935
  <?php nfw_toggle_switch( 'info', 'nfw_options[csp_frontend]', $yes, $no, 'small', $nfw_options['response_headers'][6], $err, 'onclick="nfwjs_csp_onoff(\'csp1_switch\',\'csp1\');"', 'csp1_switch' ) ?>
936
  <br />
937
+ <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="nfw_options[csp_frontend_data]" id="csp1" class="large-text code" rows="8"<?php wp_readonly( $err, 1 ); wp_readonly( $nfw_options['response_headers'][6], 0 ) ?>><?php echo htmlspecialchars( $nfw_options['csp_frontend_data'] ) ?></textarea>
938
  <p class="description"><?php _e('This CSP header will apply to the website frontend only.', 'ninjafirewall') ?></p>
939
  </td>
940
  </tr>
943
  <td>
944
  <?php nfw_toggle_switch( 'info', 'nfw_options[csp_backend]', $yes, $no, 'small', $nfw_options['response_headers'][7], $err, 'onclick="nfwjs_csp_onoff(\'csp2_switch\',\'csp2\');"', 'csp2_switch' ) ?>
945
  <br />
946
+ <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="nfw_options[csp_backend_data]" id="csp2" class="large-text code" rows="8"<?php wp_readonly( $err, 1 ); wp_readonly( $nfw_options['response_headers'][7], 0 ) ?>><?php echo htmlspecialchars( $nfw_options['csp_backend_data'] ) ?></textarea>
947
  <p class="description"><?php _e('This CSP header will apply to the WordPress admin dashboard only.', 'ninjafirewall') ?></p>
948
  <?php echo $err_msg ?>
949
  </td>
976
  </select>
977
  </td>
978
  </tr>
979
+
980
+ <?php
981
+ $custom_headers = '';
982
+ if (! empty( $nfw_options['custom_headers'] ) ) {
983
+ $headers = json_decode( $nfw_options['custom_headers'], true );
984
+ if (! empty( $headers ) ) {
985
+ foreach( $headers as $key => $value ) {
986
+ $custom_headers .= "$key: $value\n";
987
+ }
988
+ }
989
+ }
990
+ ?>
991
+ <tr>
992
+ <th scope="row" class="row-med"><?php esc_html_e('Custom HTTP headers', 'ninjafirewall'); ?></th>
993
+ <td>
994
+ <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="nfw_options[custom_headers]" class="large-text code" rows="8"><?php echo esc_textarea( $custom_headers ) ?></textarea>
995
+ <p class="description"><?php _e('You can enter one or more custom HTTP headers. The format is <code>header: value</code>, one per line.', 'ninjafirewall') ?></p>
996
+ </td>
997
+ </tr>
998
+
999
+ <tr>
1000
+ <th scope="row" class="row-med"><?php esc_html_e('HTTP headers test', 'ninjafirewall'); ?></th>
1001
+ <td>
1002
+ <button type="button" class="button-secondary" onClick="nfwjs_test_headers('<?php echo esc_attr( home_url( '/' ) ) ?>');" /><?php esc_html_e('View your website\'s HTTP response headers', 'ninjafirewall' )?></button>
1003
+ &nbsp;&nbsp;&nbsp;
1004
+ <img style="vertical-align:middle;display:none" id="progress-gif" src="<?php echo plugins_url('/images/progress.gif', dirname (__FILE__ ) ) ?>" />
1005
+ <p class="description"><?php _e('Make sure to save your changes before running the test.', 'ninjafirewall') ?></p>
1006
+ </td>
1007
+ </tr>
1008
  </table>
1009
 
1010
  <br /><br />
1363
  }
1364
  }
1365
 
1366
+ // Custom HTTP headers
1367
+ $custom_headers = array();
1368
+ if (! empty( $_POST['nfw_options']['custom_headers'] ) ) {
1369
+ $headers = explode( "\r\n", $_POST['nfw_options']['custom_headers'] );
1370
+ if (! empty( $headers[0] ) ) {
1371
+ foreach( $headers as $header ) {
1372
+ list( $key, $value ) = explode( ':', "$header:" );
1373
+ $key = trim( $key );
1374
+ $value = trim( $value );
1375
+ if (! empty( $key ) && ! empty( $value ) ) {
1376
+ $custom_headers[ $key ] = $value;
1377
+ }
1378
+ }
1379
+ }
1380
+ }
1381
+ if (! empty( $custom_headers ) ) {
1382
+ $nfw_options['custom_headers'] = json_encode( $custom_headers );
1383
+ } else {
1384
+ unset ( $nfw_options['custom_headers'] );
1385
+ }
1386
 
1387
  if ( empty( $_POST['nfw_options']['cookies_scan']) ) {
1388
  $nfw_options['cookies_scan'] = 0;
1719
  unset( $nfw_options['csp_backend_data'] );
1720
  $nfw_options['csp_frontend_data'] = '';
1721
  }
1722
+ $nfw_options['custom_headers'] = '';
1723
  $nfw_options['cookies_scan'] = 1;
1724
  $nfw_options['cookies_sanitise'] = 0;
1725
  $nfw_options['ua_scan'] = 1;
lib/i18n-extra.php CHANGED
@@ -18,7 +18,6 @@ __('Invalid IP address.', 'ninjafirewall');
18
  __('Installation', 'ninjafirewall');
19
  __('NinjaFirewall: Access Control', 'ninjafirewall');
20
  __('NinjaFirewall: Antispam', 'ninjafirewall');
21
- __('Referral Program', 'ninjafirewall');
22
  __('License', 'ninjafirewall');
23
  __('Enter your NinjaFirewall WP+ license and click on the save button', 'ninjafirewall');
24
  __('Don\'t have a license yet?', 'ninjafirewall');
18
  __('Installation', 'ninjafirewall');
19
  __('NinjaFirewall: Access Control', 'ninjafirewall');
20
  __('NinjaFirewall: Antispam', 'ninjafirewall');
 
21
  __('License', 'ninjafirewall');
22
  __('Enter your NinjaFirewall WP+ license and click on the save button', 'ninjafirewall');
23
  __('Don\'t have a license yet?', 'ninjafirewall');
lib/logs_firewall_log.php CHANGED
@@ -220,6 +220,11 @@ function nf_sub_log_save_options( $nfw_options ) {
220
  } else {
221
  $nfw_options['auto_del_log'] = (int) $_POST['nfw_options']['auto_del_log'];
222
  }
 
 
 
 
 
223
 
224
  nfw_update_option( 'nfw_options', $nfw_options );
225
 
220
  } else {
221
  $nfw_options['auto_del_log'] = (int) $_POST['nfw_options']['auto_del_log'];
222
  }
223
+ // We need to keep the log for more than 24 hours otherwise
224
+ // the daily report will be empty
225
+ if ( $nfw_options['auto_del_log'] == 1 ) {
226
+ $nfw_options['auto_del_log'] = 2;
227
+ }
228
 
229
  nfw_update_option( 'nfw_options', $nfw_options );
230
 
lib/thickbox.php CHANGED
@@ -72,7 +72,13 @@ function nfw_upgrade_fullwaf() {
72
  <div id="nfw-activate-thickbox-content" style="display:none">
73
 
74
  <h2><?php _e('Activate Full WAF mode', 'ninjafirewall') ?></h2>
75
-
 
 
 
 
 
 
76
  <div id="nfwaf-step1">
77
  <p>
78
  <?php
72
  <div id="nfw-activate-thickbox-content" style="display:none">
73
 
74
  <h2><?php _e('Activate Full WAF mode', 'ninjafirewall') ?></h2>
75
+ <?php
76
+ // Detect and warn about Docker image when upgrading to Full WAF mode
77
+ if ( function_exists( 'getenv_docker' ) ) {
78
+ echo '<div class="nfw-notice nfw-notice-red"><p>'.
79
+ esc_html__('Warning, it seems that you are running WordPress in a Docker image: activating the Full WAF mode may crash your site. Make sure to read the following recommendations:', 'ninjafirewall' ) .' <a href="https://wordpress.org/support/topic/fatal-error-cannot-retrieve-wordpress-credentials-using-docker-image/" target="_blank" rel="noreferrer noopener">'. esc_html__('WordPress and Docker image', 'ninjafirewall') . '</a></p></div>';
80
+ }
81
+ ?>
82
  <div id="nfwaf-step1">
83
  <p>
84
  <?php
lib/utils.php CHANGED
@@ -1734,8 +1734,8 @@ add_action('plugins_loaded', 'nfw_dropins', -1);
1734
  // ---------------------------------------------------------------------
1735
  // For WP <4.9.
1736
 
1737
- if (! function_exists( 'readonly' ) ) {
1738
- function readonly( $var, $val) {
1739
  if ( $var == $val ) {
1740
  echo " readonly='readonly'";
1741
  }
1734
  // ---------------------------------------------------------------------
1735
  // For WP <4.9.
1736
 
1737
+ if (! function_exists( 'wp_readonly' ) ) {
1738
+ function wp_readonly( $var, $val) {
1739
  if ( $var == $val ) {
1740
  echo " readonly='readonly'";
1741
  }
lib/widget.php CHANGED
@@ -35,8 +35,8 @@ if ( is_multisite() ) {
35
  $dashboard = 'dashboard';
36
  }
37
  if (! empty( $wp_meta_boxes[$dashboard]['normal']['core'] ) ) {
38
- $wpmb = $wp_meta_boxes[$dashboard]['normal']['core'];
39
- $nfwidget = ['nfw_dashboard_welcome' => $wpmb['nfw_dashboard_welcome'],];
40
  $wp_meta_boxes[$dashboard]['normal']['core'] = array_merge( $nfwidget, $wpmb );
41
  }
42
 
@@ -50,15 +50,15 @@ function nfw_stats_widget() {
50
  $nfw_stat = '0:0:0:0:0:0:0:0:0:0';
51
  }
52
  list($tmp, $medium, $high, $critical) = explode(':', $nfw_stat . ':');
53
- $medium = (int) $medium;
54
- $high = (int) $high;
55
- $critical = (int) $critical;
56
- $total = $critical + $high + $medium;
57
  if ( $total ) {
58
- $coef = 100 / $total;
59
- $critical = round( $critical * $coef, 2);
60
- $high = round( $high * $coef, 2);
61
- $medium = round( $medium * $coef, 2);
62
  }
63
  echo '
64
  <table border="0" width="100%">
@@ -112,7 +112,7 @@ function nfw_stats_widget() {
112
  return;
113
  }
114
 
115
- echo '<br /><div><h3 style="font-weight:600;">'. esc_html__('Latest Security News', 'ninjafirewall' ) .'</h3></div>';
116
  echo '<div class="rss-widget"><ul>';
117
  $count = 0;
118
  foreach( $news as $k => $v ) {
35
  $dashboard = 'dashboard';
36
  }
37
  if (! empty( $wp_meta_boxes[$dashboard]['normal']['core'] ) ) {
38
+ $wpmb = $wp_meta_boxes[$dashboard]['normal']['core'];
39
+ $nfwidget = ['nfw_dashboard_welcome' => $wpmb['nfw_dashboard_welcome'],];
40
  $wp_meta_boxes[$dashboard]['normal']['core'] = array_merge( $nfwidget, $wpmb );
41
  }
42
 
50
  $nfw_stat = '0:0:0:0:0:0:0:0:0:0';
51
  }
52
  list($tmp, $medium, $high, $critical) = explode(':', $nfw_stat . ':');
53
+ $medium = (int) $medium;
54
+ $high = (int) $high;
55
+ $critical = (int) $critical;
56
+ $total = $critical + $high + $medium;
57
  if ( $total ) {
58
+ $coef = 100 / $total;
59
+ $critical = round( $critical * $coef, 2);
60
+ $high = round( $high * $coef, 2);
61
+ $medium = round( $medium * $coef, 2);
62
  }
63
  echo '
64
  <table border="0" width="100%">
112
  return;
113
  }
114
 
115
+ echo '<br /><div><h3 style="font-weight:600;">'. esc_html__('Latest News from NinTechNet', 'ninjafirewall' ) .'</h3></div>';
116
  echo '<div class="rss-widget"><ul>';
117
  $count = 0;
118
  foreach( $news as $k => $v ) {
ninjafirewall.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: NinjaFirewall (WP Edition)
4
  Plugin URI: https://nintechnet.com/
5
  Description: A true Web Application Firewall to protect and secure WordPress.
6
- Version: 4.4.3
7
  Author: The Ninja Technologies Network
8
  Author URI: https://nintechnet.com/
9
  License: GPLv3 or later
@@ -19,7 +19,7 @@ Domain Path: /languages
19
  | (c) NinTechNet - https://nintechnet.com/ |
20
  +---------------------------------------------------------------------+
21
  */
22
- define( 'NFW_ENGINE_VERSION', '4.4.3' );
23
  /*
24
  +---------------------------------------------------------------------+
25
  | This program is free software: you can redistribute it and/or |
3
  Plugin Name: NinjaFirewall (WP Edition)
4
  Plugin URI: https://nintechnet.com/
5
  Description: A true Web Application Firewall to protect and secure WordPress.
6
+ Version: 4.5
7
  Author: The Ninja Technologies Network
8
  Author URI: https://nintechnet.com/
9
  License: GPLv3 or later
19
  | (c) NinTechNet - https://nintechnet.com/ |
20
  +---------------------------------------------------------------------+
21
  */
22
+ define( 'NFW_ENGINE_VERSION', '4.5' );
23
  /*
24
  +---------------------------------------------------------------------+
25
  | This program is free software: you can redistribute it and/or |
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: nintechnet, bruandet
3
  Tags: security, firewall, malware, protection, hack, antispam, virus, scanner, hacked site, brute force, seguridad, seguranca, sicherheit, sicurezza, veiligheid, classicpress
4
  Requires at least: 4.7
5
- Tested up to: 5.8
6
- Stable tag: 4.4.3
7
  Requires PHP: 5.5
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -84,7 +84,7 @@ You can prepend your own PHP code to the firewall with the help of an [optional
84
  = Low Footprint Firewall =
85
 
86
  NinjaFirewall is very fast, optimised, compact, and requires very low system resource.
87
- See for yourself: download and install [Query Monitor](https://wordpress.org/plugins/query-monitor/ "") and [Xdebug Profiler](https://xdebug.org/ "") and compare NinjaFirewall performances with other security plugins.
88
 
89
  = Non-Intrusive User Interface =
90
 
@@ -208,395 +208,18 @@ WordPress Sicherheit Plugin.
208
 
209
  Need more security? Take the time to explore our supercharged Premium edition: [NinjaFirewall WP+ Edition](https://nintechnet.com/ninjafirewall/wp-edition/?comparison)
210
 
211
- = 4.4.3 =
212
-
213
- * Fixed a potential PHP error on servers running the Litespeed PHP SAPI (LSAPI) that deosn't have the MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT constant defined.
214
- * Removed the "Cannot check if the PHP INI file is readable: connection error" warning.
215
- * Fixed an "Undefined array key SERVER_ADDR" PHP warning.
216
- * Updated Charts.js to v3.6.1
217
- * WP+ Edition (Premium): Updated GeoIP databases.
218
- * Small fixes and adjustments.
219
-
220
- = 4.4.2 =
221
-
222
- * Fixed an issue introduced in v4.4.1 where a notification email was sent each time an external application authenticated itself.
223
-
224
- = 4.4.1 =
225
-
226
- * Added support for MySQL/MariaDB database connection over SSL.
227
- * NinjaFirewall will permanently monitor its scheduled tasks (cron) to make sure they are working. If they stopped, it would restart them and write the incident to its error log (which can be viewed from the "NinjaFirewall > Dashboard" page).
228
- * Uninstalled plugins and themes will be removed from the cache used for security updates notifications.
229
- * Error messages were rewritten for better understanding.
230
- * The "Block attempts to publish, edit or delete a published post by users who do not have the right capabilities" policy will only apply if the content or the title of the post has been changed, so that plugins that are used to modify metadata such as the date and time will not be blocked.
231
- * Users who do not have access to a WordPress installation any longer but keep receiving the firewall's email notifications, can remove their email address by clicking on the corresponding link found in every notification sent by NinjaFirewall.
232
- * WP+ Edition (Premium): Updated GeoIP databases.
233
- * Many additional small fixes and adjustments.
234
-
235
- = 4.4 =
236
-
237
- * The "Full WAF" mode can be configured to exclude some directories. That can be done from the "NinjaFirewall > Dashboard" page by clicking on the new "Configure" button. There's no need to use the ".htninja" script to exclude folders anymore. That can be useful to exclude third-party applications that rely on PHP sessions and could behave erratically with the "Full WAF" mode (e.g., Piwik/Matomo, phpMyAdmin, forums etc).
238
- * You can easily downgrade from "Full WAF" mode to "WordPress WAF" mode by clicking the "Configure" button in the "NinjaFirewall > Dashboard" page.
239
- * Added a warning about the "X-XSS-Protection" HTTP header in the "Firewall Policies" section: although NinjaFirewall still supports it, it is now deprecated and only used by Safari. Consider using "Content-Security-Policy" (CSP) instead.
240
- * When reactivating NinjaFirewall from the "Plugins" page, it will verify that the path to the firewall file is correct or, if necessary, will adjust it (e.g., after a server migration etc).
241
- * NinjaFirewall will display a warning in its "Dashboard" page if the .user.ini or php.ini file is readable.
242
- * The configuation backup files are now base64-encoded to prevent being wrongly flagged by some hosting companies antivirus.
243
- * NinjaFirewall will hightlight in red colour in the "Plugins" page any plugin that has a pending security update. See [https://nin.link/nfsecupdates/](https://nin.link/nfsecupdates/) for more details.
244
- * The cache used to store information about pending security updates will be automatically flushed.
245
- * On old multisite installations, the firewall will no longer block access to the "/wp-includes/ms-files.php" script.
246
- * The firewall can now detect user roles even before WordPress is loaded.
247
- * Updated Charts.js to v3.4.1.
248
- * WP+ Edition (Premium): Updated GeoIP databases.
249
- * Many additional small fixes and adjustments.
250
-
251
- = 4.3.4 =
252
-
253
- * Fixed a PHP fatal error ("Argument #1 must be of type array, string given") in the Events Notification page that could occur when updating a plugin.
254
- * NinjaFirewall will only start a PHP session in the "admin_init" hook if the user is logged-in, so that unauthenticated AJAX calls will remain cookie free (props @mattvol).
255
- * When creating a snapshot, File Check will ensure that the directory is not a PHP wrapper to prevent potential phar deserialization (props C. Chamberland). Consult this post for more details: https://nin.link/nfwpphar/
256
- * WP+ Edition (Premium): Fixed a syntax error in a regex.
257
- * During the File Check scan, errors will be written to the firewall's error log, which is viewable in the "Dashboard" page.
258
  * WP+ Edition (Premium): Updated GeoIP databases.
259
- * Small fixes and adjustments.
260
-
261
- = 4.3.3 =
262
-
263
- * Added a new firewall policy to prevent user enumeration via the author sitemap. See "Firewall Policies > Protect against username enumeration > Through the author sitemap".
264
- * WP+ Edition (Premium): The "File Uploads > Allow, but block dangerous files" option will now block uploaded files that include JavaScript tags.
265
- * The "General" section in the "Firewall Policies > Basic Policies" page was renamed to "Permissions".
266
- * The firewall will display a notice message if the Login Protection is set to "Captcha" but PHP wasn't compiled with freetype support (--with-freetype-dir=DIR) to avoid a "Call to undefined function imagettftext" fatal error when accessing the login page.
267
- * Fixed a potential "Undefined constant GEOIP_STANDARD" PHP error.
268
- * Fixed a potential "Undefined array key shmop" PHP warning.
269
- * Fixed a false positive detection triggered when submitting ACF Forms base64-encoded payload.
270
- * WP+ Edition (Premium): Added Paypal IPN new IP addresses to the Access Control whitelist.
271
- * Small fixes and adjustments.
272
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
273
-
274
- = 4.3.2 =
275
-
276
- * To make things easier for translators, NinjaFirewall WP (free) and WP+ (premium) Edition will now use the same language files. Translators can work on the files available at https://translate.wordpress.org/projects/wp-plugins/ninjafirewall/ , they will be used by both editions.
277
- * WP+ Edition (Premium): If you want to use the language files (if available) from translate.wordpress.org, you can enable that new option from the "Firewall Options > Load language files from the WordPress repo" section. Note that this does not apply to en_US and fr_FR locales because they are already installed with NinjaFirewall.
278
- * The NinjaFirewall notice in the Site Health page about the failed loopback test will not be displayed anymore on blogs running WordPress >=5.6.1 (this was a bug in WordPress and was fixed in v5.6.1).
279
- * Fixed a "Undefined index: SERVER_ADDR" PHP notice.
280
- * In the Login Protection page, the username and password can now be up to 255 characters, instead of 32.
281
- * Small fixes and adjustments.
282
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
283
-
284
- = 4.3.1 =
285
-
286
- * Added a new policy to disable the "Application Passwords" feature that was introduced in WordPress 5.6. See "Firewall Policies > Basic Policies > Application Passwords".
287
- * Added a notice to Site Health's page: if the Login Protection is enabled, Site Health will return an error, which is normal and thus can be safely ignored.
288
- * Fixed a bug where it was not possible to enable the Full WAF mode on HTTP server running Apache and PHP 8.0 as a module (mod_php).
289
- * Add detection of HTTP servers running Apache with LSAPI PHP module (CloudLinux).
290
- * The sandbox can be disabled when running the Full WAF mode installer.
291
- * Small fixes and adjustments.
292
-
293
- = 4.3 =
294
-
295
- * Added a new firewall policy to block attempts to override PHP superglobals. See the "NinjaFirewall > Firewall Policies > Advanced Policies > PHP" section.
296
- * WP+ Edition (Premium): Added a whitelist of IP addresses from the following external services: Automattic (JetPack, VaultPress etc), Paypal and Stripes payment gateways. If you use those services, you can easily whitelist them with the "NinjaFirewall > Access Control > IP Access Control > External Services" option.
297
- * Fixed PHP 8.0 compatibility issues.
298
- * Fixed a potential bug that could reset some advanced policies when updating the firewall security rules.
299
- * Fixed a "Call to undefined function readonly" PHP error on old WordPress versions (<4.9).
300
- * Fixed a "Cannot redeclare nfw_anonymize_ip2" PHP error message.
301
- * Improved the sandbox of the "Full WAF" mode installer.
302
- * Updated Chart.js to the latest version.
303
- * Many additional small fixes and adjustments.
304
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
305
-
306
- = 4.2.6 =
307
-
308
- * Fixed a database error message on a multisite installation when accessing a subsite.
309
- * On a multisite installation, the "Block attempts to gain administrative privileges" policy will apply to the main site only so that it won't block users if they are allowed to register new sites. Another policy was added for subsites, which should be enabled only if site registration is turned-off (see "Firewall Policies > Apply to all subsites in the network" ).
310
- * Small fixes and adjustments.
311
-
312
- = 4.2.5 =
313
-
314
- * The "NinjaFirewall > Dashboard" page will display the firewall's error log if it exists. It could be viewed and deleted from that page.
315
- * The "Block attempts to publish or edit a published post by users who do not have the right capabilities" policy will now also apply to post/page deletion.
316
- * Added a warning if Woocomerce was installed and the user tried to enable the "Block user accounts creation" policy.
317
- * WP+ Edition (Premium) : Fixed a `shmop_open` PHP warning message in the backend when WP_DEBUG was enabled.
318
- * Improved "Full WAF" mode installer.
319
- * Many additional small fixes and adjustments.
320
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
321
-
322
- = 4.2.4 =
323
-
324
- * Fixed a potential PHP warning when checking for security updates.
325
- * Since the new WordPress v5.5, the Site Health function returns a wrong "An active PHP session was detected" critical message. This version of NinjaFirewall will remove it because the REST API is working as expected (the firewall does not interfer with it or any loopback request).
326
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
327
-
328
- = 4.2.3 =
329
-
330
- * Fixed a potential issue where NinjaFirewall could prevent the WordPress Quick Draft widget from loading (#2140).
331
- * Authors and Contributors will no longer be blocked when using Gutenberg if the firewall was set up to block any access to the REST API.
332
- * NinjaFirewall can now handle DB passwords enclosed in double-quotes and containing one or more escaped dollar sign (e.g., `"...\$..."`).
333
- * Small fixes and adjustments.
334
-
335
- = 4.2.2 =
336
-
337
- * WP+ Edition (Premium): NinjaFirewall can now scan ZIP archives. If you have enabled the "Allow uploads, but block dangerous files" firewall policy, you can also enable the "Apply to ZIP archives file contents" option so that the firewall will extract and scan the files found in ZIP archives. See "Firewall Policies > Basic Policies > File Uploads > Apply to ZIP archives file contents".
338
- * Added "preload" to the Strict-Transport-Security policy (HSTS) and the "max-age" value was increased up to 2 years (this is the recommended value for preload) in the "Firewall Policies > Advanced Policies > HTTP response headers" section.
339
- * The daily report will try to prevent WP Cron to send it twice on blogs that may have an issue with the task scheduler.
340
- * Fixed an issue with the captcha protection: some plugins are wrongly redirecting HTTP requests to get the favicon.ico file to the login page and thus trigger the firewall protection.
341
- * Better handling of the backslash character in the database password field.
342
- * Fixed potential "Call to a member function get_error_message on null" PHP error when checking security updates.
343
- * You can change the length of the payload that NinjaFirewall writes to its log, by defining the `NFW_MAXPAYLOAD` constant in the .htninja file. By default, the firewall will write up to 200 characters to the log.
344
- * The dashboard widget will cache the data for 30 minutes.
345
- * The login notification hook has a higher priority so that it will always be triggered before two-factor authentication plugins. The priority can be changed in the wp-config.php or .htninja file by defining the `NFW_LOGINHOOK` constant (current value is "-999999999", previous one was "999").
346
- * When creating a snapshot, File Check will exclude the Ninjascanner's cache folder if it is installed on the blog.
347
- * Many additional small fixes and adjustments.
348
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
349
-
350
- = 4.2.1 =
351
-
352
- * Fixed a bug introduced in version 4.2 where a user such as an editor could potentially be blocked while editing a post owned by another user.
353
-
354
- = 4.2 =
355
-
356
- * Added a new policy to block attempts to publish or edit a published page/post by suspicious users. This feature can be very useful to protect against attacks where hackers (authenticated or not) try to exploit zero-day vulnerabilities to inject code into posts and pages on the blog. It is disabled by default and can be enabled from the "Firewall Policies > Basic Policies > General > Block attempts to publish or edit a published post by users who do not have the right capabilities" menu.
357
- * Added a new policy to protect against username enumeration through the blog RSS feed. See "Firewall Policies > Basic Policies > Protect against username enumeration > Through the blog feed".
358
- * Added a security news feed below NinjaFirewall's widget in the WordPress Dashboard. It can be configured (or even removed) from the "Firewall Options > Miscellaneous > Dashboard Widget" menu.
359
- * Added a hook to remove all potential and annoying admin notices from third-party themes or plugins on every page of NinjaFirewall in the backend.
360
- * Fixed a bug where some firewall policies were reset to their default values when reimporting the user configuration.
361
- * Fixed a bug in the "Statistics" page where the threats percentage numbers were missing beside the three graphs.
362
- * Fixed a bug with language files: when a user selected a specific language, NinjaFirewall was still loading the language file defined in the blog settings page.
363
  * Many small fixes and adjustments.
364
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
365
-
366
- = 4.1.1 =
367
-
368
- * Improved the Full WAF installer when the server is running Litespeed or OpenLitespeed.
369
- * Fixed a potential "undefined constant NFW_IS_HTTPS" PHP warning when using the ".htninja" script with the WP Edition.
370
- * Fixed a potential issue in a multisite environment when running the firewall in WordPress WAF mode: the main site and a child site configuration could be out of sync.
371
- * Many small fixes and adjustments.
372
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
373
-
374
- = 4.1 =
375
-
376
- * Added a new feature that will alert you by email if there were an important security update available for your themes, plugins or WordPress. It is enabled by default and can be found in the "Event Notifications > Security updates > Send me an alert whenever an important security update is available for a plugin, theme or WordPress".
377
- * Fixed an issue with the "Block user accounts creation" policy: when using the WordPress "Lost your password" link, some users were wrongly blocked.
378
- * On old PHP installations (<5.4.8), it is now possible to update the security rules: NinjaFirewall will not verify their digital signature anymore because of the missing OPENSSL_ALGO_SHA256 algo required by the openssl_verify function.
379
- * Fixed "Date Range Processed" wrong timezone in the daily report.
380
- * The contextual help was reformatted and is now easier to read.
381
- * Added a dismissible welcome banner to the "Dashboard" page to explain how to use the contextual help.
382
- * Many small fixes and adjustments.
383
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
384
-
385
- = 4.0.6 =
386
-
387
- * The option to detect and block attemtps to gain administrative privileges can now be turned off from the admin dashboard. See "Firewall Policies > Basic Policies > General > Block attempts to gain administrative privileges".
388
- * Added some code to prevent users who have a caching plugin configured to cache wp-admin requests, from receiving many empty "Database changes detected" email notifications. Note that if you're using a caching plugin, we don't recommend to enable objects caching in the admin back-end because it can have bad side effects.
389
- * Several small fixes and adjustments (UI, CSS, JS and PHP code).
390
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
391
-
392
- = 4.0.5 =
393
-
394
- * The "Event Notifications" code was rewritten from scratch.
395
- * The "Full WAF" installer will rely on the `
396
- get_home_path` function rather than the `ABSPATH` constant in order to better detect if WordPress was installed into its own directory.
397
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
398
- * Small fixes and adjustments.
399
-
400
- = 4.0.4 =
401
-
402
- * Improved firewall engine: Fixed a bug in the HTML entities decoder and added ES6 unicode detection and decoding.
403
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
404
-
405
- = 4.0.3 =
406
-
407
- We have simplified the menu structure and reduced the total number of menuitems from 15 to 10 (WP Edition) and from 19 to 12 (WP+ Edition):
408
-
409
- * New menuitem: "Dashboard". It includes the former "Overview", "Statistics" and "About". In the premium WP+ Edition, it also includes "License".
410
- * New menuitem: "Monitoring". It includes "File Guard" and "File Check". In the premium WP+ Edition, it also includes "Web Filter".
411
- * New menuitem: "Logs". It includes "Firewall Log" and "Live Log". In the premium WP+ Edition, it also includes "Centralized Logging".
412
- * New menuitem: "Security Rules". It includes "Rules Updates" and "Rules Editor".
413
- * Fixed a potential "Undefined index: size" PHP notice.
414
- * Fixed missing CSS on the Login Protection page input fields.
415
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
416
- * Small fixes and adjustments.
417
-
418
- = 4.0.2 =
419
-
420
- * Added a new policy to enable the "SameSite" flag on cookies in order to protect against cross-site request forgery (CSRF) attacks. See "Firewall Policies > Advanced Policies > HTTP response headers > Force SameSite flag on all cookies".
421
- * Fixed a bug in multisite installations: when additional superadmin users were created, they were not whitelisted by the firewall because WordPress does not assign them a "capabilities" meta_key in the database.
422
- * Fixed a bug in the firewall engine sanitizing function: when dealing with an empty string, the function was returning NULL rather than returning the empty value.
423
- * Fixed a bug in the "Login Protection" menu: after changing the "GET/POST" options, reloading the page reset them to the default value.
424
- * Fixed a "Undefined variable: phpini" PHP notice in the uninstaller.
425
- * Improved the code used to detect if another instance of the firewall is running in a parent directory.
426
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
427
- * Several small fixes and adjustments.
428
-
429
- = 4.0.1 =
430
-
431
- * Fixed a bug where it was not possible to disable the "Strict-Transport-Security HTSC" advanced policy.
432
- * Fixed a potential "Undefined index: size" PHP notice that could occur during uploads.
433
- * Fixed a bug where the firewall log was wrongly displaying "DEBUG_ON" instead of "INFO" in the "Level" column.
434
- * Fixed a potential "The plugin does not have a valid header" error message when activating NinjaFirewall. On some installations, WordPress was not loading the right file.
435
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
436
-
437
- = 4.0 =
438
-
439
- * Improved NinjaFirewall overall interface and pages layout; added some simple toggle switches to replace radio buttons, better handling of error messages, cleaned up useless code etc.
440
- * All JavaScript code was 100% rewritten from scratch, including all features that rely on it (e.g., "Live Log" etc).
441
- * The installer was removed: When activating NinjaFirewall for the first time, it will automatically install itself in "WordPress WAF" mode. To upgrade to "Full WAF" mode, simply click on the corresponding link in the “Overview” page. The process is now very straightforward! A "sandbox" was added too, so that if there were a crash during the process, NinjaFirewall would undo the changes and warn the user.
442
- * When NinjaFirewall is running in "Full WAF" mode, if the PHP INI file used to load its firewall was deleted by mistake, it would automatically fallback to "WordPress WAF" mode so that the blog will remain protected.
443
- * Fixed the admin login page bug where some users had to enter their credentials twice.
444
- * The "Block the DOCUMENT_ROOT server variable in HTTP request" policy will not be enabled by default with new installations of NinjaFirewall.
445
- * NinjaFirewall will not block users with author and editor role while they are editing a post or page using either the Classic or the new Block Editor.
446
- * Added Openlitespeed detection to the "Full WAF" mode installer.
447
- * WP+ Edition (Premium): The "Access Control" pages interface was simplified: it now uses simple textarea elements where you can copy/paste your data (URL, IP, Bot and User Input) very easily. The "Geolocation" page was simplified too.
448
- * WP+ Edition (Premium): In addition to an IP address or CIDR, you can now also enter an AS number (Autonomous System number). This new feature is very helpful if you want to allow or block all IPs from an ISP or hosting company: just enter their AS number instead of hundreds of IP addresses. Syntax is "AS" + the number, e.g. "AS12345". See "Access Control > IP Access Control".
449
- * WP+ Edition (Premium): You can now add an IP to the Access Control blacklist or whitelist from the "Firewall Log" page by entering the IP in the input field below the log textarea.
450
- * WP+ Edition (Premium): When running in "WordPress WAF" mode, NinjaFirewall will automatically disable the shared memory option, because that feature is only useful when used in "Full WAF" mode (there is no benefit at all to run it in "WordPress WAF" mode).
451
- * WP+ Edition (Premium): Fixed a bug where the ISO 3166 country code was not found when using an external PHP Variable instead of the built-in GeoIP database.
452
- * WP+ Edition (Premium): Improved malicious SVG files detection.
453
- * WP+ Edition (Premium): Updated IPv4/IPv6/ASN GeoIP databases.
454
- * Many fixes and adjustments.
455
-
456
-
457
- = 3.9.1 =
458
-
459
- * Fixed potential "Nesting level too deep – recursive dependency" error message in the backend.
460
- * You can select the verbosity of the PHP backtrace attached to email notifications: low, medium or high verbosity. See "Event Notification > PHP backtrace".
461
- * Added a new policy to protect the `admin-ajax.php` script against malicious bots and scanners. See "Firewall Policy > Basic Policies > WordPress AJAX".
462
- * WP+ Edition (Premium): NinjaFirewall can check for security rules updates as often as every 15 minutes (versus one hour for the free WP Edition). See "Rules Update > Check for updates".
463
- * WP+ Edition (Premium): Added a new access control section: "User Input Access Control". It can be used to ignore or block specific user input (GET, POST and COOKIE). See "Access Control > User Input".
464
- * WP+ Edition (Premium): Role-based Access Control has been improved: it will display all user roles available on the blog, including custom ones from all third-party applications (e.g., WooCommerce, bbPress etc) so that they can be whitelisted too.
465
- * WP+ Edition (Premium): The `/` character is now allowed in the Bot Access Control.
466
- * Improved user_roles protection to prevent blocking third-party applications than may modify it when a non-administrator user is logged-in.
467
- * Many small fixes, adjustments and improvements.
468
-
469
- = 3.8.4 =
470
-
471
- * Fixed a potential "Call to undefined function wp_get_current_user()" error that may occur with plugins such as RevSlider.
472
-
473
- = 3.8.3 =
474
-
475
- * NinjaFirewall will attach a PHP backtrace to some important email notifications (see "Event Notifications > PHP backtrace").
476
- * Fixed an issue where the firewall could not connect to the database if its password contained an escaped single quote.
477
- * Fixed an issue where it was not possible to use the WordPress plugin and theme editor. This is due to a bug introduced in WordPress 4.9.2 which does not play well with PHP sessions (see https://core.trac.wordpress.org/ticket/43358).
478
- * The firewall will detect if the PHP mysqli extension is missing or is not loaded and will warn the admin in the backend.
479
- * Improved TLS detection for servers that are behind a load-balancer or reverse proxy.
480
- * Various fixes and adjustments.
481
-
482
- = 3.8.2 =
483
-
484
- * Improved the firewall engine to detect shell command obfuscation tricks using uninitialized variables (e.g. `?a=cat$foo $foo/etc/$foo/passwd$foo`).
485
- * Added a policy to disable the fatal error handler introduced in WordPress 5.1. See "Firewall Policies > Basic Policies > Disable the fatal error handler".
486
- * Disabled the firewall when running WP-CLI.
487
- * If the firewall settings were corrupted, the garbage collector would restore the last known good configuration backup. If there is no backup available, it will restore its default settings so that NinjaFirewall will keep working and protecting the site.
488
- * Various fixes and adjustments.
489
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
490
-
491
- = 3.8.1 =
492
-
493
- * Fixed a potential issue where the firewall configuration could be corrupted when attempting to restore a backup from the Firewall Options page right after updating to version 3.8.
494
-
495
- = 3.8 =
496
-
497
- * A lot of code was cleaned-up, fixed and improved as well as the whole files structure of the plugin.
498
- * Increased the height of the textarea in the "Firewall Log" and "Live Log" pages.
499
- * Fixed an issue where some caching plugins could mess with the database monitoring process which could return erroneous results.
500
- * Improved the database monitoring process for blogs that have a huge amount of rows in the "wp_usermeta" table.
501
- * The "File Check" notification will include the number of new, modified and deleted files in the body of the email.
502
- * [WP+ Edition] Added an option to disable login alerts for users whose IP address is whitelisted. See "NinjaFirewall > Event Notifications > Do not send a notification if the user is in the IP Access Control whitelist".
503
- * [WP+ Edition] Fixed an issue where, after deleting the log, it was once again deleted if the page was reloaded in the browser.
504
- * Fixed an issue where any `auto_prepend_file` directive left by another application in the .htaccess was not removed before starting the installation of NinjaFirewall on servers running LiteSpeed or Apache + mod_php.
505
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
506
-
507
- = 3.7.2 =
508
-
509
- * Added a new option to block any attempt by non-admin users to modify some important WordPress settings (e.g., by exploiting a vulnerability, using a backdoor etc). See "Firewall Policies > Basic Policies > Block attempts to modify important WordPress settings".
510
- * [WP+ Edition] Fixed a bug in the "Web Filter" callback function where the firewall was writing its log in the `/wp-content/` folder instead of `/wp-content/nfwlog/`.
511
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
512
- * Small fixes and adjustments.
513
-
514
- = 3.7.1 =
515
-
516
- * Fixed two potential PHP notices in the firewall on systems running PHP 7.2+.
517
- * Added a function to the firewall engine to detect octal-encoded values that could be used as WAF evasion techniques (e.g. `?foo=\050\141\154\145\162\164\051\050\170\163\163\051`).
518
- * If you have a complex database setup that NinjaFirewall is not able to properly retrieve, you can give it a MySQLi link identifier in the `.htninja` instead. See "Giving NinjaFirewall a MySQLi link identifier" at http://nin.link/htninja/ for more details.
519
- * Added right to left language support.
520
- * Improved HTTPS detection in the firewall.
521
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
522
- * Fixed potential "ini_set" PHP warning when a session was started by another plugin.
523
- * Many small fixes and adjustments.
524
-
525
- = 3.7 =
526
-
527
- * Added a new option to the "Live Log" page: you can apply filters in order to include or exclude files and folders. See "Live Log > Inclusion and exclusion filters".
528
- * Added a new option to the "Firewall Options" page: NinjaFirewall will automatically backup its configuration (options, policies and rules) everyday for the last 5 days so that you can restore its configuration to an earlier date if needed. See "Firewall Options > Configuration backup".
529
- * [WP+ Edition] The "IP Access Control" whitelist and blacklist can now support CIDR notation for IPv4 and IPv6 (e.g., 66.155.0.0/17, 2c0f:f248::/32).
530
- * Added a warning to the "Login Protection" page if Jetpack is installed and the XML-RPC API protection is activated.
531
- * Added a notice to the "Login Protection" page to remind that the "Authentication log" option can only work when the protection is set to "Yes, if under attack".
532
- * Fixed a potential "401 Unauthorized" HTTP response when attempting to access the XMLRPC API using a non-POST method.
533
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
534
- * Minor fixes.
535
-
536
- = 3.6.8 =
537
-
538
- * Fixed an issue where third-party plugins making use of PHP session but without properly checking the status of the current session could behave erratically.
539
-
540
- = 3.6.7 =
541
-
542
- * Added a new option to block any attempt (e.g., exploiting a vulnerability, using a backdoor etc) to create a user account. See "Firewall Policies > Basic Policies > Block user accounts creation".
543
- * The "Daily Activity Report" will include the domain name of the blog in the email subject.
544
- * Fixed a potential "Zend OPcache API " warning message when saving the "Login Protection" options.
545
- * The "Updates" menu was renamed to "Rules Update".
546
- * Improved PHP session handling.
547
- * Fixed a potential "Call to a member function close() on null" PHP error in the firewall.
548
- * [WP+ Edition] Fixed a bug in the "Web Filter" page where the button to submit the HTML form was not visible.
549
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
550
- * Minor fixes and adjustments.
551
-
552
- = 3.6.6 =
553
-
554
- * The "Statistics" page and dashboard widget will display the same values. Previously, the total of blocked threats displayed in the "Statistics" page was reset if the corresponding firewall log was deleted.
555
- * Fixed a bug in the Garbage Collector: in some cases, the firewall log was deleted a few days later than expected.
556
- * The Garbage Collector will still be able to run even if WP-Cron is disabled.
557
- * Fixed an issue introduced in WordPress 4.9.6: NinjaFirewall was not visible in the list of plugins when using WP-CLI. Note that if you want to enable/disable it from WP-CLI you will need to append the `--user` switch to your command (e.g., `$ wp plugin activate nfwplus --user=some_admin`).
558
- * Minor fixes.
559
-
560
- = 3.6.5 =
561
-
562
- * The brute-force protection will not be triggered when users click on the email confirmation link, which points to the wp-login.php script, sent by the new WordPress "Export Personal Data" feature.
563
- * The firewall will automatically detect if the blog runs on an old multisite installation where the main site options table is named "wp_1_options" instead of "wp_options".
564
-
565
- = 3.6.4 =
566
-
567
- * Fixed potential "session_status()" error with old PHP installations.
568
-
569
- = 3.6.3 =
570
-
571
- * Added the "Referrer-Policy" header (see "Firewall Policies > Advanced Policies > HTTP response headers").
572
- * Added the "418 I'm a teapot" HTTP error code (see "Firewall Options > HTTP error code to return").
573
- * Modified how PHP sessions were handled in order to prevent conflicts with third-party applications that may attempt to start a session without checking if one was already started (e.g., Piwik/Zend Framework, phpMyadmin).
574
- * Added more options to the X-XSS-Protection header; it can be set to "0", "1", "1; mode=block" or disabled (see "Firewall Policies > Advanced Policies > HTTP response headers").
575
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
576
- * Minor fixes.
577
-
578
- = 3.6.2 =
579
-
580
- * Added an option to automatically delete the firewall log(s) after a period of time (see "NinjaFirewall > Firewall Log > Auto-delete log").
581
- * Added an option to enter the admin email address during the installation process.
582
- * [WP+ Edition] The "Access Control" page was split into 5 tabs: "General", "Geolocation", "IP Access Control", "URL Access Control" and "Bot Access Control".
583
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
584
- * Many small fixes throughout the code: bugs, typos, contextual help corrections, various adjustments etc.
585
-
586
- = 3.6.1 =
587
-
588
- * Added "IP Anonymization" option. It will anonymize IP addresses in the firewall log by removing their last 3 characters. See "NinjaFirewall > Firewall Options > IP Anonymization".
589
- * Fixed a bug where the "Login Protection" wrongly applied to password protected pages.
590
- * Fixed a bug where the garbage collector cron job was not deleted when NinjaFirewall was disabled.
591
- * Added a warning that NinjaFirewall requires `unfiltered_html` capability when attempting to activate it.
592
- * [WP+ Edition] The "Uploads > Allow, but block scripts, ELF and system files" firewall policy was renamed to "Allow, but block dangerous files" and will also block dangerous SVG files. Therefore, the complete list of blocked files is now: scripts (PHP, CGI, Ruby, Python, bash/shell), C/C++ source code, binaries (MZ/PE/NE and ELF formats), system files (.htaccess, .htpasswd and PHP INI) and SVG files containing Javascript/XML events.
593
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
594
- * Minor fixes.
595
-
596
- = v3.6 =
597
-
598
- * Important: We have removed the "Anti-Malware" option from NinjaFirewall. Instead, we have now a brand new and much better antivirus plugin: NinjaScanner. You can download it from wordpress.org: https://wordpress.org/plugins/ninjascanner/
599
- * [WP+ Edition] Fixed a bug where IPs that were whitelisted in the "Access Control" page could not connect to the REST API if its access was disabled in the "Firewall Policies".
600
- * [WP+ Edition] Updated IPv4/IPv6 GeoIP databases.
601
- * Minor fixes.
602
 
2
  Contributors: nintechnet, bruandet
3
  Tags: security, firewall, malware, protection, hack, antispam, virus, scanner, hacked site, brute force, seguridad, seguranca, sicherheit, sicurezza, veiligheid, classicpress
4
  Requires at least: 4.7
5
+ Tested up to: 5.9
6
+ Stable tag: 4.5
7
  Requires PHP: 5.5
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
84
  = Low Footprint Firewall =
85
 
86
  NinjaFirewall is very fast, optimised, compact, and requires very low system resource.
87
+ See for yourself: download and install the [Code Profiler](https://wordpress.org/plugins/code-profiler/ "") plugin and compare NinjaFirewall's performance with other security plugins.
88
 
89
  = Non-Intrusive User Interface =
90
 
208
 
209
  Need more security? Take the time to explore our supercharged Premium edition: [NinjaFirewall WP+ Edition](https://nintechnet.com/ninjafirewall/wp-edition/?comparison)
210
 
211
+ = 4.5 =
212
+
213
+ * Added the possibility to enter custom HTTP response headers. See "Firewall Policies > Advanced Policies > HTTP response headers > Custom HTTP headers".
214
+ * Added the possibility to view the server's HTTP response headers. Click on the "Firewall Policies > Advanced Policies > HTTP response headers > HTTP headers test" button.
215
+ * Added a warning if WordPress is running inside a Docker image and the user wants to upgrade NinjaFirewall to Full WAF mode.
216
+ * Fixed a PHP "Undefined array key pluginzip" warning when reinstalling a plugin from a ZIP archive.
217
+ * WP+ Edition (Premium): The Access Control URI whitelist and blacklist now support permalinks.
218
+ * Fixed an issue where the daily report could be sent multiple times on some multisite installations.
219
+ * Fixed deprecated readonly() function message on WordPress 5.9.
220
+ * Fixed an issue where the firewall would wrongly send a WordPress update notification.
221
+ * WP+ Edition (Premium): Updated Stripes webhook notifications IP addresses in the Access Control section.
222
+ * Updated Charts.js library.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  * WP+ Edition (Premium): Updated GeoIP databases.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  * Many small fixes and adjustments.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
static/chart.min.js CHANGED
@@ -1,5 +1,5 @@
1
  /*!
2
- * Chart.js v3.6.1
3
  * https://www.chartjs.org
4
  * (c) 2021 Chart.js Contributors
5
  * Released under the MIT License
@@ -10,4 +10,4 @@
10
  * https://github.com/kurkle/color#readme
11
  * (c) 2020 Jukka Kurkela
12
  * Released under the MIT License
13
- */const r={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},l="0123456789ABCDEF",h=t=>l[15&t],c=t=>l[(240&t)>>4]+l[15&t],d=t=>(240&t)>>4==(15&t);function u(t){var e=function(t){return d(t.r)&&d(t.g)&&d(t.b)&&d(t.a)}(t)?h:c;return t?"#"+e(t.r)+e(t.g)+e(t.b)+(t.a<255?e(t.a):""):t}function f(t){return t+.5|0}const g=(t,e,i)=>Math.max(Math.min(t,i),e);function p(t){return g(f(2.55*t),0,255)}function m(t){return g(f(255*t),0,255)}function x(t){return g(f(t/2.55)/100,0,1)}function b(t){return g(f(100*t),0,100)}const _=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const y=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function v(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function w(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function M(t,e,i){const s=v(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function k(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=n===e?(i-s)/h+(i<s?6:0):n===i?(s-e)/h+2:(e-i)/h+4,r=60*r+.5),[0|r,l||0,a]}function S(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(m)}function P(t,e,i){return S(v,t,e,i)}function D(t){return(t%360+360)%360}function C(t){const e=y.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?p(+e[5]):m(+e[5]));const n=D(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return S(M,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return S(w,t,e,i)}(n,o,a):P(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const O={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},A={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let T;function L(t){T||(T=function(){const t={},e=Object.keys(A),i=Object.keys(O);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,O[o]);o=parseInt(A[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),T.transparent=[0,0,0,0]);const e=T[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}function R(t,e,i){if(t){let s=k(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=P(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function E(t,e){return t?Object.assign(e||{},t):t}function I(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=m(t[3]))):(e=E(t,{r:0,g:0,b:0,a:1})).a=m(e.a),e}function z(t){return"r"===t.charAt(0)?function(t){const e=_.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=255&(e[8]?p(t):255*t)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?p(i):i),s=255&(e[4]?p(s):s),n=255&(e[6]?p(n):n),{r:i,g:s,b:n,a:o}}}(t):C(t)}class F{constructor(t){if(t instanceof F)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=I(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*r[s[1]],g:255&17*r[s[2]],b:255&17*r[s[3]],a:5===o?17*r[s[4]]:255}:7!==o&&9!==o||(n={r:r[s[1]]<<4|r[s[2]],g:r[s[3]]<<4|r[s[4]],b:r[s[5]]<<4|r[s[6]],a:9===o?r[s[7]]<<4|r[s[8]]:255})),i=n||L(t)||z(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=E(this._rgb);return t&&(t.a=x(t.a)),t}set rgb(t){this._rgb=I(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${x(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):this._rgb;var t}hexString(){return this._valid?u(this._rgb):this._rgb}hslString(){return this._valid?function(t){if(!t)return;const e=k(t),i=e[0],s=b(e[1]),n=b(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${x(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):this._rgb}mix(t,e){const i=this;if(t){const s=i.rgb,n=t.rgb;let o;const a=e===o?.5:e,r=2*a-1,l=s.a-n.a,h=((r*l==-1?r:(r+l)/(1+r*l))+1)/2;o=1-h,s.r=255&h*s.r+o*n.r+.5,s.g=255&h*s.g+o*n.g+.5,s.b=255&h*s.b+o*n.b+.5,s.a=a*s.a+(1-a)*n.a,i.rgb=s}return i}clone(){return new F(this.rgb)}alpha(t){return this._rgb.a=m(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=f(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return R(this._rgb,2,t),this}darken(t){return R(this._rgb,2,-t),this}saturate(t){return R(this._rgb,1,t),this}desaturate(t){return R(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=k(t);i[0]=D(i[0]+e),i=P(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function B(t){return new F(t)}const V=t=>t instanceof CanvasGradient||t instanceof CanvasPattern;function W(t){return V(t)?t:B(t)}function N(t){return V(t)?t:B(t).saturate(.5).darken(.1).hexString()}function H(){}const j=function(){let t=0;return function(){return t++}}();function $(t){return null==t}function Y(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)}function U(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const X=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function q(t,e){return X(t)?t:e}function K(t,e){return void 0===t?e:t}const G=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Z=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function Q(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function J(t,e,i,s){let n,o,a;if(Y(t))if(o=t.length,s)for(n=o-1;n>=0;n--)e.call(i,t[n],n);else for(n=0;n<o;n++)e.call(i,t[n],n);else if(U(t))for(a=Object.keys(t),o=a.length,n=0;n<o;n++)e.call(i,t[a[n]],a[n])}function tt(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function et(t){if(Y(t))return t.map(et);if(U(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=et(t[i[n]]);return e}return t}function it(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function st(t,e,i,s){if(!it(t))return;const n=e[t],o=i[t];U(n)&&U(o)?nt(n,o,s):e[t]=et(o)}function nt(t,e,i){const s=Y(e)?e:[e],n=s.length;if(!U(t))return t;const o=(i=i||{}).merger||st;for(let a=0;a<n;++a){if(!U(e=s[a]))continue;const n=Object.keys(e);for(let s=0,a=n.length;s<a;++s)o(n[s],t,e,i)}return t}function ot(t,e){return nt(t,e,{merger:at})}function at(t,e,i){if(!it(t))return;const s=e[t],n=i[t];U(s)&&U(n)?ot(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=et(n))}function rt(t,e){const i=t.indexOf(".",e);return-1===i?t.length:i}function lt(t,e){if(""===e)return t;let i=0,s=rt(e,i);for(;t&&s>i;)t=t[e.substr(i,s-i)],i=s+1,s=rt(e,i);return t}function ht(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ct=t=>void 0!==t,dt=t=>"function"==typeof t,ut=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0},ft=Object.create(null),gt=Object.create(null);function pt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function mt(t,e,i){return"string"==typeof e?nt(pt(t,e),i):nt(pt(t,""),e)}var xt=new class{constructor(t){this.animation=void 0,this.backgroundColor="rgba(0,0,0,0.1)",this.borderColor="rgba(0,0,0,0.1)",this.color="#666",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>N(e.backgroundColor),this.hoverBorderColor=(t,e)=>N(e.borderColor),this.hoverColor=(t,e)=>N(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.describe(t)}set(t,e){return mt(this,t,e)}get(t){return pt(this,t)}describe(t,e){return mt(gt,t,e)}override(t,e){return mt(ft,t,e)}route(t,e,i,s){const n=pt(this,t),o=pt(this,i),a="_"+e;Object.defineProperties(n,{[a]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=o[s];return U(t)?Object.assign({},e,t):K(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});const bt=Math.PI,_t=2*bt,yt=_t+bt,vt=Number.POSITIVE_INFINITY,wt=bt/180,Mt=bt/2,kt=bt/4,St=2*bt/3,Pt=Math.log10,Dt=Math.sign;function Ct(t){const e=Math.round(t);t=Tt(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(Pt(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function Ot(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function At(t){return!isNaN(parseFloat(t))&&isFinite(t)}function Tt(t,e,i){return Math.abs(t-e)<i}function Lt(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function Rt(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function Et(t){return t*(bt/180)}function It(t){return t*(180/bt)}function zt(t){if(!X(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Ft(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*bt&&(o+=_t),{angle:o,distance:n}}function Bt(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Vt(t,e){return(t-e+yt)%_t-bt}function Wt(t){return(t%_t+_t)%_t}function Nt(t,e,i,s){const n=Wt(t),o=Wt(e),a=Wt(i),r=Wt(o-n),l=Wt(a-n),h=Wt(n-o),c=Wt(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function Ht(t,e,i){return Math.max(e,Math.min(i,t))}function jt(t){return Ht(t,-32768,32767)}function $t(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function Yt(t){return!t||$(t.size)||$(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Ut(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function Xt(t,e,i,s){let n=(s=s||{}).data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(n=s.data={},o=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,h,c,d,u;for(l=0;l<r;l++)if(d=i[l],null!=d&&!0!==Y(d))a=Ut(t,n,o,a,d);else if(Y(d))for(h=0,c=d.length;h<c;h++)u=d[h],null==u||Y(u)||(a=Ut(t,n,o,a,u));t.restore();const f=o.length/2;if(f>i.length){for(l=0;l<f;l++)delete n[o[l]];o.splice(0,f)}return a}function qt(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function Kt(t,e){(e=e||t.getContext("2d")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Gt(t,e,i,s){let n,o,a,r,l;const h=e.pointStyle,c=e.rotation,d=e.radius;let u=(c||0)*wt;if(h&&"object"==typeof h&&(n=h.toString(),"[object HTMLImageElement]"===n||"[object HTMLCanvasElement]"===n))return t.save(),t.translate(i,s),t.rotate(u),t.drawImage(h,-h.width/2,-h.height/2,h.width,h.height),void t.restore();if(!(isNaN(d)||d<=0)){switch(t.beginPath(),h){default:t.arc(i,s,d,0,_t),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=St,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=St,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),t.closePath();break;case"rectRounded":l=.516*d,r=d-l,o=Math.cos(u+kt)*r,a=Math.sin(u+kt)*r,t.arc(i-o,s-a,l,u-bt,u-Mt),t.arc(i+a,s-o,l,u-Mt,u),t.arc(i+o,s+a,l,u,u+Mt),t.arc(i-a,s+o,l,u+Mt,u+bt),t.closePath();break;case"rect":if(!c){r=Math.SQRT1_2*d,t.rect(i-r,s-r,2*r,2*r);break}u+=kt;case"rectRot":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+a,s-o),t.lineTo(i+o,s+a),t.lineTo(i-a,s+o),t.closePath();break;case"crossRot":u+=kt;case"cross":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"star":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o),u+=kt,o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"line":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a);break;case"dash":t.moveTo(i,s),t.lineTo(i+Math.cos(u)*d,s+Math.sin(u)*d)}t.fill(),e.borderWidth>0&&t.stroke()}}function Zt(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Qt(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function Jt(t){t.restore()}function te(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if("middle"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else"after"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function ee(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function ie(t,e,i,s,n,o={}){const a=Y(e)?e:[e],r=o.strokeWidth>0&&""!==o.strokeColor;let l,h;for(t.save(),t.font=n.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);$(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,o),l=0;l<a.length;++l)h=a[l],r&&(o.strokeColor&&(t.strokeStyle=o.strokeColor),$(o.strokeWidth)||(t.lineWidth=o.strokeWidth),t.strokeText(h,i,s,o.maxWidth)),t.fillText(h,i,s,o.maxWidth),se(t,i,s,h,o),s+=n.lineHeight;t.restore()}function se(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function ne(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-Mt,bt,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,bt,Mt,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,Mt,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-Mt,!0),t.lineTo(i+a.topLeft,s)}function oe(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const ae=(t,e,i)=>oe(t,i,(s=>t[s][e]<i)),re=(t,e,i)=>oe(t,i,(s=>t[s][e]>=i));function le(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const he=["push","pop","shift","splice","unshift"];function ce(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),he.forEach((e=>{const i="_onData"+ht(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function de(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(he.forEach((e=>{delete t[e]})),delete t._chartjs)}function ue(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}function fe(){return"undefined"!=typeof window&&"undefined"!=typeof document}function ge(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function pe(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const me=t=>window.getComputedStyle(t,null);function xe(t,e){return me(t).getPropertyValue(e)}const be=["top","right","bottom","left"];function _e(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=be[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ye(t,e){const{canvas:i,currentDevicePixelRatio:s}=e,n=me(i),o="border-box"===n.boxSizing,a=_e(n,"padding"),r=_e(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.native||t,s=i.touches,n=s&&s.length?s[0]:i,{offsetX:o,offsetY:a}=n;let r,l,h=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(o,a,i.target))r=o,l=a;else{const t=e.getBoundingClientRect();r=n.clientX-t.left,l=n.clientY-t.top,h=!0}return{x:r,y:l,box:h}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const ve=t=>Math.round(10*t)/10;function we(t,e,i,s){const n=me(t),o=_e(n,"margin"),a=pe(n.maxWidth,t,"clientWidth")||vt,r=pe(n.maxHeight,t,"clientHeight")||vt,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=ge(t);if(o){const t=o.getBoundingClientRect(),a=me(o),r=_e(a,"border","width"),l=_e(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=pe(a.maxWidth,o,"clientWidth"),n=pe(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||vt,maxHeight:n||vt}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=_e(n,"border","width"),e=_e(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=ve(Math.min(h,a,l.maxWidth)),c=ve(Math.min(c,r,l.maxHeight)),h&&!c&&(c=ve(h/2)),{width:h,height:c}}function Me(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const ke=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function Se(t,e){const i=xe(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function Pe(t,e){return"native"in t?{x:t.x,y:t.y}:ye(t,e)}function De(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&a&&o.length){const t=r._reversePixels?re:ae;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n="function"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Ce(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=De(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Oe(t,e,i,s){const n=[];if(!Zt(e,t.chartArea,t._minPadding))return n;return Ce(t,i,e,(function(t,i,o){t.inRange(e.x,e.y,s)&&n.push({element:t,datasetIndex:i,index:o})}),!0),n}function Ae(t,e,i,s,n){const o=function(t){const e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let a=Number.POSITIVE_INFINITY,r=[];if(!Zt(e,t.chartArea,t._minPadding))return r;return Ce(t,i,e,(function(i,l,h){if(s&&!i.inRange(e.x,e.y,n))return;const c=i.getCenterPoint(n);if(!Zt(c,t.chartArea,t._minPadding)&&!i.inRange(e.x,e.y,n))return;const d=o(e,c);d<a?(r=[{element:i,datasetIndex:l,index:h}],a=d):d===a&&r.push({element:i,datasetIndex:l,index:h})})),r}function Te(t,e,i,s){const n=Pe(e,t),o=[],a=i.axis,r="x"===a?"inXRange":"inYRange";let l=!1;return function(t,e){const i=t.getSortedVisibleDatasetMetas();let s,n,o;for(let t=0,a=i.length;t<a;++t){({index:s,data:n}=i[t]);for(let t=0,i=n.length;t<i;++t)o=n[t],o.skip||e(o,s,t)}}(t,((t,e,i)=>{t[r](n[a],s)&&o.push({element:t,datasetIndex:e,index:i}),t.inRange(n.x,n.y,s)&&(l=!0)})),i.intersect&&!l?[]:o}var Le={modes:{index(t,e,i,s){const n=Pe(e,t),o=i.axis||"x",a=i.intersect?Oe(t,n,o,s):Ae(t,n,o,!1,s),r=[];return a.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=a[0].index,i=t.data[e];i&&!i.skip&&r.push({element:i,datasetIndex:t.index,index:e})})),r):[]},dataset(t,e,i,s){const n=Pe(e,t),o=i.axis||"xy";let a=i.intersect?Oe(t,n,o,s):Ae(t,n,o,!1,s);if(a.length>0){const e=a[0].datasetIndex,i=t.getDatasetMeta(e).data;a=[];for(let t=0;t<i.length;++t)a.push({element:i[t],datasetIndex:e,index:t})}return a},point:(t,e,i,s)=>Oe(t,Pe(e,t),i.axis||"xy",s),nearest:(t,e,i,s)=>Ae(t,Pe(e,t),i.axis||"xy",i.intersect,s),x:(t,e,i,s)=>(i.axis="x",Te(t,e,i,s)),y:(t,e,i,s)=>(i.axis="y",Te(t,e,i,s))}};const Re=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),Ee=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function Ie(t,e){const i=(""+t).match(Re);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function ze(t,e){const i={},s=U(e),n=s?Object.keys(e):e,o=U(t)?s?i=>K(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=+o(t)||0;return i}function Fe(t){return ze(t,{top:"y",right:"x",bottom:"y",left:"x"})}function Be(t){return ze(t,["topLeft","topRight","bottomLeft","bottomRight"])}function Ve(t){const e=Fe(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function We(t,e){t=t||{},e=e||xt.font;let i=K(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=K(t.style,e.style);s&&!(""+s).match(Ee)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:K(t.family,e.family),lineHeight:Ie(K(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:K(t.weight,e.weight),string:""};return n.string=Yt(n),n}function Ne(t,e,i,s){let n,o,a,r=!0;for(n=0,o=t.length;n<o;++n)if(a=t[n],void 0!==a&&(void 0!==e&&"function"==typeof a&&(a=a(e),r=!1),void 0!==i&&Y(a)&&(a=a[i%a.length],r=!1),void 0!==a))return s&&!r&&(s.cacheable=!1),a}function He(t,e,i){const{min:s,max:n}=t,o=Z(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function je(t,e){return Object.assign(Object.create(t),e)}const $e=["left","top","right","bottom"];function Ye(t,e){return t.filter((t=>t.pos===e))}function Ue(t,e){return t.filter((t=>-1===$e.indexOf(t.pos)&&t.box.axis===e))}function Xe(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function qe(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!$e.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function Ke(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Ge(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Ze(t,e,i,s){const{pos:n,box:o}=i,a=t.maxPadding;if(!U(n)){i.size&&(t[n]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?o.height:o.width),i.size=e.size/e.count,t[n]+=i.size}o.getPadding&&Ge(a,o.getPadding());const r=Math.max(0,e.outerWidth-Ke(a,t,"left","right")),l=Math.max(0,e.outerHeight-Ke(a,t,"top","bottom")),h=r!==t.w,c=l!==t.h;return t.w=r,t.h=l,i.horizontal?{same:h,other:c}:{same:c,other:h}}function Qe(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function Je(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,Qe(r.horizontal,e));const{same:a,other:d}=Ze(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&Je(n,e,i,s)||c}function ti(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function ei(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;ct(l.start)&&(a=l.start),t.fullSize?ti(t,n.left,a,i.outerWidth-n.right-n.left,o):ti(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;ct(l.start)&&(o=l.start),t.fullSize?ti(t,o,n.top,a,i.outerHeight-n.bottom-n.top):ti(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}xt.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var ii={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=Ve(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=Xe(e.filter((t=>t.box.fullSize)),!0),s=Xe(Ye(e,"left"),!0),n=Xe(Ye(e,"right")),o=Xe(Ye(e,"top"),!0),a=Xe(Ye(e,"bottom")),r=Ue(e,"x"),l=Ue(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ye(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;J(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),u=Object.assign({},n);Ge(u,Ve(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=qe(l.concat(h),d);Je(r.fullSize,f,d,g),Je(l,f,d,g),Je(h,f,d,g)&&Je(l,f,d,g),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),ei(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,ei(r.rightAndBottom,f,d,g),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},J(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})}))}};function si(t,e=[""],i=t,s,n=(()=>t[0])){ct(s)||(s=gi("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>si([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>li(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=gi(ai(o,t),i),ct(n))return ri(t,n)?ui(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>pi(t).includes(e),ownKeys:t=>pi(t),set:(t,e,i)=>((t._storage||(t._storage=n()))[e]=i,delete t[e],delete t._keys,!0)})}function ni(t,e,i,s){const n={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:oi(t,s),setContext:e=>ni(t,e,i,s),override:n=>ni(t.override(n),e,i,s)};return new Proxy(n,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>li(t,e,(()=>function(t,e,i){const{_proxy:s,_context:n,_subProxy:o,_descriptors:a}=t;let r=s[e];dt(r)&&a.isScriptable(e)&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),ri(t,e)&&(e=ui(n._scopes,n,t,e));return e}(e,r,t,i));Y(r)&&r.length&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_descriptors:r}=i;if(ct(o.index)&&s(t))e=e[o.index%e.length];else if(U(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=ui(s,n,t,l);e.push(ni(i,o,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));ri(e,r)&&(r=ni(r,n,o&&o[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function oi(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:dt(i)?i:()=>i,isIndexable:dt(s)?s:()=>s}}const ai=(t,e)=>t?t+ht(e):e,ri=(t,e)=>U(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function li(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function hi(t,e,i){return dt(t)?t(e,i):t}const ci=(t,e)=>!0===t?e:"string"==typeof t?lt(e,t):void 0;function di(t,e,i,s){for(const n of e){const e=ci(i,n);if(e){t.add(e);const n=hi(e._fallback,i,e);if(ct(n)&&n!==i&&n!==s)return n}else if(!1===e&&ct(s)&&i!==s)return null}return!1}function ui(t,e,i,s){const n=e._rootScopes,o=hi(e._fallback,i,s),a=[...t,...n],r=new Set;r.add(s);let l=fi(r,a,i,o||i);return null!==l&&((!ct(o)||o===i||(l=fi(r,a,o,l),null!==l))&&si(Array.from(r),[""],n,o,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const n=s[e];if(Y(n)&&U(i))return i;return n}(e,i,s))))}function fi(t,e,i,s){for(;i;)i=di(t,e,i,s);return i}function gi(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ct(e))return e}}function pi(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}const mi=Number.EPSILON||1e-14,xi=(t,e)=>e<t.length&&!t[e].skip&&t[e],bi=t=>"x"===t?"y":"x";function _i(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=Bt(o,n),l=Bt(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function yi(t,e="x"){const i=bi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=xi(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=xi(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?Dt(n[a-1])!==Dt(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=xi(t,0);for(let c=0;c<s-1;++c)l=h,h=xi(t,c+1),l&&h&&(Tt(e[c],0,mi)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i="x"){const s=bi(i),n=t.length;let o,a,r,l=xi(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=xi(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function vi(t,e,i){return Math.max(Math.min(t,i),e)}function wi(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),"monotone"===e.cubicInterpolationMode)yi(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=_i(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Zt(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Zt(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=vi(n.cp1x,e.left,e.right),n.cp1y=vi(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=vi(n.cp2x,e.left,e.right),n.cp2y=vi(n.cp2y,e.top,e.bottom)))}(t,i)}const Mi=t=>0===t||1===t,ki=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*_t/i),Si=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*_t/i)+1,Pi={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*Mt),easeOutSine:t=>Math.sin(t*Mt),easeInOutSine:t=>-.5*(Math.cos(bt*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>Mi(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>Mi(t)?t:ki(t,.075,.3),easeOutElastic:t=>Mi(t)?t:Si(t,.075,.3),easeInOutElastic(t){const e=.1125;return Mi(t)?t:t<.5?.5*ki(2*t,e,.45):.5+.5*Si(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let 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:t=>1-Pi.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*Pi.easeInBounce(2*t):.5*Pi.easeOutBounce(2*t-1)+.5};function Di(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function Ci(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function Oi(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=Di(t,n,i),r=Di(n,o,i),l=Di(o,e,i),h=Di(a,r,i),c=Di(r,l,i);return Di(h,c,i)}const Ai=new Map;function Ti(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=Ai.get(i);return s||(s=new Intl.NumberFormat(t,e),Ai.set(i,s)),s}(e,i).format(t)}function Li(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ri(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function Ei(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Ii(t){return"angle"===t?{between:Nt,compare:Vt,normalize:Wt}:{between:$t,compare:(t,e)=>t-e,normalize:t=>t}}function zi({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Fi(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Ii(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Ii(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,x,b=!1,_=null;const y=()=>b||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(zi({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(zi({start:_,end:d,loop:u,count:a,style:f})),g}function Bi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Fi(s[n],t.points,e);o.length&&i.push(...o)}return i}function Vi(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Wi(t,[{start:a,end:r,loop:o}],i,e);return Wi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Wi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=Ni(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=Ni(s.setContext(je(n,{type:"segment",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),Hi(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function Ni(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function Hi(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var ji=Object.freeze({__proto__:null,easingEffects:Pi,color:W,getHoverColor:N,noop:H,uid:j,isNullOrUndef:$,isArray:Y,isObject:U,isFinite:X,finiteOrDefault:q,valueOrDefault:K,toPercentage:G,toDimension:Z,callback:Q,each:J,_elementsEqual:tt,clone:et,_merger:st,merge:nt,mergeIf:ot,_mergerIf:at,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': "'+i+'" is deprecated. Please use "'+s+'" instead')},resolveObjectKey:lt,_capitalize:ht,defined:ct,isFunction:dt,setsEqual:ut,toFontString:Yt,_measureText:Ut,_longestText:Xt,_alignPixel:qt,clearCanvas:Kt,drawPoint:Gt,_isPointInArea:Zt,clipArea:Qt,unclipArea:Jt,_steppedLineTo:te,_bezierCurveTo:ee,renderText:ie,addRoundedRectPath:ne,_lookup:oe,_lookupByKey:ae,_rlookupByKey:re,_filterBetween:le,listenArrayEvents:ce,unlistenArrayEvents:de,_arrayUnique:ue,_createResolver:si,_attachContext:ni,_descriptors:oi,splineCurve:_i,splineCurveMonotone:yi,_updateBezierControlPoints:wi,_isDomSupported:fe,_getParentNode:ge,getStyle:xe,getRelativePosition:ye,getMaximumSize:we,retinaScale:Me,supportsEventListenerOptions:ke,readUsedSize:Se,fontString:function(t,e,i){return e+" "+t+"px "+i},requestAnimFrame:t,throttled:e,debounce:i,_toLeftRightCenter:s,_alignStartEnd:n,_textX:o,_pointInLine:Di,_steppedInterpolation:Ci,_bezierInterpolation:Oi,formatNumber:Ti,toLineHeight:Ie,_readValueToProps:ze,toTRBL:Fe,toTRBLCorners:Be,toPadding:Ve,toFont:We,resolve:Ne,_addGrace:He,createContext:je,PI:bt,TAU:_t,PITAU:yt,INFINITY:vt,RAD_PER_DEG:wt,HALF_PI:Mt,QUARTER_PI:kt,TWO_THIRDS_PI:St,log10:Pt,sign:Dt,niceNum:Ct,_factorize:Ot,isNumber:At,almostEquals:Tt,almostWhole:Lt,_setMinAndMaxByKey:Rt,toRadians:Et,toDegrees:It,_decimalPlaces:zt,getAngleFromPoint:Ft,distanceBetweenPoints:Bt,_angleDiff:Vt,_normalizeAngle:Wt,_angleBetween:Nt,_limitValue:Ht,_int16Range:jt,_isBetween:$t,getRtlAdapter:Li,overrideTextDirection:Ri,restoreTextDirection:Ei,_boundSegment:Fi,_boundSegments:Bi,_computeSegments:Vi});class $i{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Yi extends $i{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const Ui={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Xi=t=>null===t||""===t;const qi=!!ke&&{passive:!0};function Ki(t,e,i){t.canvas.removeEventListener(e,i,qi)}function Gi(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function Zi(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Gi(i.addedNodes,s),e=e&&!Gi(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function Qi(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Gi(i.removedNodes,s),e=e&&!Gi(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const Ji=new Map;let ts=0;function es(){const t=window.devicePixelRatio;t!==ts&&(ts=t,Ji.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function is(t,i,s){const n=t.canvas,o=n&&ge(n);if(!o)return;const a=e(((t,e)=>{const i=o.clientWidth;s(t,e),i<o.clientWidth&&s()}),window),r=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||a(i,s)}));return r.observe(o),function(t,e){Ji.size||window.addEventListener("resize",es),Ji.set(t,e)}(t,a),r}function ss(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){Ji.delete(t),Ji.size||window.removeEventListener("resize",es)}(t)}function ns(t,i,s){const n=t.canvas,o=e((e=>{null!==t.ctx&&s(function(t,e){const i=Ui[t.type]||t.type,{x:s,y:n}=ye(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,qi)}(n,i,o),o}class os extends $i{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",Xi(n)){const e=Se(t,"width");void 0!==e&&(t.width=e)}if(Xi(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Se(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const s=i[t];$(s)?e.removeAttribute(t):e.setAttribute(t,s)}));const s=i.style||{};return Object.keys(s).forEach((t=>{e.style[t]=s[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:Zi,detach:Qi,resize:is}[e]||ns;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ss,detach:ss,resize:ss}[e]||Ki)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return we(t,e,i,s)}isAttached(t){const e=ge(t);return!(!e||!e.isConnected)}}function as(t){return!fe()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Yi:os}var rs=Object.freeze({__proto__:null,_detectPlatform:as,BasePlatform:$i,BasicPlatform:Yi,DomPlatform:os});const ls="transparent",hs={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=W(t||ls),n=s.valid&&W(e||ls);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class cs{constructor(t,e,i,s){const n=e[i];s=Ne([t.to,s,n,t.from]);const o=Ne([t.from,n,s]);this._active=!0,this._fn=t.fn||hs[t.type||typeof o],this._easing=Pi[t.easing]||Pi.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=Ne([t.to,e,s,t.from]),this._from=Ne([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}xt.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const ds=Object.keys(xt.animation);xt.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),xt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),xt.describe("animations",{_fallback:"animation"}),xt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class us{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!U(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const s=t[i];if(!U(s))return;const n={};for(const t of ds)n[t]=s[t];(Y(s.properties)&&s.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,n)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new cs(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function fs(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function gs(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function ps(t,e,i,s={}){const n=t.keys,o="single"===s.mode;let a,r,l,h;if(null!==e){for(a=0,r=n.length;a<r;++a){if(l=+n[a],l===i){if(s.all)continue;break}h=t.values[l],X(h)&&(o||0===e||Dt(e)===Dt(h))&&(e+=h)}return e}}function ms(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function xs(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function bs(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function _s(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=xs(n,c,o),u[r]=d,u._top=bs(u,a,!0,s.type),u._bottom=bs(u,a,!1,s.type)}}function ys(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function vs(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const ws=t=>"reset"===t||"none"===t,Ms=(t,e)=>e?t:Object.assign({},t);class ks{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ms(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&vs(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=K(i.xAxisID,ys(t,"x")),o=e.yAxisID=K(i.yAxisID,ys(t,"y")),a=e.rAxisID=K(i.rAxisID,ys(t,"r")),r=e.indexAxis,l=e.iAxisID=s(r,n,o,a),h=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(l),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&de(this._data,this),t._stacked&&vs(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(U(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){de(i,this);const t=this._cachedMeta;vs(t),t._parsed=[]}e&&Object.isExtensible(e)&&ce(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=ms(e.vScale,e),e.stack!==i.stack&&(s=!0,vs(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&_s(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:s}=this,{iScale:n,_stacked:o}=i,a=n.axis;let r,l,h,c=0===t&&e===s.length||i._sorted,d=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,h=s;else{h=Y(s[t])?this.parseArrayData(i,s,t,e):U(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const n=()=>null===l[a]||d&&l[a]<d[a];for(r=0;r<e;++r)i._parsed[r+t]=l=h[r],c&&(n()&&(c=!1),d=l);i._sorted=c}o&&_s(this,h)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(lt(u,a),d),y:o.parse(lt(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return ps({keys:gs(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=ps(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,o=s.length,a=this._getOtherScale(t),r=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:gs(i,!0),values:null})(e,i,this.chart),l={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:c}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(a);let d,u;function f(){u=s[d];const e=u[a.axis];return!X(u[t.axis])||h>e||c<e}for(d=0;d<o&&(f()||(this.updateRangeFromParsed(l,t,u,r),!n));++d);if(n)for(d=o-1;d>=0;--d)if(!f()){this.updateRangeFromParsed(l,t,u,r);break}return l}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s][t.axis],X(o)&&i.push(o);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?""+i.getLabelForValue(n[i.axis]):"",value:s?""+s.getLabelForValue(n[s.axis]):""}}_update(t){const e=this._cachedMeta;this.update(t||"default"),e._clip=function(t){let e,i,s,n;return U(t)?(e=t.top,i=t.right,s=t.bottom,n=t.left):e=i=s=n=t,{top:e,right:i,bottom:s,left:n,disabled:!1===t}}(K(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=fs(t,i),n=fs(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a;let l;for(i.dataset&&i.dataset.draw(t,n,a,r),l=a;l<a+r;++l){const e=s[l];e.hidden||(e.active?o.push(e):e.draw(t,n))}for(l=0;l<o.length;++l)o[l].draw(t,n)}getStyle(t,e){const i=e?"active":"default";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return je(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:"default",type:"data"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return je(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:"default",type:"dataset"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e="default",i){const s="active"===e,n=this._cachedDataOpts,o=t+"-"+e,a=n[o],r=this.enableOptionSharing&&ct(i);if(a)return Ms(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,"hover",t,""]:[t,""],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(xt.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ms(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new us(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||ws(t)||this.chart._animationsDisabled}updateElement(t,e,i,s){ws(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!ws(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,"reset")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&vs(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync(["_insertElements",this.getDataset().data.length-t,t])}_onDataPop(){this._sync(["_removeElements",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync(["_removeElements",0,1])}_onDataSplice(t,e){e&&this._sync(["_removeElements",t,e]);const i=arguments.length-2;i&&this._sync(["_insertElements",t,i])}_onDataUnshift(){this._sync(["_insertElements",0,arguments.length])}}ks.defaults={},ks.prototype.datasetElementType=null,ks.prototype.dataElementType=null;class Ss{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}hasValue(){return At(this.x)&&At(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Ss.defaults={},Ss.defaultRoutes=void 0;const Ps={values:t=>Y(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Pt(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),Ti(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(Pt(t)));return 1===s||2===s||5===s?Ps.numeric.call(this,t,e,i):""}};var Ds={formatters:Ps};function Cs(t,e){const i=t.options.ticks,s=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),n=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],o=n.length,a=n[0],r=n[o-1],l=[];if(o>s)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,l,n,o/s),l;const h=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=Ot(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(n,e,s);if(o>0){let t,i;const s=o>1?Math.round((r-a)/(o-1)):null;for(Os(e,l,h,$(s)?0:a-s,a),t=0,i=o-1;t<i;t++)Os(e,l,h,n[t],n[t+1]);return Os(e,l,h,r,$(s)?e.length:r+s),l}return Os(e,l,h),l}function Os(t,e,i,s,n){const o=K(s,0),a=Math.min(K(n,t.length),t.length);let r,l,h,c=0;for(i=Math.ceil(i),n&&(r=n-s,i=r/Math.floor(r/i)),h=o;h<0;)c++,h=Math.round(o+c*i);for(l=Math.max(o,0);l<a;l++)l===h&&(e.push(t[l]),c++,h=Math.round(o+c*i))}xt.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Ds.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),xt.route("scale.ticks","color","","color"),xt.route("scale.grid","color","","borderColor"),xt.route("scale.grid","borderColor","","borderColor"),xt.route("scale.title","color","","color"),xt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),xt.describe("scales",{_fallback:"scale"}),xt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const As=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Ts(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Ls(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Rs(t){return t.drawTicks?t.tickLength:0}function Es(t,e){if(!t.display)return 0;const i=We(t.font,e),s=Ve(t.padding);return(Y(t.text)?t.text.length:1)*i.lineHeight+s.height}function Is(t,e,i){let n=s(t);return(i&&"right"!==e||!i&&"right"===e)&&(n=(t=>"left"===t?"right":"right"===t?"left":t)(n)),n}class zs extends Ss{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=q(t,Number.POSITIVE_INFINITY),e=q(e,Number.NEGATIVE_INFINITY),i=q(i,Number.POSITIVE_INFINITY),s=q(s,Number.NEGATIVE_INFINITY),{min:q(t,i),max:q(e,s),minDefined:X(t),maxDefined:X(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;r<l;++r)e=a[r].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:q(i,q(s,i)),max:q(s,q(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){Q(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=He(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Ts(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||"auto"===o.source)&&(this.ticks=Cs(this,this.ticks),this._labelSizes=null),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){Q(this.options.afterUpdate,[this])}beforeSetDimensions(){Q(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){Q(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),Q(this.options[t],[this])}beforeDataLimits(){this._callHooks("beforeDataLimits")}determineDataLimits(){}afterDataLimits(){this._callHooks("afterDataLimits")}beforeBuildTicks(){this._callHooks("beforeBuildTicks")}buildTicks(){return[]}afterBuildTicks(){this._callHooks("afterBuildTicks")}beforeTickToLabelConversion(){Q(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=Q(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){Q(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){Q(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Ht(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Rs(t.grid)-e.padding-Es(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=It(Math.min(Math.asin(Ht((h.highest.height+6)/o,-1,1)),Math.asin(Ht(a/r,-1,1))-Math.asin(Ht(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){Q(this.options.afterCalculateLabelRotation,[this])}beforeFit(){Q(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=Es(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Rs(n)+o):(t.height=this.maxHeight,t.width=Rs(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=Et(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){Q(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e<i;e++)$(t[e].label)&&(t.splice(e,1),i--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Ts(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:i,_longestTextCache:s}=this,n=[],o=[];let a,r,l,h,c,d,u,f,g,p,m,x=0,b=0;for(a=0;a<e;++a){if(h=t[a].label,c=this._resolveTickFontOptions(a),i.font=d=c.string,u=s[d]=s[d]||{data:{},gc:[]},f=c.lineHeight,g=p=0,$(h)||Y(h)){if(Y(h))for(r=0,l=h.length;r<l;++r)m=h[r],$(m)||Y(m)||(g=Ut(i,u.data,u.gc,g,m),p+=f)}else g=Ut(i,u.data,u.gc,g,h),p=f;n.push(g),o.push(p),x=Math.max(g,x),b=Math.max(p,b)}!function(t,e){J(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(s,e);const _=n.indexOf(x),y=o.indexOf(b),v=t=>({width:n[t]||0,height:o[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:n,heights:o}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return jt(this._alignToPixels?qt(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return je(t,{tick:i,index:e,type:"tick"})}(this.getContext(),t,i))}return this.$context||(this.$context=je(this.chart.getContext(),{scale:this,type:"scale"}))}_tickSize(){const t=this.options.ticks,e=Et(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return"auto"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:o}=s,a=n.offset,r=this.isHorizontal(),l=this.ticks.length+(a?1:0),h=Rs(n),c=[],d=n.setContext(this.getContext()),u=d.drawBorder?d.borderWidth:0,f=u/2,g=function(t){return qt(i,t,u)};let p,m,x,b,_,y,v,w,M,k,S,P;if("top"===o)p=g(this.bottom),y=this.bottom-h,w=p-f,k=g(t.top)+f,P=t.bottom;else if("bottom"===o)p=g(this.top),k=t.top,P=g(t.bottom)-f,y=p+f,w=this.top+h;else if("left"===o)p=g(this.right),_=this.right-h,v=p-f,M=g(t.left)+f,S=t.right;else if("right"===o)p=g(this.left),M=t.left,S=g(t.right)-f,_=p+f,v=this.left+h;else if("x"===e){if("center"===o)p=g((t.top+t.bottom)/2+.5);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}k=t.top,P=t.bottom,y=p+f,w=y+h}else if("y"===e){if("center"===o)p=g((t.left+t.right)/2);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}_=p-f,v=_-h,M=t.left,S=t.right}const D=K(s.ticks.maxTicksLimit,l),C=Math.max(1,Math.ceil(l/D));for(m=0;m<l;m+=C){const t=n.setContext(this.getContext(m)),e=t.lineWidth,s=t.color,o=n.borderDash||[],l=t.borderDashOffset,h=t.tickWidth,d=t.tickColor,u=t.tickBorderDash||[],f=t.tickBorderDashOffset;x=Ls(this,m,a),void 0!==x&&(b=qt(i,x,e),r?_=v=M=S=b:y=w=k=P=b,c.push({tx1:_,ty1:y,tx2:v,ty2:w,x1:M,y1:k,x2:S,y2:P,width:e,color:s,borderDash:o,borderDashOffset:l,tickWidth:h,tickColor:d,tickBorderDash:u,tickBorderDashOffset:f}))}return this._ticksLength=l,this._borderValue=p,c}_computeLabelItems(t){const e=this.axis,i=this.options,{position:s,ticks:n}=i,o=this.isHorizontal(),a=this.ticks,{align:r,crossAlign:l,padding:h,mirror:c}=n,d=Rs(i.grid),u=d+h,f=c?-h:u,g=-Et(this.labelRotation),p=[];let m,x,b,_,y,v,w,M,k,S,P,D,C="middle";if("top"===s)v=this.bottom-f,w=this._getXAxisLabelAlignment();else if("bottom"===s)v=this.top+f,w=this._getXAxisLabelAlignment();else if("left"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("right"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("x"===e){if("center"===s)v=(t.top+t.bottom)/2+u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];v=this.chart.scales[t].getPixelForValue(e)+u}w=this._getXAxisLabelAlignment()}else if("y"===e){if("center"===s)y=(t.left+t.right)/2-u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];y=this.chart.scales[t].getPixelForValue(e)}w=this._getYAxisLabelAlignment(d).textAlign}"y"===e&&("start"===r?C="top":"end"===r&&(C="bottom"));const O=this._getLabelSizes();for(m=0,x=a.length;m<x;++m){b=a[m],_=b.label;const t=n.setContext(this.getContext(m));M=this.getPixelForTick(m)+n.labelOffset,k=this._resolveTickFontOptions(m),S=k.lineHeight,P=Y(_)?_.length:1;const e=P/2,i=t.color,r=t.textStrokeColor,h=t.textStrokeWidth;let d;if(o?(y=M,D="top"===s?"near"===l||0!==g?-P*S+S/2:"center"===l?-O.highest.height/2-e*S+S:-O.highest.height+S/2:"near"===l||0!==g?S/2:"center"===l?O.highest.height/2-e*S:O.highest.height-P*S,c&&(D*=-1)):(v=M,D=(1-P)*S/2),t.showLabelBackdrop){const e=Ve(t.backdropPadding),i=O.heights[m],s=O.widths[m];let n=v+D-e.top,o=y-e.left;switch(C){case"middle":n-=i/2;break;case"bottom":n-=i}switch(w){case"center":o-=s/2;break;case"right":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}p.push({rotation:g,label:_,font:k,color:i,strokeColor:r,strokeWidth:h,textOffset:D,textAlign:w,textBaseline:C,translation:[y,v],backdrop:d})}return p}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-Et(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align&&(i="right"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=qt(t,this.left,n)-n/2,l=qt(t,this.right,o)+o/2,h=c=a):(h=qt(t,this.top,n)-n/2,c=qt(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Qt(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),ie(e,o,0,t.textOffset,i,t)}i&&Jt(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:s}}=this;if(!i.display)return;const o=We(i.font),a=Ve(i.padding),r=i.align;let l=o.lineHeight/2;"bottom"===e||"center"===e||U(e)?(l+=a.bottom,Y(i.text)&&(l+=o.lineHeight*(i.text.length-1))):l+=a.top;const{titleX:h,titleY:c,maxWidth:d,rotation:u}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,x=l-a;if(t.isHorizontal()){if(f=n(s,a,l),U(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g="center"===i?(c.bottom+c.top)/2+m-e:As(t,i,e);u=l-a}else{if(U(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-x+e}else f="center"===i?(c.left+c.right)/2-x+e:As(t,i,e);g=n(s,r,o),p="left"===i?-Mt:Mt}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,l,e,r);ie(t,i.text,0,0,o,{color:i.color,maxWidth:d,rotation:u,textAlign:Is(r,e,s),textBaseline:"middle",translation:[h,c]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=K(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===zs.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return We(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Fs{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return"id"in t&&"defaults"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+"."+n;if(!n)throw new Error("class does not have id: "+t);return n in s||(s[n]=t,function(t,e,i){const s=nt(Object.create(null),[i?xt.get(i):{},xt.get(e),t.defaults]);xt.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");xt.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&xt.describe(e,t.descriptors)}(t,o,i),this.override&&xt.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in xt[s]&&(delete xt[s][i],this.override&&delete ft[i])}}var Bs=new class{constructor(){this.controllers=new Fs(ks,"datasets",!0),this.elements=new Fs(Ss,"elements"),this.plugins=new Fs(Object,"plugins"),this.scales=new Fs(zs,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):J(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=ht(t);Q(i["before"+s],[],i),e[t](i),Q(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('"'+t+'" is not a registered '+i+".");return s}};class Vs{constructor(){this._init=[]}notify(t,e,i,s){"beforeInit"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,"install"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return"destroy"===e&&(this._notify(n,t,"stop"),this._notify(this._init,t,"uninstall")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===Q(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){$(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=K(i.options&&i.options.plugins,{}),n=function(t){const e=[],i=Object.keys(Bs.plugins.items);for(let t=0;t<i.length;t++)e.push(Bs.getPlugin(i[t]));const s=t.plugins||[];for(let t=0;t<s.length;t++){const i=s[t];-1===e.indexOf(i)&&e.push(i)}return e}(i);return!1!==s||e?function(t,e,i,s){const n=[],o=t.getContext();for(let a=0;a<e.length;a++){const r=e[a],l=Ws(i[r.id],s);null!==l&&n.push({plugin:r,options:Ns(t.config,r,l,o)})}return n}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function Ws(t,e){return e||!1!==t?!0===t?{}:t:null}function Ns(t,e,i,s){const n=t.pluginScopeKeys(e),o=t.getOptionScopes(i,n);return t.createResolver(o,s,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function Hs(t,e){const i=xt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function js(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function $s(t){const e=t.options||(t.options={});e.plugins=K(e.plugins,{}),e.scales=function(t,e){const i=ft[t.type]||{scales:{}},s=e.scales||{},n=Hs(t.type,e),o=Object.create(null),a=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!U(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const r=js(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,n),h=i.scales||{};o[r]=o[r]||t,a[t]=ot(Object.create(null),[{axis:r},e,h[r],h[l]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,r=i.indexAxis||Hs(n,e),l=(ft[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),n=i[e+"AxisID"]||o[e]||e;a[n]=a[n]||Object.create(null),ot(a[n],[{axis:e},s[n],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];ot(e,[xt.scales[e.type],xt.scale])})),a}(t,e)}function Ys(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const Us=new Map,Xs=new Set;function qs(t,e){let i=Us.get(t);return i||(i=e(),Us.set(t,i),Xs.add(i)),i}const Ks=(t,e,i)=>{const s=lt(e,i);void 0!==s&&t.add(s)};class Gs{constructor(t){this._config=function(t){return(t=t||{}).data=Ys(t.data),$s(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Ys(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),$s(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return qs(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return qs(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return qs(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return qs(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>Ks(r,t,e)))),e.forEach((t=>Ks(r,s,t))),e.forEach((t=>Ks(r,ft[n]||{},t))),e.forEach((t=>Ks(r,xt,t))),e.forEach((t=>Ks(r,gt,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),Xs.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,ft[e]||{},xt.datasets[e]||{},{type:e},xt,gt]}resolveNamedOptions(t,e,i,s=[""]){const n={$shared:!0},{resolver:o,subPrefixes:a}=Zs(this._resolverCache,t,s);let r=o;if(function(t,e){const{isScriptable:i,isIndexable:s}=oi(t);for(const n of e){const e=i(n),o=s(n),a=(o||e)&&t[n];if(e&&(dt(a)||Qs(a))||o&&Y(a))return!0}return!1}(o,e)){n.$shared=!1;r=ni(o,i=dt(i)?i():i,this.createResolver(t,i,a))}for(const t of e)n[t]=r[t];return n}createResolver(t,e,i=[""],s){const{resolver:n}=Zs(this._resolverCache,t,i);return U(e)?ni(n,e,void 0,s):n}}function Zs(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:si(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const Qs=t=>U(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||dt(t[i])),!1);const Js=["top","bottom","left","right","chartArea"];function tn(t,e){return"top"===t||"bottom"===t||-1===Js.indexOf(t)&&"x"===e}function en(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function sn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),Q(i&&i.onComplete,[t],e)}function nn(t){const e=t.chart,i=e.options.animation;Q(i&&i.onProgress,[t],e)}function on(t){return fe()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const an={},rn=t=>{const e=on(t);return Object.values(an).filter((t=>t.canvas===e)).pop()};function ln(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class hn{constructor(t,e){const s=this.config=new Gs(e),n=on(t),o=rn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||as(n)),this.platform.updateConfig(s);const l=this.platform.acquireContext(n,r.aspectRatio),h=l&&l.canvas,c=h&&h.height,d=h&&h.width;this.id=j(),this.ctx=l,this.canvas=h,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Vs,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((t=>this.update(t)),r.resizeDelay||0),this._dataChanges=[],an[this.id]=this,l&&h?(a.listen(this,"complete",sn),a.listen(this,"progress",nn),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:s,_aspectRatio:n}=this;return $(t)?e&&n?n:s?i/s:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():Me(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Kt(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,Me(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),Q(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){J(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=js(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),J(n,(e=>{const n=e.options,o=n.id,a=js(o,n),r=K(n.type,e.dtype);void 0!==n.position&&tn(n.position,a)===tn(e.dposition)||(n.position=e.dposition),s[o]=!0;let l=null;if(o in i&&i[o].type===r)l=i[o];else{l=new(Bs.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[l.id]=l}l.init(n,t)})),J(s,((t,e)=>{t||delete i[e]})),J(i,(t=>{ii.configure(this,t,t.options),ii.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(en("order","index"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||Hs(o,this.options),n.order=s.order||0,n.index=i,n.label=""+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Bs.getController(o),{datasetElementType:s,dataElementType:a}=xt.datasets[o];Object.assign(e.prototype,{dataElementType:Bs.getElement(a),datasetElementType:s&&Bs.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){J(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||J(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(en("z","_idx")),this._lastEvent&&this._eventHandler(this._lastEvent,!0),this.render()}_updateScales(){J(this.scales,(t=>{ii.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);ut(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){ln(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;t<e;t++)if(!ut(s,i(t)))return;return Array.from(s).map((t=>t.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ii.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],J(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,dt(t)?t({datasetIndex:e}):t);this.notifyPlugins("afterDatasetsUpdate",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetUpdate",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins("afterDatasetUpdate",s))}render(){!1!==this.notifyPlugins("beforeRender",{cancelable:!0})&&(a.has(this)?this.attached&&!a.running(this)&&a.start(this):(this.draw(),sn({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins("beforeDraw",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins("afterDraw")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins("beforeDatasetsDraw",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&Qt(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&Jt(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}getElementsAtEventForMode(t,e,i,s){const n=Le.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=je(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);ct(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),a.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),Kt(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins("destroy"),delete an[this.id]}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};J(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){J(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},J(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+"HoverStyle"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!tt(i,e)&&(this._active=i,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e){const{_active:i=[],options:s}=this,n=s.hover,o=e;let a=[],r=!1,l=null;return"mouseout"!==t.type&&(a=this.getElementsAtEventForMode(t,n.mode,n,o),l="click"===t.type?this._lastEvent:t),this._lastEvent=null,Zt(t,this.chartArea,this._minPadding)&&(Q(s.onHover,[t,a,this],this),"mouseup"!==t.type&&"click"!==t.type&&"contextmenu"!==t.type||Q(s.onClick,[t,a,this],this)),r=!tt(a,i),(r||e)&&(this._active=a,this._updateHoverStyles(a,i,e)),this._lastEvent=l,r}}const cn=()=>J(hn.instances,(t=>t._plugins.invalidate())),dn=!0;function un(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(hn,{defaults:{enumerable:dn,value:xt},instances:{enumerable:dn,value:an},overrides:{enumerable:dn,value:ft},registry:{enumerable:dn,value:Bs},version:{enumerable:dn,value:"3.6.1"},getChart:{enumerable:dn,value:rn},register:{enumerable:dn,value:(...t)=>{Bs.add(...t),cn()}},unregister:{enumerable:dn,value:(...t)=>{Bs.remove(...t),cn()}}});class fn{constructor(t){this.options=t||{}}formats(){return un()}parse(t,e){return un()}format(t,e){return un()}add(t,e,i){return un()}diff(t,e,i){return un()}startOf(t,e,i){return un()}endOf(t,e){return un()}}fn.override=function(t){Object.assign(fn.prototype,t)};var gn={_date:fn};function pn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=ue(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(ct(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function mn(t,e,i,s){return Y(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function xn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(mn(u,d,o,h));return l}function bn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function _n(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i="left",s="right"):(e=t.base<t.y,i="bottom",s="top"),e?(n="end",o="start"):(n="start",o="end"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);"middle"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[yn(c,a,r,l)]=!0,n=h)),o[yn(n,a,r,l)]=!0,t.borderSkipped=o}function yn(t,e,i,s){var n,o,a;return s?(a=i,t=vn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=vn(t,e,i),t}function vn(t,e,i){return"start"===t?e:"end"===t?i:t}function wn(t,{inflateAmount:e},i){t.inflateAmount="auto"===e?1===i?.33:0:e}class Mn extends ks{parsePrimitiveData(t,e,i,s){return xn(t,e,i,s)}parseArrayData(t,e,i,s){return xn(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(lt(g,l),d),c.push(mn(lt(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=bn(o)?"["+o.start+", "+o.end+"]":""+s.getLabelForValue(n[s.axis]);return{label:""+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,i,s){const n="reset"===s,{index:o,_cachedMeta:{vScale:a}}=this,r=a.getBasePixel(),l=a.isHorizontal(),h=this._getRuler(),c=this.resolveDataElementOptions(e,s),d=this.getSharedOptions(c),u=this.includeOptions(s,d);this.updateSharedOptions(d,s,c);for(let c=e;c<e+i;c++){const e=this.getParsed(c),i=n||$(e[a.axis])?{base:r,head:r}:this._calculateBarValuePixels(c),f=this._calculateBarIndexPixels(c,h),g=(e._stacks||{})[a.axis],p={horizontal:l,base:i.base,enableBorderRadius:!g||bn(e._custom)||o===g._top||o===g._bottom,x:l?i.head:f.center,y:l?f.center:i.head,height:l?f.size:Math.abs(i.size),width:l?Math.abs(i.size):f.size};u&&(p.options=d||this.resolveDataElementOptions(c,t[c].active?"active":s));const m=p.options||t[c].options;_n(p,m,g,o),wn(p,m,h.ratio),this.updateElement(t[c],c,p,s)}}_getStacks(t,e){const i=this._cachedMeta.iScale,s=i.getMatchingVisibleMetas(this._type),n=i.options.stacked,o=s.length,a=[];let r,l;for(r=0;r<o;++r)if(l=s[r],l.controller.options.grouped){if(void 0!==e){const t=l.controller.getParsed(e)[l.controller._cachedMeta.vScale.axis];if($(t)||isNaN(t))continue}if((!1===n||-1===a.indexOf(l.stack)||void 0===n&&void 0===l.stack)&&a.push(l.stack),l.index===t)break}return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||pn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:i},options:{base:s,minBarLength:n}}=this,o=s||0,a=this.getParsed(t),r=a._custom,l=bn(r);let h,c,d=a[e.axis],u=0,f=i?this.applyStack(e,a,i):d;f!==d&&(u=f-d,f=d),l&&(d=r.barStart,f=r.barEnd-r.barStart,0!==d&&Dt(d)!==Dt(r.barEnd)&&(u=0),u+=d);const g=$(s)||l?u:s;let p=e.getPixelForValue(g);if(h=this.chart.getDataVisibility(t)?e.getPixelForValue(u+f):p,c=h-p,Math.abs(c)<n&&(c=function(t,e,i){return 0!==t?Dt(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(c,e,o)*n,d===o&&(p-=c/2),h=p+c),p===e.getPixelForValue(o)){const t=Dt(c)*e.getLineWidthForValue(o)/2;p+=t,c-=t}return{size:c,base:p,head:h,center:h+c/2}}_calculateBarIndexPixels(t,e){const i=e.scale,s=this.options,n=s.skipNull,o=K(s.maxBarThickness,1/0);let a,r;if(e.grouped){const i=n?this._getStackCount(t):e.stackCount,l="flex"===s.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,s,i):function(t,e,i,s){const n=i.barThickness;let o,a;return $(n)?(o=e.min*i.categoryPercentage,a=i.barPercentage):(o=n*s,a=1),{chunk:o/s,ratio:a,start:e.pixels[t]-o/2}}(t,e,s,i),h=this._getStackIndex(this.index,this._cachedMeta.stack,n?t:void 0);a=l.start+l.chunk*h+l.chunk/2,r=Math.min(o,l.chunk*l.ratio)}else a=i.getPixelForValue(this.getParsed(t)[i.axis],t),r=Math.min(o,e.min*e.ratio);return{base:a-r/2,head:a+r/2,center:a,size:r}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Mn.id="bar",Mn.defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}},Mn.overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};class kn extends ks{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,r=this.resolveDataElementOptions(e,s),l=this.getSharedOptions(r),h=this.includeOptions(s,l),c=o.axis,d=a.axis;for(let r=e;r<e+i;r++){const e=t[r],i=!n&&this.getParsed(r),l={},u=l[c]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[c]),f=l[d]=n?a.getBasePixel():a.getPixelForValue(i[d]);l.skip=isNaN(u)||isNaN(f),h&&(l.options=this.resolveDataElementOptions(r,e.active?"active":s),n&&(l.options.radius=0)),this.updateElement(e,r,l,s)}this.updateSharedOptions(l,s,r)}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return"active"!==e&&(s.radius=0),s.radius+=K(i&&i._custom,n),s}}kn.id="bubble",kn.defaults={datasetElementType:!1,dataElementType:"point",animations:{numbers:{type:"number",properties:["x","y","borderWidth","radius"]}}},kn.overrides={scales:{x:{type:"linear"},y:{type:"linear"}},plugins:{tooltip:{callbacks:{title:()=>""}}}};class Sn extends ks{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,o,a=t=>+i[t];if(U(i[t])){const{key:t="value"}=this._parsing;a=e=>+lt(i[e],t)}for(n=t,o=t+e;n<o;++n)s._parsed[n]=a(n)}}_getRotation(){return Et(this.options.rotation-90)}_getCircumference(){return Et(this.options.circumference)}_getRotationExtents(){let t=_t,e=-_t;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(G(this.options.cutout,a),1),l=this._getRingWeight(this.index),{circumference:h,rotation:c}=this._getRotationExtents(),{ratioX:d,ratioY:u,offsetX:f,offsetY:g}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<_t){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>Nt(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>Nt(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(Mt,c,u),x=g(bt,h,d),b=g(bt+Mt,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(c,h,r),p=(i.width-o)/d,m=(i.height-o)/u,x=Math.max(Math.min(p,m)/2,0),b=Z(this.options.radius,x),_=(b-Math.max(b*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=f*b,this.offsetY=g*b,s.total=this.calculateTotal(),this.outerRadius=b-_*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-_*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/_t)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,f=this.resolveDataElementOptions(e,s),g=this.getSharedOptions(f),p=this.includeOptions(s,g);let m,x=this._getRotation();for(m=0;m<e;++m)x+=this._circumference(m,n);for(m=e;m<e+i;++m){const e=this._circumference(m,n),i=t[m],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:x,endAngle:x+e,circumference:e,outerRadius:u,innerRadius:d};p&&(o.options=g||this.resolveDataElementOptions(m,i.active?"active":s)),x+=e,this.updateElement(i,m,o,s)}this.updateSharedOptions(g,s,f)}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?_t*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ti(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),"inner"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(K(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}Sn.id="doughnut",Sn.defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"},Sn.descriptors={_scriptable:t=>"spacing"!==t,_indexable:t=>"spacing"!==t},Sn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return Y(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Pn extends ks{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=function(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=Ht(Math.min(ae(r,a.axis,h).lo,i?s:ae(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?Ht(Math.max(ae(r,a.axis,c).hi+1,i?0:ae(e,l,a.getPixelForValue(c)).hi+1),n,s)-n:s-n}return{start:n,count:o}}(e,s,o);this._drawStart=a,this._drawCount=r,function(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a,_stacked:r,_dataset:l}=this._cachedMeta,h=this.resolveDataElementOptions(e,s),c=this.getSharedOptions(h),d=this.includeOptions(s,c),u=o.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,m=At(g)?g:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||n||"none"===s;let b=e>0&&this.getParsed(e-1);for(let h=e;h<e+i;++h){const e=t[h],i=this.getParsed(h),g=x?e:{},_=$(i[f]),y=g[u]=o.getPixelForValue(i[u],h),v=g[f]=n||_?a.getBasePixel():a.getPixelForValue(r?this.applyStack(a,i,r):i[f],h);g.skip=isNaN(y)||isNaN(v)||_,g.stop=h>0&&i[u]-b[u]>m,p&&(g.parsed=i,g.raw=l.data[h]),d&&(g.options=c||this.resolveDataElementOptions(h,e.active?"active":s)),x||this.updateElement(e,h,g,s),b=i}this.updateSharedOptions(c,s,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Pn.id="line",Pn.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},Pn.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class Dn extends ks{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ti(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=this.getDataset(),r=o.options.animation,l=this._cachedMeta.rScale,h=l.xCenter,c=l.yCenter,d=l.getIndexAngle(0)-.5*bt;let u,f=d;const g=360/this.countVisibleElements();for(u=0;u<e;++u)f+=this._computeAngle(u,s,g);for(u=e;u<e+i;u++){const e=t[u];let i=f,p=f+this._computeAngle(u,s,g),m=o.getDataVisibility(u)?l.getDistanceFromCenterForValue(a.data[u]):0;f=p,n&&(r.animateScale&&(m=0),r.animateRotate&&(i=p=d));const x={x:h,y:c,innerRadius:0,outerRadius:m,startAngle:i,endAngle:p,options:this.resolveDataElementOptions(u,e.active?"active":s)};this.updateElement(e,u,x,s)}}countVisibleElements(){const t=this.getDataset(),e=this._cachedMeta;let i=0;return e.data.forEach(((e,s)=>{!isNaN(t.data[s])&&this.chart.getDataVisibility(s)&&i++})),i}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?Et(this.resolveDataElementOptions(t,e).angle||i):0}}Dn.id="polarArea",Dn.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},Dn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class Cn extends Sn{}Cn.id="pie",Cn.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class On extends ks{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this.getDataset(),o=this._cachedMeta.rScale,a="reset"===s;for(let r=e;r<e+i;r++){const e=t[r],i=this.resolveDataElementOptions(r,e.active?"active":s),l=o.getPointPositionForValue(r,n.data[r]),h=a?o.xCenter:l.x,c=a?o.yCenter:l.y,d={x:h,y:c,angle:l.angle,skip:isNaN(h)||isNaN(c),options:i};this.updateElement(e,r,d,s)}}}On.id="radar",On.defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}},On.overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};class An extends Pn{}An.id="scatter",An.defaults={showLine:!1,fill:!1},An.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var Tn=Object.freeze({__proto__:null,BarController:Mn,BubbleController:kn,DoughnutController:Sn,LineController:Pn,PolarAreaController:Dn,PieController:Cn,RadarController:On,ScatterController:An});function Ln(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+Mt,s-Mt),t.closePath(),t.clip()}function Rn(t,e,i,s){const n=ze(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Ht(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Ht(n.innerStart,0,a),innerEnd:Ht(n.innerEnd,0,a)}}function En(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function In(t,e,i,s,n){const{x:o,y:a,startAngle:r,pixelMargin:l,innerRadius:h}=e,c=Math.max(e.outerRadius+s+i-l,0),d=h>0?h+s+i+l:0;let u=0;const f=n-r;if(s){const t=((h>0?h-s:0)+(c>0?c-s:0))/2;u=(f-(0!==t?f*t/(t+s):f))/2}const g=(f-Math.max(.001,f*c-i/bt)/c)/2,p=r+g+u,m=n-g-u,{outerStart:x,outerEnd:b,innerStart:_,innerEnd:y}=Rn(e,d,c,m-p),v=c-x,w=c-b,M=p+x/v,k=m-b/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(o,a,c,M,k),b>0){const e=En(w,k,o,a);t.arc(e.x,e.y,b,k,m+Mt)}const O=En(P,m,o,a);if(t.lineTo(O.x,O.y),y>0){const e=En(P,C,o,a);t.arc(e.x,e.y,y,m+Mt,C+Math.PI)}if(t.arc(o,a,d,m-y/d,p+_/d,!0),_>0){const e=En(S,D,o,a);t.arc(e.x,e.y,_,D+Math.PI,p-Mt)}const A=En(v,p,o,a);if(t.lineTo(A.x,A.y),x>0){const e=En(v,M,o,a);t.arc(e.x,e.y,x,p-Mt,M)}t.closePath()}function zn(t,e,i,s,n){const{options:o}=e,a="inner"===o.borderAlign;o.borderWidth&&(a?(t.lineWidth=2*o.borderWidth,t.lineJoin="round"):(t.lineWidth=o.borderWidth,t.lineJoin="bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&Ln(t,e,o+_t),t.beginPath(),t.arc(s,n,h,o+_t,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+_t),c=0;c<r;++c)t.stroke()}(t,e,a),a&&Ln(t,e,n),In(t,e,i,s,n),t.stroke())}class Fn extends Ss{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=Ft(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:l,outerRadius:h,circumference:c}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),d=this.options.spacing/2,u=K(c,r-a)>=_t||Nt(n,a,r),f=$t(o,l+d,h+d);return u&&f}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>_t?Math.floor(i/_t):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let o=0;if(s){o=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*o,Math.sin(e)*o),this.circumference>=bt&&(o=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const a=function(t,e,i,s){const{fullCircles:n,startAngle:o,circumference:a}=e;let r=e.endAngle;if(n){In(t,e,i,s,o+_t);for(let e=0;e<n;++e)t.fill();isNaN(a)||(r=o+a%_t,a%_t==0&&(r+=_t))}return In(t,e,i,s,r),t.fill(),r}(t,this,o,n);zn(t,this,o,n,a),t.restore()}}function Bn(t,e,i=e){t.lineCap=K(i.borderCapStyle,e.borderCapStyle),t.setLineDash(K(i.borderDash,e.borderDash)),t.lineDashOffset=K(i.borderDashOffset,e.borderDashOffset),t.lineJoin=K(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=K(i.borderWidth,e.borderWidth),t.strokeStyle=K(i.borderColor,e.borderColor)}function Vn(t,e,i){t.lineTo(i.x,i.y)}function Wn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function Nn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=Wn(n,i,s),c=function(t){return t.stepped?te:t.tension||"monotone"===t.cubicInterpolationMode?ee:Vn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function Hn(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=Wn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,x=0;const b=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function jn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?Hn:Nn}Fn.id="arc",Fn.defaults={borderAlign:"center",borderColor:"#fff",borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Fn.defaultRoutes={backgroundColor:"backgroundColor"};const $n="function"==typeof Path2D;function Yn(t,e,i,s){$n&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Bn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=jn(e);for(const r of n)Bn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class Un extends Ss{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;wi(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Vi(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Bi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?Ci:t.tension||"monotone"===t.cubicInterpolationMode?Oi:Di}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return jn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=jn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Yn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function Xn(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}Un.id="line",Un.defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0},Un.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},Un.descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};class qn extends Ss{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return Xn(this,t,"x",e)}inYRange(t,e){return Xn(this,t,"y",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Zt(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Gt(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function Kn(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps(["x","y","base","width","height"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function Gn(t,e,i,s){return t?0:Ht(e,i,s)}function Zn(t){const e=Kn(t),i=e.right-e.left,s=e.bottom-e.top,n=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=Fe(s);return{t:Gn(n.top,o.top,0,i),r:Gn(n.right,o.right,0,e),b:Gn(n.bottom,o.bottom,0,i),l:Gn(n.left,o.left,0,e)}}(t,i/2,s/2),o=function(t,e,i){const{enableBorderRadius:s}=t.getProps(["enableBorderRadius"]),n=t.options.borderRadius,o=Be(n),a=Math.min(e,i),r=t.borderSkipped,l=s||U(n);return{topLeft:Gn(!l||r.top||r.left,o.topLeft,0,a),topRight:Gn(!l||r.top||r.right,o.topRight,0,a),bottomLeft:Gn(!l||r.bottom||r.left,o.bottomLeft,0,a),bottomRight:Gn(!l||r.bottom||r.right,o.bottomRight,0,a)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:o},inner:{x:e.left+n.l,y:e.top+n.t,w:i-n.l-n.r,h:s-n.t-n.b,radius:{topLeft:Math.max(0,o.topLeft-Math.max(n.t,n.l)),topRight:Math.max(0,o.topRight-Math.max(n.t,n.r)),bottomLeft:Math.max(0,o.bottomLeft-Math.max(n.b,n.l)),bottomRight:Math.max(0,o.bottomRight-Math.max(n.b,n.r))}}}}function Qn(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&Kn(t,s);return a&&(n||$t(e,a.left,a.right))&&(o||$t(i,a.top,a.bottom))}function Jn(t,e){t.rect(e.x,e.y,e.w,e.h)}function to(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}qn.id="point",qn.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},qn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};class eo extends Ss{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=Zn(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?ne:Jn;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,to(o,e,n)),t.clip(),a(t,to(n,-e,o)),t.fillStyle=i,t.fill("evenodd")),t.beginPath(),a(t,to(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return Qn(this,t,e,i)}inXRange(t,e){return Qn(this,t,null,e)}inYRange(t,e){return Qn(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps(["x","y","base","horizontal"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return"x"===t?this.width/2:this.height/2}}eo.id="bar",eo.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},eo.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var io=Object.freeze({__proto__:null,ArcElement:Fn,LineElement:Un,PointElement:qn,BarElement:eo});function so(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function no(t){t.data.datasets.forEach((t=>{so(t)}))}var oo={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void no(t);const s=t.width;t.data.datasets.forEach(((e,n)=>{const{_data:o,indexAxis:a}=e,r=t.getDatasetMeta(n),l=o||e.data;if("y"===Ne([a,t.options.indexAxis]))return;if("line"!==r.type)return;const h=t.scales[r.xAxisID];if("linear"!==h.type&&"time"!==h.type)return;if(t.options.parsing)return;let{start:c,count:d}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Ht(ae(e,o.axis,a).lo,0,i-1)),s=h?Ht(ae(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(r,l);if(d<=(i.threshold||4*s))return void so(e);let u;switch($(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":u=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,x=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=x,o/=x;const b=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=b;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(l,c,d,s,i);break;case"min-max":u=function(t,e,i,s){let n,o,a,r,l,h,c,d,u,f,g=0,p=0;const m=[],x=e+i-1,b=t[e].x,_=t[x].x-b;for(n=e;n<e+i;++n){o=t[n],a=(o.x-b)/_*s,r=o.y;const e=0|a;if(e===l)r<u?(u=r,h=n):r>f&&(f=r,c=n),g=(p*g+o.x)/++p;else{const i=n-1;if(!$(h)&&!$(c)){const e=Math.min(h,c),s=Math.max(h,c);e!==d&&e!==i&&m.push({...t[e],x:g}),s!==d&&s!==i&&m.push({...t[s],x:g})}n>0&&i!==d&&m.push(t[i]),m.push(o),l=e,p=0,u=f=r,h=c=d=n}}return m}(l,c,d,s);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=u}))},destroy(t){no(t)}};function ao(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=K(i&&i.target,i);return void 0===s&&(s=!!e.backgroundColor),!1!==s&&null!==s&&(!0===s?"origin":s)}(t);if(U(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return X(n)&&Math.floor(n)===n?("-"!==s[0]&&"+"!==s[0]||(n=e+n),!(n===e||n<0||n>=i)&&n):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}class ro{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:_t},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function lo(t){return(t.scale||{}).getPointPositionForValue?function(t){const{scale:e,fill:i}=t,s=e.options,n=e.getLabels().length,o=[],a=s.reverse?e.max:e.min,r=s.reverse?e.min:e.max;let l,h,c;if(c="start"===i?a:"end"===i?r:U(i)?i.value:e.getBaseValue(),s.grid.circular)return h=e.getPointPositionForValue(0,a),new ro({x:h.x,y:h.y,radius:e.getDistanceFromCenterForValue(c)});for(l=0;l<n;++l)o.push(e.getPointPositionForValue(l,c));return o}(t):function(t){const{scale:e={},fill:i}=t;let s,n=null;return"start"===i?n=e.bottom:"end"===i?n=e.top:U(i)?n=e.getPixelForValue(i.value):e.getBasePixel&&(n=e.getBasePixel()),X(n)?(s=e.isHorizontal(),{x:s?n:null,y:s?null:n}):null}(t)}function ho(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function co(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=uo(o,e,"x");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function uo(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if($t(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}function fo(t){const{chart:e,fill:i,line:s}=t;if(X(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if("stack"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas("line");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(go({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)co(n,a[t],r)}return new Un({points:n,options:{}})}(t);if("shape"===i)return!0;const n=lo(t);return n instanceof ro?n:go(n,s)}function go(t,e){let i=[],s=!1;return Y(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=ho(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new Un({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function po(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!X(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function mo(t,e,i){t.beginPath(),e.path(t),t.lineTo(e.last().x,i),t.lineTo(e.first().x,i),t.closePath(),t.clip()}function xo(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=Wt(n),o=Wt(o)),{property:t,start:n,end:o}}function bo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function _o(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};"x"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function yo(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}function vo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=ho(s,r,n);const l=xo(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Bi(e,l);for(const e of h){const s=xo(i,o[e.start],o[e.end],e.loop),r=Fi(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:bo(l,s,"start",Math.max)},end:{[i]:bo(l,s,"end",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,_o(t,a,d&&xo(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():yo(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||yo(t,s,h,n)}t.closePath(),t.fill(f?"evenodd":"nonzero"),t.restore()}}function wo(t,e,i){const s=fo(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Qt(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?"angle":e.axis;t.save(),"x"===l&&o!==n&&(mo(t,s,a.top),vo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),mo(t,s,a.bottom)),vo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),Jt(t))}var Mo={id:"filler",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof Un&&(l={visible:t.isDatasetVisible(a),index:a,fill:ao(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=po(n,a,i.propagate))},beforeDraw(t,e,i){const s="beforeDraw"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&wo(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;i&&wo(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;s&&!1!==s.fill&&"beforeDatasetDraw"===i.drawTime&&wo(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const ko=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class So extends Ss{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=Q(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=We(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=ko(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:o}}=this,a=Li(o,this.left,this.width);if(this.isHorizontal()){let o=0,r=n(i,this.left+s,this.right-this.lineWidths[o]);for(const l of e)o!==l.row&&(o=l.row,r=n(i,this.left+s,this.right-this.lineWidths[o])),l.top+=this.top+t+s,l.left=a.leftForLtr(a.x(r),l.width),r+=l.width+s}else{let o=0,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height);for(const l of e)l.col!==o&&(o=l.col,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height)),l.top=r,l.left+=this.left+s,l.left=a.leftForLtr(a.x(l.left),l.width),r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Qt(t,this),this._draw(),Jt(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:a,labels:r}=t,l=xt.color,h=Li(t.rtl,this.left,this.width),c=We(r.font),{color:d,padding:u}=r,f=c.size,g=f/2;let p;this.drawTitle(),s.textAlign=h.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=c.string;const{boxWidth:m,boxHeight:x,itemHeight:b}=ko(r,f),_=this.isHorizontal(),y=this._computeTitleHeight();p=_?{x:n(a,this.left+u,this.right-i[0]),y:this.top+u+y,line:0}:{x:this.left+u,y:n(a,this.top+y+u,this.bottom-e[0].height),line:0},Ri(this.ctx,t.textDirection);const v=b+u;this.legendItems.forEach(((w,M)=>{s.strokeStyle=w.fontColor||d,s.fillStyle=w.fontColor||d;const k=s.measureText(w.text).width,S=h.textAlign(w.textAlign||(w.textAlign=r.textAlign)),P=m+g+k;let D=p.x,C=p.y;h.setWidth(this.width),_?M>0&&D+P+u>this.right&&(C=p.y+=v,p.line++,D=p.x=n(a,this.left+u,this.right-i[p.line])):M>0&&C+v>this.bottom&&(D=p.x=D+e[p.line].width+u,p.line++,C=p.y=n(a,this.top+y+u,this.bottom-e[p.line].height));!function(t,e,i){if(isNaN(m)||m<=0||isNaN(x)||x<0)return;s.save();const n=K(i.lineWidth,1);if(s.fillStyle=K(i.fillStyle,l),s.lineCap=K(i.lineCap,"butt"),s.lineDashOffset=K(i.lineDashOffset,0),s.lineJoin=K(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=K(i.strokeStyle,l),s.setLineDash(K(i.lineDash,[])),r.usePointStyle){const o={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},a=h.xPlus(t,m/2);Gt(s,o,a,e+g)}else{const o=e+Math.max((f-x)/2,0),a=h.leftForLtr(t,m),r=Be(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?ne(s,{x:a,y:o,w:m,h:x,radius:r}):s.rect(a,o,m,x),s.fill(),0!==n&&s.stroke()}s.restore()}(h.x(D),C,w),D=o(S,D+m+g,_?D+P:this.right,t.rtl),function(t,e,i){ie(s,i.text,t,e+b/2,c,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(D),C,w),_?p.x+=P+u:p.y+=v})),Ei(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=We(e.font),o=Ve(e.padding);if(!e.display)return;const a=Li(t.rtl,this.left,this.width),r=this.ctx,l=e.position,h=i.size/2,c=o.top+h;let d,u=this.left,f=this.width;if(this.isHorizontal())f=Math.max(...this.lineWidths),d=this.top+c,u=n(t.align,u,this.right-f);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);d=c+n(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const g=n(l,u,u+f);r.textAlign=a.textAlign(s(l)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=i.string,ie(r,e.text,g,d,i)}_computeTitleHeight(){const t=this.options.title,e=We(t.font),i=Ve(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if($t(t,this.left,this.right)&&$t(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],$t(t,s.left,s.left+s.width)&&$t(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if("mousemove"===t&&(e.onHover||e.onLeave))return!0;if(e.onClick&&("click"===t||"mouseup"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if("mousemove"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&Q(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&Q(e.onHover,[t,i,this],this)}else i&&Q(e.onClick,[t,i,this],this);var s,n}}var Po={id:"legend",_element:So,start(t,e,i){const s=t.legend=new So({ctx:t.ctx,options:i,chart:t});ii.configure(t,s,i),ii.addBox(t,s)},stop(t){ii.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;ii.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=Ve(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Do extends Ss{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=Y(i.text)?i.text.length:1;this._padding=Ve(i.padding);const n=s*We(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=n:this.width=n}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:o,options:a}=this,r=a.align;let l,h,c,d=0;return this.isHorizontal()?(h=n(r,i,o),c=e+t,l=o-i):("left"===a.position?(h=i+t,c=n(r,s,e),d=-.5*bt):(h=o-t,c=n(r,e,s),d=.5*bt),l=s-e),{titleX:h,titleY:c,maxWidth:l,rotation:d}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=We(e.font),n=i.lineHeight/2+this._padding.top,{titleX:o,titleY:a,maxWidth:r,rotation:l}=this._drawArgs(n);ie(t,e.text,0,0,i,{color:e.color,maxWidth:r,rotation:l,textAlign:s(e.align),textBaseline:"middle",translation:[o,a]})}}var Co={id:"title",_element:Do,start(t,e,i){!function(t,e){const i=new Do({ctx:t.ctx,options:e,chart:t});ii.configure(t,i,e),ii.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ii.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ii.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Oo=new WeakMap;var Ao={id:"subtitle",start(t,e,i){const s=new Do({ctx:t.ctx,options:i,chart:t});ii.configure(t,s,i),ii.addBox(t,s),Oo.set(t,s)},stop(t){ii.removeBox(t,Oo.get(t)),Oo.delete(t)},beforeUpdate(t,e,i){const s=Oo.get(t);ii.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const To={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=Bt(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function Lo(t,e){return e&&(Y(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Ro(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function Eo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Io(t,e){const i=t._chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=We(e.bodyFont),h=We(e.titleFont),c=We(e.footerFont),d=o.length,u=n.length,f=s.length,g=Ve(e.padding);let p=g.height,m=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),x){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-f)*l.lineHeight+(x-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*c.lineHeight+(u-1)*e.footerSpacing);let b=0;const _=function(t){m=Math.max(m,i.measureText(t).width+b)};return i.save(),i.font=h.string,J(t.title,_),i.font=l.string,J(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?a+2+e.boxPadding:0,J(s,(t=>{J(t.before,_),J(t.lines,_),J(t.after,_)})),b=0,i.font=c.string,J(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function zo(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Fo(t,e,i){const s=e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?"top":i>t.height-s/2?"bottom":"center"}(t,i);return{xAlign:e.xAlign||zo(t,e,i,s),yAlign:s}}function Bo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=Be(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:Ht(g,0,s.width-e.width),y:Ht(p,0,s.height-e.height)}}function Vo(t,e,i){const s=Ve(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function Wo(t){return Lo([],Ro(t))}function No(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Ho extends Ss{constructor(t){super(),this.opacity=0,this._active=[],this._chart=t._chart,this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this._chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new us(this._chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this._chart.getContext(),e=this,i=this._tooltipItems,je(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=Lo(a,Ro(s)),a=Lo(a,Ro(n)),a=Lo(a,Ro(o)),a}getBeforeBody(t,e){return Wo(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return J(t,(t=>{const e={before:[],lines:[],after:[]},n=No(i,t);Lo(e.before,Ro(n.beforeLabel.call(this,t))),Lo(e.lines,n.label.call(this,t)),Lo(e.after,Ro(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return Wo(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=Lo(a,Ro(s)),a=Lo(a,Ro(n)),a=Lo(a,Ro(o)),a}_createItems(t){const e=this._active,i=this._chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(Eo(this._chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),J(l,(e=>{const i=No(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=To[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Io(this,i),a=Object.assign({},t,e),r=Fo(this._chart,i,a),l=Bo(i,a,r,this._chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this._chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=Be(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Li(i.rtl,this.x,this.width);for(t.x=Vo(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=We(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,n){const o=this.labelColors[i],a=this.labelPointStyles[i],{boxHeight:r,boxWidth:l,boxPadding:h}=n,c=We(n.bodyFont),d=Vo(this,"left",n),u=s.x(d),f=r<c.lineHeight?(c.lineHeight-r)/2:0,g=e.y+f;if(n.usePointStyle){const e={radius:Math.min(l,r)/2,pointStyle:a.pointStyle,rotation:a.rotation,borderWidth:1},i=s.leftForLtr(u,l)+l/2,h=g+r/2;t.strokeStyle=n.multiKeyBackground,t.fillStyle=n.multiKeyBackground,Gt(t,e,i,h),t.strokeStyle=o.borderColor,t.fillStyle=o.backgroundColor,Gt(t,e,i,h)}else{t.lineWidth=o.borderWidth||1,t.strokeStyle=o.borderColor,t.setLineDash(o.borderDash||[]),t.lineDashOffset=o.borderDashOffset||0;const e=s.leftForLtr(u,l-h),i=s.leftForLtr(s.xPlus(u,1),l-h-2),a=Be(o.borderRadius);Object.values(a).some((t=>0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,ne(t,{x:e,y:g,w:l,h:r,radius:a}),t.fill(),t.stroke(),t.fillStyle=o.backgroundColor,t.beginPath(),ne(t,{x:i,y:g+1,w:l-2,h:r-2,radius:a}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,l,r),t.strokeRect(e,g,l,r),t.fillStyle=o.backgroundColor,t.fillRect(i,g+1,l-2,r-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=We(i.bodyFont);let d=c.lineHeight,u=0;const f=Li(i.rtl,this.x,this.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+n},p=f.textAlign(o);let m,x,b,_,y,v,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=Vo(this,p,i),e.fillStyle=i.bodyColor,J(this.beforeBody,g),u=a&&"right"!==p?"center"===o?l/2+h:l+2+h:0,_=0,v=s.length;_<v;++_){for(m=s[_],x=this.labelTextColors[_],e.fillStyle=x,J(m.before,g),b=m.lines,a&&b.length&&(this._drawColorBox(e,t,_,f,i),d=Math.max(c.lineHeight,r)),y=0,w=b.length;y<w;++y)g(b[y]),d=c.lineHeight;J(m.after,g)}u=0,d=c.lineHeight,J(this.afterBody,g),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=Li(i.rtl,this.x,this.width);for(t.x=Vo(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline="middle",o=We(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=Be(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),"top"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),"center"===o&&"right"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),"bottom"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),"center"===o&&"left"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this._chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=To[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Io(this,t),a=Object.assign({},i,this._size),r=Fo(e,t,a),l=Bo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=Ve(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ri(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),Ei(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this._chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!tt(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this.update(!0))}handleEvent(t,e){const i=this.options,s=this._active||[];let n=!1,o=[];"mouseout"!==t.type&&(o=this._chart.getElementsAtEventForMode(t,i.mode,i,e),i.reverse&&o.reverse());const a=this._positionChanged(o,t);return n=e||!tt(o,s)||a,n&&(this._active=o,(i.enabled||i.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),n}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=To[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}Ho.positioners=To;var jo={id:"tooltip",_element:Ho,positioners:To,afterInit(t,e,i){i&&(t.tooltip=new Ho({_chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip,i={tooltip:e};!1!==t.notifyPlugins("beforeTooltipDraw",i)&&(e&&e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i))},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:H,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return""},afterTitle:H,beforeBody:H,beforeLabel:H,label(t){if(this&&this.options&&"dataset"===this.options.mode)return t.label+": "+t.formattedValue||t.formattedValue;let e=t.dataset.label||"";e&&(e+=": ");const i=t.formattedValue;return $(i)||(e+=i),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:H,afterBody:H,beforeFooter:H,footer:H,afterFooter:H}},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},$o=Object.freeze({__proto__:null,Decimation:oo,Filler:Mo,Legend:Po,SubTitle:Ao,Title:Co,Tooltip:jo});function Yo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class Uo extends zs{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if($(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:Ht(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:Yo(i,t,K(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function Xo(t,e,{horizontal:i,minRotation:s}){const n=Et(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}Uo.id="category",Uo.defaults={ticks:{callback:Uo.prototype.getLabelForValue}};class qo extends zs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return $(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=Dt(s),e=Dt(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const s=function(t,e){const i=[],{bounds:s,step:n,min:o,max:a,precision:r,count:l,maxTicks:h,maxDigits:c,includeBounds:d}=t,u=n||1,f=h-1,{min:g,max:p}=e,m=!$(o),x=!$(a),b=!$(l),_=(p-g)/(c+1);let y,v,w,M,k=Ct((p-g)/f/u)*u;if(k<1e-14&&!m&&!x)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Ct(M*k/f/u)*u),$(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===s?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&x&&n&&Lt((a-o)/n,k/1e3)?(M=Math.round(Math.min((a-o)/k,h)),k=(a-o)/M,v=o,w=a):b?(v=m?o:v,w=x?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=Tt(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(zt(k),zt(v));y=Math.pow(10,$(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==o?(i.push({value:o}),v<o&&P++,Tt(Math.round((v+P*k)*y)/y,o,Xo(o,_,t))&&P++):v<o&&P++);P<M;++P)i.push({value:Math.round((v+P*k)*y)/y});return x&&d&&w!==a?i.length&&Tt(i[i.length-1].value,a,Xo(a,_,t))?i[i.length-1].value=a:i.push({value:a}):x&&w!==a||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&Rt(s,this,"value"),t.reverse?(s.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),s}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return Ti(t,this.chart.options.locale,this.options.ticks.format)}}class Ko extends qo{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?t:0,this.max=X(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=Et(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function Go(t){return 1===t/Math.pow(10,Math.floor(Pt(t)))}Ko.id="linear",Ko.defaults={ticks:{callback:Ds.formatters.numeric}};class Zo extends zs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=qo.prototype.parse.apply(this,[t,e]);if(0!==i)return X(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?Math.max(0,t):null,this.max=X(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(Pt(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(Pt(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=q(t.min,Math.pow(10,Math.floor(Pt(e.min)))),a=Math.floor(Pt(o)),r=Math.floor(o/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{n.push({value:o,major:Go(o)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),o=Math.round(r*Math.pow(10,a)*l)/l}while(a<i||a===i&&r<s);const h=q(t.max,o);return n.push({value:h,major:Go(o)}),n}({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&Rt(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":Ti(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=Pt(t),this._valueRange=Pt(this.max)-Pt(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(Pt(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function Qo(t){const e=t.ticks;if(e.display&&t.display){const t=Ve(e.backdropPadding);return K(e.font&&e.font.size,xt.font.size)+t.height}return 0}function Jo(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function ta(t){const e={l:0,r:t.width,t:0,b:t.height-t.paddingTop},i={},s=[],n=[],o=t.getLabels().length;for(let h=0;h<o;h++){const o=t.options.pointLabels.setContext(t.getPointLabelContext(h));n[h]=o.padding;const c=t.getPointPosition(h,t.drawingArea+n[h]),d=We(o.font),u=(a=t.ctx,r=d,l=Y(l=t._pointLabels[h])?l:[l],{w:Xt(a,r.string,l),h:l.length*r.lineHeight});s[h]=u;const f=t.getIndexAngle(h),g=It(f),p=Jo(g,c.x,u.w,0,180),m=Jo(g,c.y,u.h,90,270);p.start<e.l&&(e.l=p.start,i.l=f),p.end>e.r&&(e.r=p.end,i.r=f),m.start<e.t&&(e.t=m.start,i.t=f),m.end>e.b&&(e.b=m.end,i.b=f)}var a,r,l;t._setReductions(t.drawingArea,e,i),t._pointLabelItems=function(t,e,i){const s=[],n=t.getLabels().length,o=t.options,a=Qo(o),r=t.getDistanceFromCenterForValue(o.ticks.reverse?t.min:t.max);for(let o=0;o<n;o++){const n=0===o?a/2:0,l=t.getPointPosition(o,r+n+i[o]),h=It(t.getIndexAngle(o)),c=e[o],d=sa(l.y,c.h,h),u=ea(h),f=ia(l.x,c.w,u);s.push({x:l.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,s,n)}function ea(t){return 0===t||180===t?"center":t<180?"left":"right"}function ia(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function sa(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function na(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,_t);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}function oa(t){return At(t)?t:0}Zo.id="logarithmic",Zo.defaults={ticks:{callback:Ds.formatters.logarithmic,major:{enabled:!0}}};class aa extends qo{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){this.width=this.maxWidth,this.height=this.maxHeight,this.paddingTop=Qo(this.options)/2,this.xCenter=Math.floor(this.width/2),this.yCenter=Math.floor((this.height-this.paddingTop)/2),this.drawingArea=Math.min(this.height-this.paddingTop,this.width)/2}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=X(t)&&!isNaN(t)?t:0,this.max=X(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/Qo(this.options))}generateTickLabels(t){qo.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=Q(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""}))}fit(){const t=this.options;t.display&&t.pointLabels.display?ta(this):this.setCenterPoint(0,0,0,0)}_setReductions(t,e,i){let s=e.l/Math.sin(i.l),n=Math.max(e.r-this.width,0)/Math.sin(i.r),o=-e.t/Math.cos(i.t),a=-Math.max(e.b-(this.height-this.paddingTop),0)/Math.cos(i.b);s=oa(s),n=oa(n),o=oa(o),a=oa(a),this.drawingArea=Math.max(t/2,Math.min(Math.floor(t-(s+n)/2),Math.floor(t-(o+a)/2))),this.setCenterPoint(s,n,o,a)}setCenterPoint(t,e,i,s){const n=this.width-e-this.drawingArea,o=t+this.drawingArea,a=i+this.drawingArea,r=this.height-this.paddingTop-s-this.drawingArea;this.xCenter=Math.floor((o+n)/2+this.left),this.yCenter=Math.floor((a+r)/2+this.top+this.paddingTop)}getIndexAngle(t){return Wt(t*(_t/this.getLabels().length)+Et(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if($(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if($(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return je(t,{label:i,index:e,type:"pointLabel"})}(this.getContext(),t,i)}}getPointPosition(t,e){const i=this.getIndexAngle(t)-Mt;return{x:Math.cos(i)*e+this.xCenter,y:Math.sin(i)*e+this.yCenter,angle:i}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),na(this,this.getDistanceFromCenterForValue(this._endValue),e,this.getLabels().length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:i,grid:s}=e,n=this.getLabels().length;let o,a,r;if(e.pointLabels.display&&function(t,e){const{ctx:i,options:{pointLabels:s}}=t;for(let n=e-1;n>=0;n--){const e=s.setContext(t.getPointLabelContext(n)),o=We(e.font),{x:a,y:r,textAlign:l,left:h,top:c,right:d,bottom:u}=t._pointLabelItems[n],{backdropColor:f}=e;if(!$(f)){const t=Ve(e.backdropPadding);i.fillStyle=f,i.fillRect(h-t.left,c-t.top,d-h+t.width,u-c+t.height)}ie(i,t._pointLabels[n],a,r+o.lineHeight/2,o,{color:e.color,textAlign:l,textBaseline:"middle"})}}(this,n),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e){a=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),na(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,s.setContext(this.getContext(e-1)),a,n)}})),i.display){for(t.save(),o=this.getLabels().length-1;o>=0;o--){const s=i.setContext(this.getPointLabelContext(o)),{color:n,lineWidth:l}=s;l&&n&&(t.lineWidth=l,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,a=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),r=this.getPointPosition(o,a),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(r.x,r.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=We(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=Ve(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}ie(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}aa.id="radialLinear",aa.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Ds.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5}},aa.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},aa.descriptors={angleLines:{_fallback:"grid"}};const ra={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}},la=Object.keys(ra);function ha(t,e){return t-e}function ca(t,e){if($(e))return null;const i=t._adapter,{parser:s,round:n,isoWeekday:o}=t._parseOpts;let a=e;return"function"==typeof s&&(a=s(a)),X(a)||(a="string"==typeof s?i.parse(a,s):i.parse(a)),null===a?null:(n&&(a="week"!==n||!At(o)&&!0!==o?i.startOf(a,n):i.startOf(a,"isoWeek",o)),+a)}function da(t,e,i,s){const n=la.length;for(let o=la.indexOf(t);o<n-1;++o){const t=ra[la[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return la[o]}return la[n-1]}function ua(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=oe(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function fa(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class ga extends zs{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new gn._date(t.adapters.date);ot(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:ca(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:a}=this.getUserBounds();function r(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),a||isNaN(t.max)||(n=Math.max(n,t.max))}o&&a||(r(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||r(this.getMinMax(!1))),s=X(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=X(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=le(s,n,this.max);return this._unit=e.unit||(i.autoSkip?da(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=la.length-1;o>=la.indexOf(i);o--){const i=la[o];if(ra[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return la[i?la.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=la.indexOf(t)+1,i=la.length;e<i;++e)if(ra[la[e]].common)return la[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),fa(this,o,this._majorUnit)}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Ht(s,0,o),n=Ht(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||da(n.minUnit,e,i,this._getLabelCapacity(e)),a=K(n.stepSize,1),r="week"===o&&n.isoWeekday,l=At(r)||!0===r,h={};let c,d,u=e;if(l&&(u=+t.startOf(u,"isoWeek",r)),u=+t.startOf(u,l?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const f="data"===s.ticks.source&&this.getDataTimestamps();for(c=u,d=0;c<i;c=+t.add(c,a,o),d++)ua(h,c,f);return c!==i&&"ticks"!==s.bounds&&1!==d||ua(h,c,f),Object.keys(h).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],c=i[e],d=r&&h&&c&&c.major,u=this._adapter.format(t,s||(d?h:l)),f=n.ticks.callback;return f?Q(f,[u,e,i],this):u}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=Et(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,fa(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(ca(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return ue(t.sort(ha))}}function pa(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=ae(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=ae(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}ga.id="time",ga.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ma extends ga{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=pa(e,this.min),this._tableRange=pa(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(pa(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return pa(this._table,i*this._tableRange+this._minPos,!0)}}ma.id="timeseries",ma.defaults=ga.defaults;var xa=Object.freeze({__proto__:null,CategoryScale:Uo,LinearScale:Ko,LogarithmicScale:Zo,RadialLinearScale:aa,TimeScale:ga,TimeSeriesScale:ma});return hn.register(Tn,xa,io,$o),hn.helpers={...ji},hn._adapters=gn,hn.Animation=cs,hn.Animations=us,hn.animator=a,hn.controllers=Bs.controllers.items,hn.DatasetController=ks,hn.Element=Ss,hn.elements=io,hn.Interaction=Le,hn.layouts=ii,hn.platforms=rs,hn.Scale=zs,hn.Ticks=Ds,Object.assign(hn,Tn,xa,io,$o,rs),hn.Chart=hn,"undefined"!=typeof window&&(window.Chart=hn),hn}));
1
  /*!
2
+ * Chart.js v3.7.0
3
  * https://www.chartjs.org
4
  * (c) 2021 Chart.js Contributors
5
  * Released under the MIT License
10
  * https://github.com/kurkle/color#readme
11
  * (c) 2020 Jukka Kurkela
12
  * Released under the MIT License
13
+ */const r={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},l="0123456789ABCDEF",h=t=>l[15&t],c=t=>l[(240&t)>>4]+l[15&t],d=t=>(240&t)>>4==(15&t);function u(t){var e=function(t){return d(t.r)&&d(t.g)&&d(t.b)&&d(t.a)}(t)?h:c;return t?"#"+e(t.r)+e(t.g)+e(t.b)+(t.a<255?e(t.a):""):t}function f(t){return t+.5|0}const g=(t,e,i)=>Math.max(Math.min(t,i),e);function p(t){return g(f(2.55*t),0,255)}function m(t){return g(f(255*t),0,255)}function x(t){return g(f(t/2.55)/100,0,1)}function b(t){return g(f(100*t),0,100)}const _=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const y=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function v(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function w(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function M(t,e,i){const s=v(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function k(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=n===e?(i-s)/h+(i<s?6:0):n===i?(s-e)/h+2:(e-i)/h+4,r=60*r+.5),[0|r,l||0,a]}function S(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(m)}function P(t,e,i){return S(v,t,e,i)}function D(t){return(t%360+360)%360}function C(t){const e=y.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?p(+e[5]):m(+e[5]));const n=D(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return S(M,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return S(w,t,e,i)}(n,o,a):P(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const O={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},A={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let T;function L(t){T||(T=function(){const t={},e=Object.keys(A),i=Object.keys(O);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,O[o]);o=parseInt(A[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),T.transparent=[0,0,0,0]);const e=T[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}function R(t,e,i){if(t){let s=k(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=P(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function E(t,e){return t?Object.assign(e||{},t):t}function I(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=m(t[3]))):(e=E(t,{r:0,g:0,b:0,a:1})).a=m(e.a),e}function z(t){return"r"===t.charAt(0)?function(t){const e=_.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=255&(e[8]?p(t):255*t)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?p(i):i),s=255&(e[4]?p(s):s),n=255&(e[6]?p(n):n),{r:i,g:s,b:n,a:o}}}(t):C(t)}class F{constructor(t){if(t instanceof F)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=I(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*r[s[1]],g:255&17*r[s[2]],b:255&17*r[s[3]],a:5===o?17*r[s[4]]:255}:7!==o&&9!==o||(n={r:r[s[1]]<<4|r[s[2]],g:r[s[3]]<<4|r[s[4]],b:r[s[5]]<<4|r[s[6]],a:9===o?r[s[7]]<<4|r[s[8]]:255})),i=n||L(t)||z(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=E(this._rgb);return t&&(t.a=x(t.a)),t}set rgb(t){this._rgb=I(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${x(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):this._rgb;var t}hexString(){return this._valid?u(this._rgb):this._rgb}hslString(){return this._valid?function(t){if(!t)return;const e=k(t),i=e[0],s=b(e[1]),n=b(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${x(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):this._rgb}mix(t,e){const i=this;if(t){const s=i.rgb,n=t.rgb;let o;const a=e===o?.5:e,r=2*a-1,l=s.a-n.a,h=((r*l==-1?r:(r+l)/(1+r*l))+1)/2;o=1-h,s.r=255&h*s.r+o*n.r+.5,s.g=255&h*s.g+o*n.g+.5,s.b=255&h*s.b+o*n.b+.5,s.a=a*s.a+(1-a)*n.a,i.rgb=s}return i}clone(){return new F(this.rgb)}alpha(t){return this._rgb.a=m(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=f(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return R(this._rgb,2,t),this}darken(t){return R(this._rgb,2,-t),this}saturate(t){return R(this._rgb,1,t),this}desaturate(t){return R(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=k(t);i[0]=D(i[0]+e),i=P(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function B(t){return new F(t)}const V=t=>t instanceof CanvasGradient||t instanceof CanvasPattern;function W(t){return V(t)?t:B(t)}function N(t){return V(t)?t:B(t).saturate(.5).darken(.1).hexString()}function H(){}const j=function(){let t=0;return function(){return t++}}();function $(t){return null==t}function Y(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)}function U(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const X=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function q(t,e){return X(t)?t:e}function K(t,e){return void 0===t?e:t}const G=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Z=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function J(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function Q(t,e,i,s){let n,o,a;if(Y(t))if(o=t.length,s)for(n=o-1;n>=0;n--)e.call(i,t[n],n);else for(n=0;n<o;n++)e.call(i,t[n],n);else if(U(t))for(a=Object.keys(t),o=a.length,n=0;n<o;n++)e.call(i,t[a[n]],a[n])}function tt(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function et(t){if(Y(t))return t.map(et);if(U(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=et(t[i[n]]);return e}return t}function it(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function st(t,e,i,s){if(!it(t))return;const n=e[t],o=i[t];U(n)&&U(o)?nt(n,o,s):e[t]=et(o)}function nt(t,e,i){const s=Y(e)?e:[e],n=s.length;if(!U(t))return t;const o=(i=i||{}).merger||st;for(let a=0;a<n;++a){if(!U(e=s[a]))continue;const n=Object.keys(e);for(let s=0,a=n.length;s<a;++s)o(n[s],t,e,i)}return t}function ot(t,e){return nt(t,e,{merger:at})}function at(t,e,i){if(!it(t))return;const s=e[t],n=i[t];U(s)&&U(n)?ot(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=et(n))}function rt(t,e){const i=t.indexOf(".",e);return-1===i?t.length:i}function lt(t,e){if(""===e)return t;let i=0,s=rt(e,i);for(;t&&s>i;)t=t[e.substr(i,s-i)],i=s+1,s=rt(e,i);return t}function ht(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ct=t=>void 0!==t,dt=t=>"function"==typeof t,ut=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function ft(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const gt=Object.create(null),pt=Object.create(null);function mt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function xt(t,e,i){return"string"==typeof e?nt(mt(t,e),i):nt(mt(t,""),e)}var bt=new class{constructor(t){this.animation=void 0,this.backgroundColor="rgba(0,0,0,0.1)",this.borderColor="rgba(0,0,0,0.1)",this.color="#666",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>N(e.backgroundColor),this.hoverBorderColor=(t,e)=>N(e.borderColor),this.hoverColor=(t,e)=>N(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return xt(this,t,e)}get(t){return mt(this,t)}describe(t,e){return xt(pt,t,e)}override(t,e){return xt(gt,t,e)}route(t,e,i,s){const n=mt(this,t),o=mt(this,i),a="_"+e;Object.defineProperties(n,{[a]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=o[s];return U(t)?Object.assign({},e,t):K(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});const _t=Math.PI,yt=2*_t,vt=yt+_t,wt=Number.POSITIVE_INFINITY,Mt=_t/180,kt=_t/2,St=_t/4,Pt=2*_t/3,Dt=Math.log10,Ct=Math.sign;function Ot(t){const e=Math.round(t);t=Lt(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(Dt(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function At(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function Tt(t){return!isNaN(parseFloat(t))&&isFinite(t)}function Lt(t,e,i){return Math.abs(t-e)<i}function Rt(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function Et(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function It(t){return t*(_t/180)}function zt(t){return t*(180/_t)}function Ft(t){if(!X(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Bt(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*_t&&(o+=yt),{angle:o,distance:n}}function Vt(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Wt(t,e){return(t-e+vt)%yt-_t}function Nt(t){return(t%yt+yt)%yt}function Ht(t,e,i,s){const n=Nt(t),o=Nt(e),a=Nt(i),r=Nt(o-n),l=Nt(a-n),h=Nt(n-o),c=Nt(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function jt(t,e,i){return Math.max(e,Math.min(i,t))}function $t(t){return jt(t,-32768,32767)}function Yt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function Ut(t){return!t||$(t.size)||$(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Xt(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function qt(t,e,i,s){let n=(s=s||{}).data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(n=s.data={},o=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,h,c,d,u;for(l=0;l<r;l++)if(d=i[l],null!=d&&!0!==Y(d))a=Xt(t,n,o,a,d);else if(Y(d))for(h=0,c=d.length;h<c;h++)u=d[h],null==u||Y(u)||(a=Xt(t,n,o,a,u));t.restore();const f=o.length/2;if(f>i.length){for(l=0;l<f;l++)delete n[o[l]];o.splice(0,f)}return a}function Kt(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function Gt(t,e){(e=e||t.getContext("2d")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Zt(t,e,i,s){let n,o,a,r,l;const h=e.pointStyle,c=e.rotation,d=e.radius;let u=(c||0)*Mt;if(h&&"object"==typeof h&&(n=h.toString(),"[object HTMLImageElement]"===n||"[object HTMLCanvasElement]"===n))return t.save(),t.translate(i,s),t.rotate(u),t.drawImage(h,-h.width/2,-h.height/2,h.width,h.height),void t.restore();if(!(isNaN(d)||d<=0)){switch(t.beginPath(),h){default:t.arc(i,s,d,0,yt),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),t.closePath();break;case"rectRounded":l=.516*d,r=d-l,o=Math.cos(u+St)*r,a=Math.sin(u+St)*r,t.arc(i-o,s-a,l,u-_t,u-kt),t.arc(i+a,s-o,l,u-kt,u),t.arc(i+o,s+a,l,u,u+kt),t.arc(i-a,s+o,l,u+kt,u+_t),t.closePath();break;case"rect":if(!c){r=Math.SQRT1_2*d,t.rect(i-r,s-r,2*r,2*r);break}u+=St;case"rectRot":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+a,s-o),t.lineTo(i+o,s+a),t.lineTo(i-a,s+o),t.closePath();break;case"crossRot":u+=St;case"cross":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"star":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o),u+=St,o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"line":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a);break;case"dash":t.moveTo(i,s),t.lineTo(i+Math.cos(u)*d,s+Math.sin(u)*d)}t.fill(),e.borderWidth>0&&t.stroke()}}function Jt(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Qt(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function te(t){t.restore()}function ee(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if("middle"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else"after"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function ie(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function se(t,e,i,s,n,o={}){const a=Y(e)?e:[e],r=o.strokeWidth>0&&""!==o.strokeColor;let l,h;for(t.save(),t.font=n.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);$(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,o),l=0;l<a.length;++l)h=a[l],r&&(o.strokeColor&&(t.strokeStyle=o.strokeColor),$(o.strokeWidth)||(t.lineWidth=o.strokeWidth),t.strokeText(h,i,s,o.maxWidth)),t.fillText(h,i,s,o.maxWidth),ne(t,i,s,h,o),s+=n.lineHeight;t.restore()}function ne(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function oe(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-kt,_t,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,_t,kt,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,kt,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-kt,!0),t.lineTo(i+a.topLeft,s)}function ae(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const re=(t,e,i)=>ae(t,i,(s=>t[s][e]<i)),le=(t,e,i)=>ae(t,i,(s=>t[s][e]>=i));function he(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ce=["push","pop","shift","splice","unshift"];function de(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ce.forEach((e=>{const i="_onData"+ht(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function ue(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(ce.forEach((e=>{delete t[e]})),delete t._chartjs)}function fe(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}function ge(){return"undefined"!=typeof window&&"undefined"!=typeof document}function pe(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function me(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const xe=t=>window.getComputedStyle(t,null);function be(t,e){return xe(t).getPropertyValue(e)}const _e=["top","right","bottom","left"];function ye(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=_e[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ve(t,e){const{canvas:i,currentDevicePixelRatio:s}=e,n=xe(i),o="border-box"===n.boxSizing,a=ye(n,"padding"),r=ye(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.native||t,s=i.touches,n=s&&s.length?s[0]:i,{offsetX:o,offsetY:a}=n;let r,l,h=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(o,a,i.target))r=o,l=a;else{const t=e.getBoundingClientRect();r=n.clientX-t.left,l=n.clientY-t.top,h=!0}return{x:r,y:l,box:h}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const we=t=>Math.round(10*t)/10;function Me(t,e,i,s){const n=xe(t),o=ye(n,"margin"),a=me(n.maxWidth,t,"clientWidth")||wt,r=me(n.maxHeight,t,"clientHeight")||wt,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=pe(t);if(o){const t=o.getBoundingClientRect(),a=xe(o),r=ye(a,"border","width"),l=ye(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=me(a.maxWidth,o,"clientWidth"),n=me(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||wt,maxHeight:n||wt}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=ye(n,"border","width"),e=ye(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=we(Math.min(h,a,l.maxWidth)),c=we(Math.min(c,r,l.maxHeight)),h&&!c&&(c=we(h/2)),{width:h,height:c}}function ke(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const Se=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function Pe(t,e){const i=be(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function De(t,e){return"native"in t?{x:t.x,y:t.y}:ve(t,e)}function Ce(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&"r"!==e&&a&&o.length){const t=r._reversePixels?le:re;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n="function"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Oe(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=Ce(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Ae(t,e,i,s){const n=[];if(!Jt(e,t.chartArea,t._minPadding))return n;return Oe(t,i,e,(function(t,i,o){t.inRange(e.x,e.y,s)&&n.push({element:t,datasetIndex:i,index:o})}),!0),n}function Te(t,e,i,s,n){let o=[];const a=function(t){const e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let r=Number.POSITIVE_INFINITY;return Oe(t,i,e,(function(i,l,h){const c=i.inRange(e.x,e.y,n);if(s&&!c)return;const d=i.getCenterPoint(n);if(!Jt(d,t.chartArea,t._minPadding)&&!c)return;const u=a(e,d);u<r?(o=[{element:i,datasetIndex:l,index:h}],r=u):u===r&&o.push({element:i,datasetIndex:l,index:h})})),o}function Le(t,e,i,s,n){return Jt(e,t.chartArea,t._minPadding)?"r"!==i||s?Te(t,e,i,s,n):function(t,e,i,s){let n=[];return Oe(t,i,e,(function(t,i,o){const{startAngle:a,endAngle:r}=t.getProps(["startAngle","endAngle"],s),{angle:l}=Bt(t,{x:e.x,y:e.y});Ht(l,a,r)&&n.push({element:t,datasetIndex:i,index:o})})),n}(t,e,i,n):[]}function Re(t,e,i,s){const n=De(e,t),o=[],a=i.axis,r="x"===a?"inXRange":"inYRange";let l=!1;return function(t,e){const i=t.getSortedVisibleDatasetMetas();let s,n,o;for(let t=0,a=i.length;t<a;++t){({index:s,data:n}=i[t]);for(let t=0,i=n.length;t<i;++t)o=n[t],o.skip||e(o,s,t)}}(t,((t,e,i)=>{t[r](n[a],s)&&o.push({element:t,datasetIndex:e,index:i}),t.inRange(n.x,n.y,s)&&(l=!0)})),i.intersect&&!l?[]:o}var Ee={modes:{index(t,e,i,s){const n=De(e,t),o=i.axis||"x",a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s),r=[];return a.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=a[0].index,i=t.data[e];i&&!i.skip&&r.push({element:i,datasetIndex:t.index,index:e})})),r):[]},dataset(t,e,i,s){const n=De(e,t),o=i.axis||"xy";let a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s);if(a.length>0){const e=a[0].datasetIndex,i=t.getDatasetMeta(e).data;a=[];for(let t=0;t<i.length;++t)a.push({element:i[t],datasetIndex:e,index:t})}return a},point:(t,e,i,s)=>Ae(t,De(e,t),i.axis||"xy",s),nearest:(t,e,i,s)=>Le(t,De(e,t),i.axis||"xy",i.intersect,s),x:(t,e,i,s)=>Re(t,e,{axis:"x",intersect:i.intersect},s),y:(t,e,i,s)=>Re(t,e,{axis:"y",intersect:i.intersect},s)}};const Ie=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),ze=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function Fe(t,e){const i=(""+t).match(Ie);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function Be(t,e){const i={},s=U(e),n=s?Object.keys(e):e,o=U(t)?s?i=>K(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=+o(t)||0;return i}function Ve(t){return Be(t,{top:"y",right:"x",bottom:"y",left:"x"})}function We(t){return Be(t,["topLeft","topRight","bottomLeft","bottomRight"])}function Ne(t){const e=Ve(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function He(t,e){t=t||{},e=e||bt.font;let i=K(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=K(t.style,e.style);s&&!(""+s).match(ze)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:K(t.family,e.family),lineHeight:Fe(K(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:K(t.weight,e.weight),string:""};return n.string=Ut(n),n}function je(t,e,i,s){let n,o,a,r=!0;for(n=0,o=t.length;n<o;++n)if(a=t[n],void 0!==a&&(void 0!==e&&"function"==typeof a&&(a=a(e),r=!1),void 0!==i&&Y(a)&&(a=a[i%a.length],r=!1),void 0!==a))return s&&!r&&(s.cacheable=!1),a}function $e(t,e,i){const{min:s,max:n}=t,o=Z(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function Ye(t,e){return Object.assign(Object.create(t),e)}const Ue=["left","top","right","bottom"];function Xe(t,e){return t.filter((t=>t.pos===e))}function qe(t,e){return t.filter((t=>-1===Ue.indexOf(t.pos)&&t.box.axis===e))}function Ke(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Ge(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Ue.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function Ze(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Je(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Qe(t,e,i,s){const{pos:n,box:o}=i,a=t.maxPadding;if(!U(n)){i.size&&(t[n]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?o.height:o.width),i.size=e.size/e.count,t[n]+=i.size}o.getPadding&&Je(a,o.getPadding());const r=Math.max(0,e.outerWidth-Ze(a,t,"left","right")),l=Math.max(0,e.outerHeight-Ze(a,t,"top","bottom")),h=r!==t.w,c=l!==t.h;return t.w=r,t.h=l,i.horizontal?{same:h,other:c}:{same:c,other:h}}function ti(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function ei(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,ti(r.horizontal,e));const{same:a,other:d}=Qe(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&ei(n,e,i,s)||c}function ii(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function si(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;ct(l.start)&&(a=l.start),t.fullSize?ii(t,n.left,a,i.outerWidth-n.right-n.left,o):ii(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;ct(l.start)&&(o=l.start),t.fullSize?ii(t,o,n.top,a,i.outerHeight-n.bottom-n.top):ii(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}bt.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var ni={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=Ne(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=Ke(e.filter((t=>t.box.fullSize)),!0),s=Ke(Xe(e,"left"),!0),n=Ke(Xe(e,"right")),o=Ke(Xe(e,"top"),!0),a=Ke(Xe(e,"bottom")),r=qe(e,"x"),l=qe(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Xe(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;Q(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),u=Object.assign({},n);Je(u,Ne(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=Ge(l.concat(h),d);ei(r.fullSize,f,d,g),ei(l,f,d,g),ei(h,f,d,g)&&ei(l,f,d,g),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),si(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,si(r.rightAndBottom,f,d,g),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},Q(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})}))}};function oi(t,e=[""],i=t,s,n=(()=>t[0])){ct(s)||(s=mi("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>oi([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>ci(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=mi(li(o,t),i),ct(n))return hi(t,n)?gi(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>xi(t).includes(e),ownKeys:t=>xi(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function ai(t,e,i,s){const n={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:ri(t,s),setContext:e=>ai(t,e,i,s),override:n=>ai(t.override(n),e,i,s)};return new Proxy(n,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>ci(t,e,(()=>function(t,e,i){const{_proxy:s,_context:n,_subProxy:o,_descriptors:a}=t;let r=s[e];dt(r)&&a.isScriptable(e)&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),hi(t,e)&&(e=gi(n._scopes,n,t,e));return e}(e,r,t,i));Y(r)&&r.length&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_descriptors:r}=i;if(ct(o.index)&&s(t))e=e[o.index%e.length];else if(U(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=gi(s,n,t,l);e.push(ai(i,o,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));hi(e,r)&&(r=ai(r,n,o&&o[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function ri(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:dt(i)?i:()=>i,isIndexable:dt(s)?s:()=>s}}const li=(t,e)=>t?t+ht(e):e,hi=(t,e)=>U(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function ci(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function di(t,e,i){return dt(t)?t(e,i):t}const ui=(t,e)=>!0===t?e:"string"==typeof t?lt(e,t):void 0;function fi(t,e,i,s,n){for(const o of e){const e=ui(i,o);if(e){t.add(e);const o=di(e._fallback,i,n);if(ct(o)&&o!==i&&o!==s)return o}else if(!1===e&&ct(s)&&i!==s)return null}return!1}function gi(t,e,i,s){const n=e._rootScopes,o=di(e._fallback,i,s),a=[...t,...n],r=new Set;r.add(s);let l=pi(r,a,i,o||i,s);return null!==l&&((!ct(o)||o===i||(l=pi(r,a,o,l,s),null!==l))&&oi(Array.from(r),[""],n,o,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const n=s[e];if(Y(n)&&U(i))return i;return n}(e,i,s))))}function pi(t,e,i,s,n){for(;i;)i=fi(t,e,i,s,n);return i}function mi(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ct(e))return e}}function xi(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}const bi=Number.EPSILON||1e-14,_i=(t,e)=>e<t.length&&!t[e].skip&&t[e],yi=t=>"x"===t?"y":"x";function vi(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=Vt(o,n),l=Vt(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function wi(t,e="x"){const i=yi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=_i(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=_i(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?Ct(n[a-1])!==Ct(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=_i(t,0);for(let c=0;c<s-1;++c)l=h,h=_i(t,c+1),l&&h&&(Lt(e[c],0,bi)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i="x"){const s=yi(i),n=t.length;let o,a,r,l=_i(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=_i(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function Mi(t,e,i){return Math.max(Math.min(t,i),e)}function ki(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),"monotone"===e.cubicInterpolationMode)wi(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=vi(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Jt(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Jt(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=Mi(n.cp1x,e.left,e.right),n.cp1y=Mi(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=Mi(n.cp2x,e.left,e.right),n.cp2y=Mi(n.cp2y,e.top,e.bottom)))}(t,i)}const Si=t=>0===t||1===t,Pi=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*yt/i),Di=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*yt/i)+1,Ci={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*kt),easeOutSine:t=>Math.sin(t*kt),easeInOutSine:t=>-.5*(Math.cos(_t*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>Si(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>Si(t)?t:Pi(t,.075,.3),easeOutElastic:t=>Si(t)?t:Di(t,.075,.3),easeInOutElastic(t){const e=.1125;return Si(t)?t:t<.5?.5*Pi(2*t,e,.45):.5+.5*Di(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let 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:t=>1-Ci.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*Ci.easeInBounce(2*t):.5*Ci.easeOutBounce(2*t-1)+.5};function Oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function Ai(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function Ti(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=Oi(t,n,i),r=Oi(n,o,i),l=Oi(o,e,i),h=Oi(a,r,i),c=Oi(r,l,i);return Oi(h,c,i)}const Li=new Map;function Ri(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=Li.get(i);return s||(s=new Intl.NumberFormat(t,e),Li.set(i,s)),s}(e,i).format(t)}function Ei(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ii(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function zi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Fi(t){return"angle"===t?{between:Ht,compare:Wt,normalize:Nt}:{between:Yt,compare:(t,e)=>t-e,normalize:t=>t}}function Bi({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Vi(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Fi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Fi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,x,b=!1,_=null;const y=()=>b||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(Bi({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Bi({start:_,end:d,loop:u,count:a,style:f})),g}function Wi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Vi(s[n],t.points,e);o.length&&i.push(...o)}return i}function Ni(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Hi(t,[{start:a,end:r,loop:o}],i,e);return Hi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Hi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=ji(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=ji(s.setContext(Ye(n,{type:"segment",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),$i(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function ji(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function $i(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Yi=Object.freeze({__proto__:null,easingEffects:Ci,color:W,getHoverColor:N,noop:H,uid:j,isNullOrUndef:$,isArray:Y,isObject:U,isFinite:X,finiteOrDefault:q,valueOrDefault:K,toPercentage:G,toDimension:Z,callback:J,each:Q,_elementsEqual:tt,clone:et,_merger:st,merge:nt,mergeIf:ot,_mergerIf:at,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': "'+i+'" is deprecated. Please use "'+s+'" instead')},resolveObjectKey:lt,_capitalize:ht,defined:ct,isFunction:dt,setsEqual:ut,_isClickEvent:ft,toFontString:Ut,_measureText:Xt,_longestText:qt,_alignPixel:Kt,clearCanvas:Gt,drawPoint:Zt,_isPointInArea:Jt,clipArea:Qt,unclipArea:te,_steppedLineTo:ee,_bezierCurveTo:ie,renderText:se,addRoundedRectPath:oe,_lookup:ae,_lookupByKey:re,_rlookupByKey:le,_filterBetween:he,listenArrayEvents:de,unlistenArrayEvents:ue,_arrayUnique:fe,_createResolver:oi,_attachContext:ai,_descriptors:ri,splineCurve:vi,splineCurveMonotone:wi,_updateBezierControlPoints:ki,_isDomSupported:ge,_getParentNode:pe,getStyle:be,getRelativePosition:ve,getMaximumSize:Me,retinaScale:ke,supportsEventListenerOptions:Se,readUsedSize:Pe,fontString:function(t,e,i){return e+" "+t+"px "+i},requestAnimFrame:t,throttled:e,debounce:i,_toLeftRightCenter:s,_alignStartEnd:n,_textX:o,_pointInLine:Oi,_steppedInterpolation:Ai,_bezierInterpolation:Ti,formatNumber:Ri,toLineHeight:Fe,_readValueToProps:Be,toTRBL:Ve,toTRBLCorners:We,toPadding:Ne,toFont:He,resolve:je,_addGrace:$e,createContext:Ye,PI:_t,TAU:yt,PITAU:vt,INFINITY:wt,RAD_PER_DEG:Mt,HALF_PI:kt,QUARTER_PI:St,TWO_THIRDS_PI:Pt,log10:Dt,sign:Ct,niceNum:Ot,_factorize:At,isNumber:Tt,almostEquals:Lt,almostWhole:Rt,_setMinAndMaxByKey:Et,toRadians:It,toDegrees:zt,_decimalPlaces:Ft,getAngleFromPoint:Bt,distanceBetweenPoints:Vt,_angleDiff:Wt,_normalizeAngle:Nt,_angleBetween:Ht,_limitValue:jt,_int16Range:$t,_isBetween:Yt,getRtlAdapter:Ei,overrideTextDirection:Ii,restoreTextDirection:zi,_boundSegment:Vi,_boundSegments:Wi,_computeSegments:Ni});class Ui{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Xi extends Ui{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const qi={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Ki=t=>null===t||""===t;const Gi=!!Se&&{passive:!0};function Zi(t,e,i){t.canvas.removeEventListener(e,i,Gi)}function Ji(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function Qi(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.addedNodes,s),e=e&&!Ji(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function ts(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.removedNodes,s),e=e&&!Ji(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const es=new Map;let is=0;function ss(){const t=window.devicePixelRatio;t!==is&&(is=t,es.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function ns(t,i,s){const n=t.canvas,o=n&&pe(n);if(!o)return;const a=e(((t,e)=>{const i=o.clientWidth;s(t,e),i<o.clientWidth&&s()}),window),r=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||a(i,s)}));return r.observe(o),function(t,e){es.size||window.addEventListener("resize",ss),es.set(t,e)}(t,a),r}function os(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){es.delete(t),es.size||window.removeEventListener("resize",ss)}(t)}function as(t,i,s){const n=t.canvas,o=e((e=>{null!==t.ctx&&s(function(t,e){const i=qi[t.type]||t.type,{x:s,y:n}=ve(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,Gi)}(n,i,o),o}class rs extends Ui{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",Ki(n)){const e=Pe(t,"width");void 0!==e&&(t.width=e)}if(Ki(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Pe(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const s=i[t];$(s)?e.removeAttribute(t):e.setAttribute(t,s)}));const s=i.style||{};return Object.keys(s).forEach((t=>{e.style[t]=s[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:Qi,detach:ts,resize:ns}[e]||as;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:os,detach:os,resize:os}[e]||Zi)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return Me(t,e,i,s)}isAttached(t){const e=pe(t);return!(!e||!e.isConnected)}}function ls(t){return!ge()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Xi:rs}var hs=Object.freeze({__proto__:null,_detectPlatform:ls,BasePlatform:Ui,BasicPlatform:Xi,DomPlatform:rs});const cs="transparent",ds={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=W(t||cs),n=s.valid&&W(e||cs);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class us{constructor(t,e,i,s){const n=e[i];s=je([t.to,s,n,t.from]);const o=je([t.from,n,s]);this._active=!0,this._fn=t.fn||ds[t.type||typeof o],this._easing=Ci[t.easing]||Ci.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=je([t.to,e,s,t.from]),this._from=je([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}bt.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const fs=Object.keys(bt.animation);bt.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),bt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),bt.describe("animations",{_fallback:"animation"}),bt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class gs{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!U(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const s=t[i];if(!U(s))return;const n={};for(const t of fs)n[t]=s[t];(Y(s.properties)&&s.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,n)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new us(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function ps(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ms(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function xs(t,e,i,s={}){const n=t.keys,o="single"===s.mode;let a,r,l,h;if(null!==e){for(a=0,r=n.length;a<r;++a){if(l=+n[a],l===i){if(s.all)continue;break}h=t.values[l],X(h)&&(o||0===e||Ct(e)===Ct(h))&&(e+=h)}return e}}function bs(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function _s(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function ys(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function vs(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=_s(n,c,o),u[r]=d,u._top=ys(u,a,!0,s.type),u._bottom=ys(u,a,!1,s.type)}}function ws(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Ms(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const ks=t=>"reset"===t||"none"===t,Ss=(t,e)=>e?t:Object.assign({},t);class Ps{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=bs(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Ms(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=K(i.xAxisID,ws(t,"x")),o=e.yAxisID=K(i.yAxisID,ws(t,"y")),a=e.rAxisID=K(i.rAxisID,ws(t,"r")),r=e.indexAxis,l=e.iAxisID=s(r,n,o,a),h=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(l),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&ue(this._data,this),t._stacked&&Ms(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(U(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){ue(i,this);const t=this._cachedMeta;Ms(t),t._parsed=[]}e&&Object.isExtensible(e)&&de(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=bs(e.vScale,e),e.stack!==i.stack&&(s=!0,Ms(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&vs(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:s}=this,{iScale:n,_stacked:o}=i,a=n.axis;let r,l,h,c=0===t&&e===s.length||i._sorted,d=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,h=s;else{h=Y(s[t])?this.parseArrayData(i,s,t,e):U(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const n=()=>null===l[a]||d&&l[a]<d[a];for(r=0;r<e;++r)i._parsed[r+t]=l=h[r],c&&(n()&&(c=!1),d=l);i._sorted=c}o&&vs(this,h)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(lt(u,a),d),y:o.parse(lt(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return xs({keys:ms(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=xs(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,o=s.length,a=this._getOtherScale(t),r=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:ms(i,!0),values:null})(e,i,this.chart),l={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:c}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(a);let d,u;function f(){u=s[d];const e=u[a.axis];return!X(u[t.axis])||h>e||c<e}for(d=0;d<o&&(f()||(this.updateRangeFromParsed(l,t,u,r),!n));++d);if(n)for(d=o-1;d>=0;--d)if(!f()){this.updateRangeFromParsed(l,t,u,r);break}return l}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s][t.axis],X(o)&&i.push(o);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?""+i.getLabelForValue(n[i.axis]):"",value:s?""+s.getLabelForValue(n[s.axis]):""}}_update(t){const e=this._cachedMeta;this.update(t||"default"),e._clip=function(t){let e,i,s,n;return U(t)?(e=t.top,i=t.right,s=t.bottom,n=t.left):e=i=s=n=t,{top:e,right:i,bottom:s,left:n,disabled:!1===t}}(K(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=ps(t,i),n=ps(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a,l=this.options.drawActiveElementsOnTop;let h;for(i.dataset&&i.dataset.draw(t,n,a,r),h=a;h<a+r;++h){const e=s[h];e.hidden||(e.active&&l?o.push(e):e.draw(t,n))}for(h=0;h<o.length;++h)o[h].draw(t,n)}getStyle(t,e){const i=e?"active":"default";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return Ye(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:"default",type:"data"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return Ye(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:"default",type:"dataset"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e="default",i){const s="active"===e,n=this._cachedDataOpts,o=t+"-"+e,a=n[o],r=this.enableOptionSharing&&ct(i);if(a)return Ss(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,"hover",t,""]:[t,""],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(bt.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ss(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new gs(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||ks(t)||this.chart._animationsDisabled}updateElement(t,e,i,s){ks(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!ks(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,"reset")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&Ms(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync(["_insertElements",this.getDataset().data.length-t,t])}_onDataPop(){this._sync(["_removeElements",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync(["_removeElements",0,1])}_onDataSplice(t,e){e&&this._sync(["_removeElements",t,e]);const i=arguments.length-2;i&&this._sync(["_insertElements",t,i])}_onDataUnshift(){this._sync(["_insertElements",0,arguments.length])}}Ps.defaults={},Ps.prototype.datasetElementType=null,Ps.prototype.dataElementType=null;class Ds{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}hasValue(){return Tt(this.x)&&Tt(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Ds.defaults={},Ds.defaultRoutes=void 0;const Cs={values:t=>Y(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Dt(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),Ri(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(Dt(t)));return 1===s||2===s||5===s?Cs.numeric.call(this,t,e,i):""}};var Os={formatters:Cs};function As(t,e){const i=t.options.ticks,s=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),n=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],o=n.length,a=n[0],r=n[o-1],l=[];if(o>s)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,l,n,o/s),l;const h=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=At(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(n,e,s);if(o>0){let t,i;const s=o>1?Math.round((r-a)/(o-1)):null;for(Ts(e,l,h,$(s)?0:a-s,a),t=0,i=o-1;t<i;t++)Ts(e,l,h,n[t],n[t+1]);return Ts(e,l,h,r,$(s)?e.length:r+s),l}return Ts(e,l,h),l}function Ts(t,e,i,s,n){const o=K(s,0),a=Math.min(K(n,t.length),t.length);let r,l,h,c=0;for(i=Math.ceil(i),n&&(r=n-s,i=r/Math.floor(r/i)),h=o;h<0;)c++,h=Math.round(o+c*i);for(l=Math.max(o,0);l<a;l++)l===h&&(e.push(t[l]),c++,h=Math.round(o+c*i))}bt.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Os.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),bt.route("scale.ticks","color","","color"),bt.route("scale.grid","color","","borderColor"),bt.route("scale.grid","borderColor","","borderColor"),bt.route("scale.title","color","","color"),bt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),bt.describe("scales",{_fallback:"scale"}),bt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Ls=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Rs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Es(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Is(t){return t.drawTicks?t.tickLength:0}function zs(t,e){if(!t.display)return 0;const i=He(t.font,e),s=Ne(t.padding);return(Y(t.text)?t.text.length:1)*i.lineHeight+s.height}function Fs(t,e,i){let n=s(t);return(i&&"right"!==e||!i&&"right"===e)&&(n=(t=>"left"===t?"right":"right"===t?"left":t)(n)),n}class Bs extends Ds{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=q(t,Number.POSITIVE_INFINITY),e=q(e,Number.NEGATIVE_INFINITY),i=q(i,Number.POSITIVE_INFINITY),s=q(s,Number.NEGATIVE_INFINITY),{min:q(t,i),max:q(e,s),minDefined:X(t),maxDefined:X(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;r<l;++r)e=a[r].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:q(i,q(s,i)),max:q(s,q(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){J(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=$e(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Rs(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||"auto"===o.source)&&(this.ticks=As(this,this.ticks),this._labelSizes=null),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){J(this.options.afterUpdate,[this])}beforeSetDimensions(){J(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){J(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),J(this.options[t],[this])}beforeDataLimits(){this._callHooks("beforeDataLimits")}determineDataLimits(){}afterDataLimits(){this._callHooks("afterDataLimits")}beforeBuildTicks(){this._callHooks("beforeBuildTicks")}buildTicks(){return[]}afterBuildTicks(){this._callHooks("afterBuildTicks")}beforeTickToLabelConversion(){J(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=J(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){J(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){J(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=jt(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Is(t.grid)-e.padding-zs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=zt(Math.min(Math.asin(jt((h.highest.height+6)/o,-1,1)),Math.asin(jt(a/r,-1,1))-Math.asin(jt(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){J(this.options.afterCalculateLabelRotation,[this])}beforeFit(){J(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=zs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Is(n)+o):(t.height=this.maxHeight,t.width=Is(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=It(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){J(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e<i;e++)$(t[e].label)&&(t.splice(e,1),i--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Rs(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:i,_longestTextCache:s}=this,n=[],o=[];let a,r,l,h,c,d,u,f,g,p,m,x=0,b=0;for(a=0;a<e;++a){if(h=t[a].label,c=this._resolveTickFontOptions(a),i.font=d=c.string,u=s[d]=s[d]||{data:{},gc:[]},f=c.lineHeight,g=p=0,$(h)||Y(h)){if(Y(h))for(r=0,l=h.length;r<l;++r)m=h[r],$(m)||Y(m)||(g=Xt(i,u.data,u.gc,g,m),p+=f)}else g=Xt(i,u.data,u.gc,g,h),p=f;n.push(g),o.push(p),x=Math.max(g,x),b=Math.max(p,b)}!function(t,e){Q(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(s,e);const _=n.indexOf(x),y=o.indexOf(b),v=t=>({width:n[t]||0,height:o[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:n,heights:o}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return $t(this._alignToPixels?Kt(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return Ye(t,{tick:i,index:e,type:"tick"})}(this.getContext(),t,i))}return this.$context||(this.$context=Ye(this.chart.getContext(),{scale:this,type:"scale"}))}_tickSize(){const t=this.options.ticks,e=It(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return"auto"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:o}=s,a=n.offset,r=this.isHorizontal(),l=this.ticks.length+(a?1:0),h=Is(n),c=[],d=n.setContext(this.getContext()),u=d.drawBorder?d.borderWidth:0,f=u/2,g=function(t){return Kt(i,t,u)};let p,m,x,b,_,y,v,w,M,k,S,P;if("top"===o)p=g(this.bottom),y=this.bottom-h,w=p-f,k=g(t.top)+f,P=t.bottom;else if("bottom"===o)p=g(this.top),k=t.top,P=g(t.bottom)-f,y=p+f,w=this.top+h;else if("left"===o)p=g(this.right),_=this.right-h,v=p-f,M=g(t.left)+f,S=t.right;else if("right"===o)p=g(this.left),M=t.left,S=g(t.right)-f,_=p+f,v=this.left+h;else if("x"===e){if("center"===o)p=g((t.top+t.bottom)/2+.5);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}k=t.top,P=t.bottom,y=p+f,w=y+h}else if("y"===e){if("center"===o)p=g((t.left+t.right)/2);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}_=p-f,v=_-h,M=t.left,S=t.right}const D=K(s.ticks.maxTicksLimit,l),C=Math.max(1,Math.ceil(l/D));for(m=0;m<l;m+=C){const t=n.setContext(this.getContext(m)),e=t.lineWidth,s=t.color,o=n.borderDash||[],l=t.borderDashOffset,h=t.tickWidth,d=t.tickColor,u=t.tickBorderDash||[],f=t.tickBorderDashOffset;x=Es(this,m,a),void 0!==x&&(b=Kt(i,x,e),r?_=v=M=S=b:y=w=k=P=b,c.push({tx1:_,ty1:y,tx2:v,ty2:w,x1:M,y1:k,x2:S,y2:P,width:e,color:s,borderDash:o,borderDashOffset:l,tickWidth:h,tickColor:d,tickBorderDash:u,tickBorderDashOffset:f}))}return this._ticksLength=l,this._borderValue=p,c}_computeLabelItems(t){const e=this.axis,i=this.options,{position:s,ticks:n}=i,o=this.isHorizontal(),a=this.ticks,{align:r,crossAlign:l,padding:h,mirror:c}=n,d=Is(i.grid),u=d+h,f=c?-h:u,g=-It(this.labelRotation),p=[];let m,x,b,_,y,v,w,M,k,S,P,D,C="middle";if("top"===s)v=this.bottom-f,w=this._getXAxisLabelAlignment();else if("bottom"===s)v=this.top+f,w=this._getXAxisLabelAlignment();else if("left"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("right"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("x"===e){if("center"===s)v=(t.top+t.bottom)/2+u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];v=this.chart.scales[t].getPixelForValue(e)+u}w=this._getXAxisLabelAlignment()}else if("y"===e){if("center"===s)y=(t.left+t.right)/2-u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];y=this.chart.scales[t].getPixelForValue(e)}w=this._getYAxisLabelAlignment(d).textAlign}"y"===e&&("start"===r?C="top":"end"===r&&(C="bottom"));const O=this._getLabelSizes();for(m=0,x=a.length;m<x;++m){b=a[m],_=b.label;const t=n.setContext(this.getContext(m));M=this.getPixelForTick(m)+n.labelOffset,k=this._resolveTickFontOptions(m),S=k.lineHeight,P=Y(_)?_.length:1;const e=P/2,i=t.color,r=t.textStrokeColor,h=t.textStrokeWidth;let d;if(o?(y=M,D="top"===s?"near"===l||0!==g?-P*S+S/2:"center"===l?-O.highest.height/2-e*S+S:-O.highest.height+S/2:"near"===l||0!==g?S/2:"center"===l?O.highest.height/2-e*S:O.highest.height-P*S,c&&(D*=-1)):(v=M,D=(1-P)*S/2),t.showLabelBackdrop){const e=Ne(t.backdropPadding),i=O.heights[m],s=O.widths[m];let n=v+D-e.top,o=y-e.left;switch(C){case"middle":n-=i/2;break;case"bottom":n-=i}switch(w){case"center":o-=s/2;break;case"right":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}p.push({rotation:g,label:_,font:k,color:i,strokeColor:r,strokeWidth:h,textOffset:D,textAlign:w,textBaseline:C,translation:[y,v],backdrop:d})}return p}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-It(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align&&(i="right"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=Kt(t,this.left,n)-n/2,l=Kt(t,this.right,o)+o/2,h=c=a):(h=Kt(t,this.top,n)-n/2,c=Kt(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Qt(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),se(e,o,0,t.textOffset,i,t)}i&&te(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:s}}=this;if(!i.display)return;const o=He(i.font),a=Ne(i.padding),r=i.align;let l=o.lineHeight/2;"bottom"===e||"center"===e||U(e)?(l+=a.bottom,Y(i.text)&&(l+=o.lineHeight*(i.text.length-1))):l+=a.top;const{titleX:h,titleY:c,maxWidth:d,rotation:u}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,x=l-a;if(t.isHorizontal()){if(f=n(s,a,l),U(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g="center"===i?(c.bottom+c.top)/2+m-e:Ls(t,i,e);u=l-a}else{if(U(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-x+e}else f="center"===i?(c.left+c.right)/2-x+e:Ls(t,i,e);g=n(s,r,o),p="left"===i?-kt:kt}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,l,e,r);se(t,i.text,0,0,o,{color:i.color,maxWidth:d,rotation:u,textAlign:Fs(r,e,s),textBaseline:"middle",translation:[h,c]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=K(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===Bs.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return He(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Vs{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return"id"in t&&"defaults"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+"."+n;if(!n)throw new Error("class does not have id: "+t);return n in s||(s[n]=t,function(t,e,i){const s=nt(Object.create(null),[i?bt.get(i):{},bt.get(e),t.defaults]);bt.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");bt.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&bt.describe(e,t.descriptors)}(t,o,i),this.override&&bt.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in bt[s]&&(delete bt[s][i],this.override&&delete gt[i])}}var Ws=new class{constructor(){this.controllers=new Vs(Ps,"datasets",!0),this.elements=new Vs(Ds,"elements"),this.plugins=new Vs(Object,"plugins"),this.scales=new Vs(Bs,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):Q(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=ht(t);J(i["before"+s],[],i),e[t](i),J(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('"'+t+'" is not a registered '+i+".");return s}};class Ns{constructor(){this._init=[]}notify(t,e,i,s){"beforeInit"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,"install"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return"afterDestroy"===e&&(this._notify(n,t,"stop"),this._notify(this._init,t,"uninstall")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===J(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){$(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=K(i.options&&i.options.plugins,{}),n=function(t){const e=[],i=Object.keys(Ws.plugins.items);for(let t=0;t<i.length;t++)e.push(Ws.getPlugin(i[t]));const s=t.plugins||[];for(let t=0;t<s.length;t++){const i=s[t];-1===e.indexOf(i)&&e.push(i)}return e}(i);return!1!==s||e?function(t,e,i,s){const n=[],o=t.getContext();for(let a=0;a<e.length;a++){const r=e[a],l=Hs(i[r.id],s);null!==l&&n.push({plugin:r,options:js(t.config,r,l,o)})}return n}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function Hs(t,e){return e||!1!==t?!0===t?{}:t:null}function js(t,e,i,s){const n=t.pluginScopeKeys(e),o=t.getOptionScopes(i,n);return t.createResolver(o,s,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function $s(t,e){const i=bt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Ys(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function Us(t){const e=t.options||(t.options={});e.plugins=K(e.plugins,{}),e.scales=function(t,e){const i=gt[t.type]||{scales:{}},s=e.scales||{},n=$s(t.type,e),o=Object.create(null),a=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!U(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const r=Ys(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,n),h=i.scales||{};o[r]=o[r]||t,a[t]=ot(Object.create(null),[{axis:r},e,h[r],h[l]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,r=i.indexAxis||$s(n,e),l=(gt[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),n=i[e+"AxisID"]||o[e]||e;a[n]=a[n]||Object.create(null),ot(a[n],[{axis:e},s[n],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];ot(e,[bt.scales[e.type],bt.scale])})),a}(t,e)}function Xs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const qs=new Map,Ks=new Set;function Gs(t,e){let i=qs.get(t);return i||(i=e(),qs.set(t,i),Ks.add(i)),i}const Zs=(t,e,i)=>{const s=lt(e,i);void 0!==s&&t.add(s)};class Js{constructor(t){this._config=function(t){return(t=t||{}).data=Xs(t.data),Us(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Xs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Us(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Gs(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return Gs(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return Gs(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return Gs(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>Zs(r,t,e)))),e.forEach((t=>Zs(r,s,t))),e.forEach((t=>Zs(r,gt[n]||{},t))),e.forEach((t=>Zs(r,bt,t))),e.forEach((t=>Zs(r,pt,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),Ks.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,gt[e]||{},bt.datasets[e]||{},{type:e},bt,pt]}resolveNamedOptions(t,e,i,s=[""]){const n={$shared:!0},{resolver:o,subPrefixes:a}=Qs(this._resolverCache,t,s);let r=o;if(function(t,e){const{isScriptable:i,isIndexable:s}=ri(t);for(const n of e){const e=i(n),o=s(n),a=(o||e)&&t[n];if(e&&(dt(a)||tn(a))||o&&Y(a))return!0}return!1}(o,e)){n.$shared=!1;r=ai(o,i=dt(i)?i():i,this.createResolver(t,i,a))}for(const t of e)n[t]=r[t];return n}createResolver(t,e,i=[""],s){const{resolver:n}=Qs(this._resolverCache,t,i);return U(e)?ai(n,e,void 0,s):n}}function Qs(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:oi(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const tn=t=>U(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||dt(t[i])),!1);const en=["top","bottom","left","right","chartArea"];function sn(t,e){return"top"===t||"bottom"===t||-1===en.indexOf(t)&&"x"===e}function nn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function on(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),J(i&&i.onComplete,[t],e)}function an(t){const e=t.chart,i=e.options.animation;J(i&&i.onProgress,[t],e)}function rn(t){return ge()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const ln={},hn=t=>{const e=rn(t);return Object.values(ln).filter((t=>t.canvas===e)).pop()};function cn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class dn{constructor(t,e){const s=this.config=new Js(e),n=rn(t),o=hn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||ls(n)),this.platform.updateConfig(s);const l=this.platform.acquireContext(n,r.aspectRatio),h=l&&l.canvas,c=h&&h.height,d=h&&h.width;this.id=j(),this.ctx=l,this.canvas=h,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Ns,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((t=>this.update(t)),r.resizeDelay||0),this._dataChanges=[],ln[this.id]=this,l&&h?(a.listen(this,"complete",on),a.listen(this,"progress",an),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:s,_aspectRatio:n}=this;return $(t)?e&&n?n:s?i/s:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ke(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Gt(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ke(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),J(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){Q(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Ys(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),Q(n,(e=>{const n=e.options,o=n.id,a=Ys(o,n),r=K(n.type,e.dtype);void 0!==n.position&&sn(n.position,a)===sn(e.dposition)||(n.position=e.dposition),s[o]=!0;let l=null;if(o in i&&i[o].type===r)l=i[o];else{l=new(Ws.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[l.id]=l}l.init(n,t)})),Q(s,((t,e)=>{t||delete i[e]})),Q(i,(t=>{ni.configure(this,t,t.options),ni.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(nn("order","index"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||$s(o,this.options),n.order=s.order||0,n.index=i,n.label=""+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Ws.getController(o),{datasetElementType:s,dataElementType:a}=bt.datasets[o];Object.assign(e.prototype,{dataElementType:Ws.getElement(a),datasetElementType:s&&Ws.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){Q(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||Q(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(nn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){Q(this.scales,(t=>{ni.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);ut(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){cn(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;t<e;t++)if(!ut(s,i(t)))return;return Array.from(s).map((t=>t.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ni.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],Q(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,dt(t)?t({datasetIndex:e}):t);this.notifyPlugins("afterDatasetsUpdate",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetUpdate",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins("afterDatasetUpdate",s))}render(){!1!==this.notifyPlugins("beforeRender",{cancelable:!0})&&(a.has(this)?this.attached&&!a.running(this)&&a.start(this):(this.draw(),on({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins("beforeDraw",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins("afterDraw")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins("beforeDatasetsDraw",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&Qt(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&te(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}getElementsAtEventForMode(t,e,i,s){const n=Ee.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=Ye(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);ct(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),a.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){this.notifyPlugins("beforeDestroy");const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),Gt(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins("destroy"),delete ln[this.id],this.notifyPlugins("afterDestroy")}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};Q(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){Q(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},Q(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+"HoverStyle"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!tt(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:Jt(t,this.chartArea,this._minPadding)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=ft(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,J(n.onHover,[t,a,this],this),r&&J(n.onClick,[t,a,this],this));const h=!tt(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const un=()=>Q(dn.instances,(t=>t._plugins.invalidate())),fn=!0;function gn(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(dn,{defaults:{enumerable:fn,value:bt},instances:{enumerable:fn,value:ln},overrides:{enumerable:fn,value:gt},registry:{enumerable:fn,value:Ws},version:{enumerable:fn,value:"3.7.0"},getChart:{enumerable:fn,value:hn},register:{enumerable:fn,value:(...t)=>{Ws.add(...t),un()}},unregister:{enumerable:fn,value:(...t)=>{Ws.remove(...t),un()}}});class pn{constructor(t){this.options=t||{}}formats(){return gn()}parse(t,e){return gn()}format(t,e){return gn()}add(t,e,i){return gn()}diff(t,e,i){return gn()}startOf(t,e,i){return gn()}endOf(t,e){return gn()}}pn.override=function(t){Object.assign(pn.prototype,t)};var mn={_date:pn};function xn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=fe(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(ct(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function bn(t,e,i,s){return Y(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function _n(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(bn(u,d,o,h));return l}function yn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function vn(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i="left",s="right"):(e=t.base<t.y,i="bottom",s="top"),e?(n="end",o="start"):(n="start",o="end"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);"middle"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[wn(c,a,r,l)]=!0,n=h)),o[wn(n,a,r,l)]=!0,t.borderSkipped=o}function wn(t,e,i,s){var n,o,a;return s?(a=i,t=Mn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=Mn(t,e,i),t}function Mn(t,e,i){return"start"===t?e:"end"===t?i:t}function kn(t,{inflateAmount:e},i){t.inflateAmount="auto"===e?1===i?.33:0:e}class Sn extends Ps{parsePrimitiveData(t,e,i,s){return _n(t,e,i,s)}parseArrayData(t,e,i,s){return _n(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(lt(g,l),d),c.push(bn(lt(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=yn(o)?"["+o.start+", "+o.end+"]":""+s.getLabelForValue(n[s.axis]);return{label:""+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,i,s){const n="reset"===s,{index:o,_cachedMeta:{vScale:a}}=this,r=a.getBasePixel(),l=a.isHorizontal(),h=this._getRuler(),c=this.resolveDataElementOptions(e,s),d=this.getSharedOptions(c),u=this.includeOptions(s,d);this.updateSharedOptions(d,s,c);for(let c=e;c<e+i;c++){const e=this.getParsed(c),i=n||$(e[a.axis])?{base:r,head:r}:this._calculateBarValuePixels(c),f=this._calculateBarIndexPixels(c,h),g=(e._stacks||{})[a.axis],p={horizontal:l,base:i.base,enableBorderRadius:!g||yn(e._custom)||o===g._top||o===g._bottom,x:l?i.head:f.center,y:l?f.center:i.head,height:l?f.size:Math.abs(i.size),width:l?Math.abs(i.size):f.size};u&&(p.options=d||this.resolveDataElementOptions(c,t[c].active?"active":s));const m=p.options||t[c].options;vn(p,m,g,o),kn(p,m,h.ratio),this.updateElement(t[c],c,p,s)}}_getStacks(t,e){const i=this._cachedMeta.iScale,s=i.getMatchingVisibleMetas(this._type),n=i.options.stacked,o=s.length,a=[];let r,l;for(r=0;r<o;++r)if(l=s[r],l.controller.options.grouped){if(void 0!==e){const t=l.controller.getParsed(e)[l.controller._cachedMeta.vScale.axis];if($(t)||isNaN(t))continue}if((!1===n||-1===a.indexOf(l.stack)||void 0===n&&void 0===l.stack)&&a.push(l.stack),l.index===t)break}return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||xn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:i},options:{base:s,minBarLength:n}}=this,o=s||0,a=this.getParsed(t),r=a._custom,l=yn(r);let h,c,d=a[e.axis],u=0,f=i?this.applyStack(e,a,i):d;f!==d&&(u=f-d,f=d),l&&(d=r.barStart,f=r.barEnd-r.barStart,0!==d&&Ct(d)!==Ct(r.barEnd)&&(u=0),u+=d);const g=$(s)||l?u:s;let p=e.getPixelForValue(g);if(h=this.chart.getDataVisibility(t)?e.getPixelForValue(u+f):p,c=h-p,Math.abs(c)<n&&(c=function(t,e,i){return 0!==t?Ct(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(c,e,o)*n,d===o&&(p-=c/2),h=p+c),p===e.getPixelForValue(o)){const t=Ct(c)*e.getLineWidthForValue(o)/2;p+=t,c-=t}return{size:c,base:p,head:h,center:h+c/2}}_calculateBarIndexPixels(t,e){const i=e.scale,s=this.options,n=s.skipNull,o=K(s.maxBarThickness,1/0);let a,r;if(e.grouped){const i=n?this._getStackCount(t):e.stackCount,l="flex"===s.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,s,i):function(t,e,i,s){const n=i.barThickness;let o,a;return $(n)?(o=e.min*i.categoryPercentage,a=i.barPercentage):(o=n*s,a=1),{chunk:o/s,ratio:a,start:e.pixels[t]-o/2}}(t,e,s,i),h=this._getStackIndex(this.index,this._cachedMeta.stack,n?t:void 0);a=l.start+l.chunk*h+l.chunk/2,r=Math.min(o,l.chunk*l.ratio)}else a=i.getPixelForValue(this.getParsed(t)[i.axis],t),r=Math.min(o,e.min*e.ratio);return{base:a-r/2,head:a+r/2,center:a,size:r}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Sn.id="bar",Sn.defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}},Sn.overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};class Pn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,r=this.resolveDataElementOptions(e,s),l=this.getSharedOptions(r),h=this.includeOptions(s,l),c=o.axis,d=a.axis;for(let r=e;r<e+i;r++){const e=t[r],i=!n&&this.getParsed(r),l={},u=l[c]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[c]),f=l[d]=n?a.getBasePixel():a.getPixelForValue(i[d]);l.skip=isNaN(u)||isNaN(f),h&&(l.options=this.resolveDataElementOptions(r,e.active?"active":s),n&&(l.options.radius=0)),this.updateElement(e,r,l,s)}this.updateSharedOptions(l,s,r)}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return"active"!==e&&(s.radius=0),s.radius+=K(i&&i._custom,n),s}}Pn.id="bubble",Pn.defaults={datasetElementType:!1,dataElementType:"point",animations:{numbers:{type:"number",properties:["x","y","borderWidth","radius"]}}},Pn.overrides={scales:{x:{type:"linear"},y:{type:"linear"}},plugins:{tooltip:{callbacks:{title:()=>""}}}};class Dn extends Ps{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,o,a=t=>+i[t];if(U(i[t])){const{key:t="value"}=this._parsing;a=e=>+lt(i[e],t)}for(n=t,o=t+e;n<o;++n)s._parsed[n]=a(n)}}_getRotation(){return It(this.options.rotation-90)}_getCircumference(){return It(this.options.circumference)}_getRotationExtents(){let t=yt,e=-yt;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(G(this.options.cutout,a),1),l=this._getRingWeight(this.index),{circumference:h,rotation:c}=this._getRotationExtents(),{ratioX:d,ratioY:u,offsetX:f,offsetY:g}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<yt){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>Ht(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>Ht(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(kt,c,u),x=g(_t,h,d),b=g(_t+kt,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(c,h,r),p=(i.width-o)/d,m=(i.height-o)/u,x=Math.max(Math.min(p,m)/2,0),b=Z(this.options.radius,x),_=(b-Math.max(b*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=f*b,this.offsetY=g*b,s.total=this.calculateTotal(),this.outerRadius=b-_*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-_*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/yt)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,f=this.resolveDataElementOptions(e,s),g=this.getSharedOptions(f),p=this.includeOptions(s,g);let m,x=this._getRotation();for(m=0;m<e;++m)x+=this._circumference(m,n);for(m=e;m<e+i;++m){const e=this._circumference(m,n),i=t[m],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:x,endAngle:x+e,circumference:e,outerRadius:u,innerRadius:d};p&&(o.options=g||this.resolveDataElementOptions(m,i.active?"active":s)),x+=e,this.updateElement(i,m,o,s)}this.updateSharedOptions(g,s,f)}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?yt*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),"inner"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(K(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}Dn.id="doughnut",Dn.defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"},Dn.descriptors={_scriptable:t=>"spacing"!==t,_indexable:t=>"spacing"!==t},Dn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return Y(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Cn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=function(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=jt(Math.min(re(r,a.axis,h).lo,i?s:re(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?jt(Math.max(re(r,a.axis,c).hi+1,i?0:re(e,l,a.getPixelForValue(c)).hi+1),n,s)-n:s-n}return{start:n,count:o}}(e,s,o);this._drawStart=a,this._drawCount=r,function(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a,_stacked:r,_dataset:l}=this._cachedMeta,h=this.resolveDataElementOptions(e,s),c=this.getSharedOptions(h),d=this.includeOptions(s,c),u=o.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,m=Tt(g)?g:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||n||"none"===s;let b=e>0&&this.getParsed(e-1);for(let h=e;h<e+i;++h){const e=t[h],i=this.getParsed(h),g=x?e:{},_=$(i[f]),y=g[u]=o.getPixelForValue(i[u],h),v=g[f]=n||_?a.getBasePixel():a.getPixelForValue(r?this.applyStack(a,i,r):i[f],h);g.skip=isNaN(y)||isNaN(v)||_,g.stop=h>0&&i[u]-b[u]>m,p&&(g.parsed=i,g.raw=l.data[h]),d&&(g.options=c||this.resolveDataElementOptions(h,e.active?"active":s)),x||this.updateElement(e,h,g,s),b=i}this.updateSharedOptions(c,s,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Cn.id="line",Cn.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},Cn.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class On extends Ps{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=this.getDataset(),r=o.options.animation,l=this._cachedMeta.rScale,h=l.xCenter,c=l.yCenter,d=l.getIndexAngle(0)-.5*_t;let u,f=d;const g=360/this.countVisibleElements();for(u=0;u<e;++u)f+=this._computeAngle(u,s,g);for(u=e;u<e+i;u++){const e=t[u];let i=f,p=f+this._computeAngle(u,s,g),m=o.getDataVisibility(u)?l.getDistanceFromCenterForValue(a.data[u]):0;f=p,n&&(r.animateScale&&(m=0),r.animateRotate&&(i=p=d));const x={x:h,y:c,innerRadius:0,outerRadius:m,startAngle:i,endAngle:p,options:this.resolveDataElementOptions(u,e.active?"active":s)};this.updateElement(e,u,x,s)}}countVisibleElements(){const t=this.getDataset(),e=this._cachedMeta;let i=0;return e.data.forEach(((e,s)=>{!isNaN(t.data[s])&&this.chart.getDataVisibility(s)&&i++})),i}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?It(this.resolveDataElementOptions(t,e).angle||i):0}}On.id="polarArea",On.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},On.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class An extends Dn{}An.id="pie",An.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class Tn extends Ps{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this.getDataset(),o=this._cachedMeta.rScale,a="reset"===s;for(let r=e;r<e+i;r++){const e=t[r],i=this.resolveDataElementOptions(r,e.active?"active":s),l=o.getPointPositionForValue(r,n.data[r]),h=a?o.xCenter:l.x,c=a?o.yCenter:l.y,d={x:h,y:c,angle:l.angle,skip:isNaN(h)||isNaN(c),options:i};this.updateElement(e,r,d,s)}}}Tn.id="radar",Tn.defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}},Tn.overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};class Ln extends Cn{}Ln.id="scatter",Ln.defaults={showLine:!1,fill:!1},Ln.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var Rn=Object.freeze({__proto__:null,BarController:Sn,BubbleController:Pn,DoughnutController:Dn,LineController:Cn,PolarAreaController:On,PieController:An,RadarController:Tn,ScatterController:Ln});function En(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+kt,s-kt),t.closePath(),t.clip()}function In(t,e,i,s){const n=Be(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return jt(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:jt(n.innerStart,0,a),innerEnd:jt(n.innerEnd,0,a)}}function zn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Fn(t,e,i,s,n){const{x:o,y:a,startAngle:r,pixelMargin:l,innerRadius:h}=e,c=Math.max(e.outerRadius+s+i-l,0),d=h>0?h+s+i+l:0;let u=0;const f=n-r;if(s){const t=((h>0?h-s:0)+(c>0?c-s:0))/2;u=(f-(0!==t?f*t/(t+s):f))/2}const g=(f-Math.max(.001,f*c-i/_t)/c)/2,p=r+g+u,m=n-g-u,{outerStart:x,outerEnd:b,innerStart:_,innerEnd:y}=In(e,d,c,m-p),v=c-x,w=c-b,M=p+x/v,k=m-b/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(o,a,c,M,k),b>0){const e=zn(w,k,o,a);t.arc(e.x,e.y,b,k,m+kt)}const O=zn(P,m,o,a);if(t.lineTo(O.x,O.y),y>0){const e=zn(P,C,o,a);t.arc(e.x,e.y,y,m+kt,C+Math.PI)}if(t.arc(o,a,d,m-y/d,p+_/d,!0),_>0){const e=zn(S,D,o,a);t.arc(e.x,e.y,_,D+Math.PI,p-kt)}const A=zn(v,p,o,a);if(t.lineTo(A.x,A.y),x>0){const e=zn(v,M,o,a);t.arc(e.x,e.y,x,p-kt,M)}t.closePath()}function Bn(t,e,i,s,n){const{options:o}=e,{borderWidth:a,borderJoinStyle:r}=o,l="inner"===o.borderAlign;a&&(l?(t.lineWidth=2*a,t.lineJoin=r||"round"):(t.lineWidth=a,t.lineJoin=r||"bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&En(t,e,o+yt),t.beginPath(),t.arc(s,n,h,o+yt,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+yt),c=0;c<r;++c)t.stroke()}(t,e,l),l&&En(t,e,n),Fn(t,e,i,s,n),t.stroke())}class Vn extends Ds{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=Bt(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:l,outerRadius:h,circumference:c}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),d=this.options.spacing/2,u=K(c,r-a)>=yt||Ht(n,a,r),f=Yt(o,l+d,h+d);return u&&f}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>yt?Math.floor(i/yt):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let o=0;if(s){o=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*o,Math.sin(e)*o),this.circumference>=_t&&(o=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const a=function(t,e,i,s){const{fullCircles:n,startAngle:o,circumference:a}=e;let r=e.endAngle;if(n){Fn(t,e,i,s,o+yt);for(let e=0;e<n;++e)t.fill();isNaN(a)||(r=o+a%yt,a%yt==0&&(r+=yt))}return Fn(t,e,i,s,r),t.fill(),r}(t,this,o,n);Bn(t,this,o,n,a),t.restore()}}function Wn(t,e,i=e){t.lineCap=K(i.borderCapStyle,e.borderCapStyle),t.setLineDash(K(i.borderDash,e.borderDash)),t.lineDashOffset=K(i.borderDashOffset,e.borderDashOffset),t.lineJoin=K(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=K(i.borderWidth,e.borderWidth),t.strokeStyle=K(i.borderColor,e.borderColor)}function Nn(t,e,i){t.lineTo(i.x,i.y)}function Hn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function jn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=Hn(n,i,s),c=function(t){return t.stepped?ee:t.tension||"monotone"===t.cubicInterpolationMode?ie:Nn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function $n(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=Hn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,x=0;const b=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function Yn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?$n:jn}Vn.id="arc",Vn.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Vn.defaultRoutes={backgroundColor:"backgroundColor"};const Un="function"==typeof Path2D;function Xn(t,e,i,s){Un&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Wn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Yn(e);for(const r of n)Wn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class qn extends Ds{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;ki(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Ni(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Wi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?Ai:t.tension||"monotone"===t.cubicInterpolationMode?Ti:Oi}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return Yn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=Yn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Xn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function Kn(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}qn.id="line",qn.defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0},qn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},qn.descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};class Gn extends Ds{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return Kn(this,t,"x",e)}inYRange(t,e){return Kn(this,t,"y",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Jt(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Zt(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function Zn(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps(["x","y","base","width","height"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function Jn(t,e,i,s){return t?0:jt(e,i,s)}function Qn(t){const e=Zn(t),i=e.right-e.left,s=e.bottom-e.top,n=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=Ve(s);return{t:Jn(n.top,o.top,0,i),r:Jn(n.right,o.right,0,e),b:Jn(n.bottom,o.bottom,0,i),l:Jn(n.left,o.left,0,e)}}(t,i/2,s/2),o=function(t,e,i){const{enableBorderRadius:s}=t.getProps(["enableBorderRadius"]),n=t.options.borderRadius,o=We(n),a=Math.min(e,i),r=t.borderSkipped,l=s||U(n);return{topLeft:Jn(!l||r.top||r.left,o.topLeft,0,a),topRight:Jn(!l||r.top||r.right,o.topRight,0,a),bottomLeft:Jn(!l||r.bottom||r.left,o.bottomLeft,0,a),bottomRight:Jn(!l||r.bottom||r.right,o.bottomRight,0,a)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:o},inner:{x:e.left+n.l,y:e.top+n.t,w:i-n.l-n.r,h:s-n.t-n.b,radius:{topLeft:Math.max(0,o.topLeft-Math.max(n.t,n.l)),topRight:Math.max(0,o.topRight-Math.max(n.t,n.r)),bottomLeft:Math.max(0,o.bottomLeft-Math.max(n.b,n.l)),bottomRight:Math.max(0,o.bottomRight-Math.max(n.b,n.r))}}}}function to(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&Zn(t,s);return a&&(n||Yt(e,a.left,a.right))&&(o||Yt(i,a.top,a.bottom))}function eo(t,e){t.rect(e.x,e.y,e.w,e.h)}function io(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}Gn.id="point",Gn.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},Gn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};class so extends Ds{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=Qn(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?oe:eo;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,io(o,e,n)),t.clip(),a(t,io(n,-e,o)),t.fillStyle=i,t.fill("evenodd")),t.beginPath(),a(t,io(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return to(this,t,e,i)}inXRange(t,e){return to(this,t,null,e)}inYRange(t,e){return to(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps(["x","y","base","horizontal"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return"x"===t?this.width/2:this.height/2}}so.id="bar",so.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},so.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var no=Object.freeze({__proto__:null,ArcElement:Vn,LineElement:qn,PointElement:Gn,BarElement:so});function oo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function ao(t){t.data.datasets.forEach((t=>{oo(t)}))}var ro={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void ao(t);const s=t.width;t.data.datasets.forEach(((e,n)=>{const{_data:o,indexAxis:a}=e,r=t.getDatasetMeta(n),l=o||e.data;if("y"===je([a,t.options.indexAxis]))return;if("line"!==r.type)return;const h=t.scales[r.xAxisID];if("linear"!==h.type&&"time"!==h.type)return;if(t.options.parsing)return;let{start:c,count:d}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=jt(re(e,o.axis,a).lo,0,i-1)),s=h?jt(re(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(r,l);if(d<=(i.threshold||4*s))return void oo(e);let u;switch($(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":u=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,x=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=x,o/=x;const b=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=b;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(l,c,d,s,i);break;case"min-max":u=function(t,e,i,s){let n,o,a,r,l,h,c,d,u,f,g=0,p=0;const m=[],x=e+i-1,b=t[e].x,_=t[x].x-b;for(n=e;n<e+i;++n){o=t[n],a=(o.x-b)/_*s,r=o.y;const e=0|a;if(e===l)r<u?(u=r,h=n):r>f&&(f=r,c=n),g=(p*g+o.x)/++p;else{const i=n-1;if(!$(h)&&!$(c)){const e=Math.min(h,c),s=Math.max(h,c);e!==d&&e!==i&&m.push({...t[e],x:g}),s!==d&&s!==i&&m.push({...t[s],x:g})}n>0&&i!==d&&m.push(t[i]),m.push(o),l=e,p=0,u=f=r,h=c=d=n}}return m}(l,c,d,s);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=u}))},destroy(t){ao(t)}};function lo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=K(i&&i.target,i);return void 0===s&&(s=!!e.backgroundColor),!1!==s&&null!==s&&(!0===s?"origin":s)}(t);if(U(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return X(n)&&Math.floor(n)===n?("-"!==s[0]&&"+"!==s[0]||(n=e+n),!(n===e||n<0||n>=i)&&n):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}class ho{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:yt},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function co(t){return(t.scale||{}).getPointPositionForValue?function(t){const{scale:e,fill:i}=t,s=e.options,n=e.getLabels().length,o=[],a=s.reverse?e.max:e.min,r=s.reverse?e.min:e.max;let l,h,c;if(c="start"===i?a:"end"===i?r:U(i)?i.value:e.getBaseValue(),s.grid.circular)return h=e.getPointPositionForValue(0,a),new ho({x:h.x,y:h.y,radius:e.getDistanceFromCenterForValue(c)});for(l=0;l<n;++l)o.push(e.getPointPositionForValue(l,c));return o}(t):function(t){const{scale:e={},fill:i}=t;let s,n=null;return"start"===i?n=e.bottom:"end"===i?n=e.top:U(i)?n=e.getPixelForValue(i.value):e.getBasePixel&&(n=e.getBasePixel()),X(n)?(s=e.isHorizontal(),{x:s?n:null,y:s?null:n}):null}(t)}function uo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function fo(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=go(o,e,"x");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function go(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if(Yt(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}function po(t){const{chart:e,fill:i,line:s}=t;if(X(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if("stack"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas("line");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(mo({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)fo(n,a[t],r)}return new qn({points:n,options:{}})}(t);if("shape"===i)return!0;const n=co(t);return n instanceof ho?n:mo(n,s)}function mo(t,e){let i=[],s=!1;return Y(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=uo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new qn({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function xo(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!X(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function bo(t,e,i){t.beginPath(),e.path(t),t.lineTo(e.last().x,i),t.lineTo(e.first().x,i),t.closePath(),t.clip()}function _o(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=Nt(n),o=Nt(o)),{property:t,start:n,end:o}}function yo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function vo(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};"x"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function wo(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}function Mo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=uo(s,r,n);const l=_o(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Wi(e,l);for(const e of h){const s=_o(i,o[e.start],o[e.end],e.loop),r=Vi(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:yo(l,s,"start",Math.max)},end:{[i]:yo(l,s,"end",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,vo(t,a,d&&_o(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():wo(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||wo(t,s,h,n)}t.closePath(),t.fill(f?"evenodd":"nonzero"),t.restore()}}function ko(t,e,i){const s=po(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Qt(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?"angle":e.axis;t.save(),"x"===l&&o!==n&&(bo(t,s,a.top),Mo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),bo(t,s,a.bottom)),Mo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),te(t))}var So={id:"filler",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof qn&&(l={visible:t.isDatasetVisible(a),index:a,fill:lo(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=xo(n,a,i.propagate))},beforeDraw(t,e,i){const s="beforeDraw"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&ko(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;i&&ko(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;s&&!1!==s.fill&&"beforeDatasetDraw"===i.drawTime&&ko(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const Po=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Do extends Ds{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=J(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=He(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Po(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:o}}=this,a=Ei(o,this.left,this.width);if(this.isHorizontal()){let o=0,r=n(i,this.left+s,this.right-this.lineWidths[o]);for(const l of e)o!==l.row&&(o=l.row,r=n(i,this.left+s,this.right-this.lineWidths[o])),l.top+=this.top+t+s,l.left=a.leftForLtr(a.x(r),l.width),r+=l.width+s}else{let o=0,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height);for(const l of e)l.col!==o&&(o=l.col,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height)),l.top=r,l.left+=this.left+s,l.left=a.leftForLtr(a.x(l.left),l.width),r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Qt(t,this),this._draw(),te(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:a,labels:r}=t,l=bt.color,h=Ei(t.rtl,this.left,this.width),c=He(r.font),{color:d,padding:u}=r,f=c.size,g=f/2;let p;this.drawTitle(),s.textAlign=h.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=c.string;const{boxWidth:m,boxHeight:x,itemHeight:b}=Po(r,f),_=this.isHorizontal(),y=this._computeTitleHeight();p=_?{x:n(a,this.left+u,this.right-i[0]),y:this.top+u+y,line:0}:{x:this.left+u,y:n(a,this.top+y+u,this.bottom-e[0].height),line:0},Ii(this.ctx,t.textDirection);const v=b+u;this.legendItems.forEach(((w,M)=>{s.strokeStyle=w.fontColor||d,s.fillStyle=w.fontColor||d;const k=s.measureText(w.text).width,S=h.textAlign(w.textAlign||(w.textAlign=r.textAlign)),P=m+g+k;let D=p.x,C=p.y;h.setWidth(this.width),_?M>0&&D+P+u>this.right&&(C=p.y+=v,p.line++,D=p.x=n(a,this.left+u,this.right-i[p.line])):M>0&&C+v>this.bottom&&(D=p.x=D+e[p.line].width+u,p.line++,C=p.y=n(a,this.top+y+u,this.bottom-e[p.line].height));!function(t,e,i){if(isNaN(m)||m<=0||isNaN(x)||x<0)return;s.save();const n=K(i.lineWidth,1);if(s.fillStyle=K(i.fillStyle,l),s.lineCap=K(i.lineCap,"butt"),s.lineDashOffset=K(i.lineDashOffset,0),s.lineJoin=K(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=K(i.strokeStyle,l),s.setLineDash(K(i.lineDash,[])),r.usePointStyle){const o={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},a=h.xPlus(t,m/2);Zt(s,o,a,e+g)}else{const o=e+Math.max((f-x)/2,0),a=h.leftForLtr(t,m),r=We(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?oe(s,{x:a,y:o,w:m,h:x,radius:r}):s.rect(a,o,m,x),s.fill(),0!==n&&s.stroke()}s.restore()}(h.x(D),C,w),D=o(S,D+m+g,_?D+P:this.right,t.rtl),function(t,e,i){se(s,i.text,t,e+b/2,c,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(D),C,w),_?p.x+=P+u:p.y+=v})),zi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=He(e.font),o=Ne(e.padding);if(!e.display)return;const a=Ei(t.rtl,this.left,this.width),r=this.ctx,l=e.position,h=i.size/2,c=o.top+h;let d,u=this.left,f=this.width;if(this.isHorizontal())f=Math.max(...this.lineWidths),d=this.top+c,u=n(t.align,u,this.right-f);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);d=c+n(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const g=n(l,u,u+f);r.textAlign=a.textAlign(s(l)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=i.string,se(r,e.text,g,d,i)}_computeTitleHeight(){const t=this.options.title,e=He(t.font),i=Ne(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Yt(t,this.left,this.right)&&Yt(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],Yt(t,s.left,s.left+s.width)&&Yt(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if("mousemove"===t&&(e.onHover||e.onLeave))return!0;if(e.onClick&&("click"===t||"mouseup"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if("mousemove"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&J(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&J(e.onHover,[t,i,this],this)}else i&&J(e.onClick,[t,i,this],this);var s,n}}var Co={id:"legend",_element:Do,start(t,e,i){const s=t.legend=new Do({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s)},stop(t){ni.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;ni.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=Ne(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Oo extends Ds{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=Y(i.text)?i.text.length:1;this._padding=Ne(i.padding);const n=s*He(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=n:this.width=n}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:o,options:a}=this,r=a.align;let l,h,c,d=0;return this.isHorizontal()?(h=n(r,i,o),c=e+t,l=o-i):("left"===a.position?(h=i+t,c=n(r,s,e),d=-.5*_t):(h=o-t,c=n(r,e,s),d=.5*_t),l=s-e),{titleX:h,titleY:c,maxWidth:l,rotation:d}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=He(e.font),n=i.lineHeight/2+this._padding.top,{titleX:o,titleY:a,maxWidth:r,rotation:l}=this._drawArgs(n);se(t,e.text,0,0,i,{color:e.color,maxWidth:r,rotation:l,textAlign:s(e.align),textBaseline:"middle",translation:[o,a]})}}var Ao={id:"title",_element:Oo,start(t,e,i){!function(t,e){const i=new Oo({ctx:t.ctx,options:e,chart:t});ni.configure(t,i,e),ni.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ni.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const To=new WeakMap;var Lo={id:"subtitle",start(t,e,i){const s=new Oo({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s),To.set(t,s)},stop(t){ni.removeBox(t,To.get(t)),To.delete(t)},beforeUpdate(t,e,i){const s=To.get(t);ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Ro={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=Vt(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function Eo(t,e){return e&&(Y(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Io(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function zo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Fo(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=He(e.bodyFont),h=He(e.titleFont),c=He(e.footerFont),d=o.length,u=n.length,f=s.length,g=Ne(e.padding);let p=g.height,m=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),x){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-f)*l.lineHeight+(x-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*c.lineHeight+(u-1)*e.footerSpacing);let b=0;const _=function(t){m=Math.max(m,i.measureText(t).width+b)};return i.save(),i.font=h.string,Q(t.title,_),i.font=l.string,Q(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?a+2+e.boxPadding:0,Q(s,(t=>{Q(t.before,_),Q(t.lines,_),Q(t.after,_)})),b=0,i.font=c.string,Q(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function Bo(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Vo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?"top":i>t.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||Bo(t,e,i,s),yAlign:s}}function Wo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:jt(g,0,s.width-e.width),y:jt(p,0,s.height-e.height)}}function No(t,e,i){const s=Ne(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function Ho(t){return Eo([],Io(t))}function jo(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class $o extends Ds{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new gs(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,Ye(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}getBeforeBody(t,e){return Ho(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return Q(t,(t=>{const e={before:[],lines:[],after:[]},n=jo(i,t);Eo(e.before,Io(n.beforeLabel.call(this,t))),Eo(e.lines,n.label.call(this,t)),Eo(e.after,Io(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return Ho(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(zo(this.chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),Q(l,(e=>{const i=jo(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Ro[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Fo(this,i),a=Object.assign({},t,e),r=Vo(this.chart,i,a),l=Wo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=We(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=He(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,n){const o=this.labelColors[i],a=this.labelPointStyles[i],{boxHeight:r,boxWidth:l,boxPadding:h}=n,c=He(n.bodyFont),d=No(this,"left",n),u=s.x(d),f=r<c.lineHeight?(c.lineHeight-r)/2:0,g=e.y+f;if(n.usePointStyle){const e={radius:Math.min(l,r)/2,pointStyle:a.pointStyle,rotation:a.rotation,borderWidth:1},i=s.leftForLtr(u,l)+l/2,h=g+r/2;t.strokeStyle=n.multiKeyBackground,t.fillStyle=n.multiKeyBackground,Zt(t,e,i,h),t.strokeStyle=o.borderColor,t.fillStyle=o.backgroundColor,Zt(t,e,i,h)}else{t.lineWidth=o.borderWidth||1,t.strokeStyle=o.borderColor,t.setLineDash(o.borderDash||[]),t.lineDashOffset=o.borderDashOffset||0;const e=s.leftForLtr(u,l-h),i=s.leftForLtr(s.xPlus(u,1),l-h-2),a=We(o.borderRadius);Object.values(a).some((t=>0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,oe(t,{x:e,y:g,w:l,h:r,radius:a}),t.fill(),t.stroke(),t.fillStyle=o.backgroundColor,t.beginPath(),oe(t,{x:i,y:g+1,w:l-2,h:r-2,radius:a}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,l,r),t.strokeRect(e,g,l,r),t.fillStyle=o.backgroundColor,t.fillRect(i,g+1,l-2,r-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=He(i.bodyFont);let d=c.lineHeight,u=0;const f=Ei(i.rtl,this.x,this.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+n},p=f.textAlign(o);let m,x,b,_,y,v,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=No(this,p,i),e.fillStyle=i.bodyColor,Q(this.beforeBody,g),u=a&&"right"!==p?"center"===o?l/2+h:l+2+h:0,_=0,v=s.length;_<v;++_){for(m=s[_],x=this.labelTextColors[_],e.fillStyle=x,Q(m.before,g),b=m.lines,a&&b.length&&(this._drawColorBox(e,t,_,f,i),d=Math.max(c.lineHeight,r)),y=0,w=b.length;y<w;++y)g(b[y]),d=c.lineHeight;Q(m.after,g)}u=0,d=c.lineHeight,Q(this.afterBody,g),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline="middle",o=He(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),"top"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),"center"===o&&"right"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),"bottom"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),"center"===o&&"left"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Ro[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Fo(this,t),a=Object.assign({},i,this._size),r=Vo(e,t,a),l=Wo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=Ne(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ii(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),zi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!tt(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!tt(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Ro[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}$o.positioners=Ro;var Yo={id:"tooltip",_element:$o,positioners:Ro,afterInit(t,e,i){i&&(t.tooltip=new $o({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip,i={tooltip:e};!1!==t.notifyPlugins("beforeTooltipDraw",i)&&(e&&e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i))},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:H,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return""},afterTitle:H,beforeBody:H,beforeLabel:H,label(t){if(this&&this.options&&"dataset"===this.options.mode)return t.label+": "+t.formattedValue||t.formattedValue;let e=t.dataset.label||"";e&&(e+=": ");const i=t.formattedValue;return $(i)||(e+=i),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:H,afterBody:H,beforeFooter:H,footer:H,afterFooter:H}},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Uo=Object.freeze({__proto__:null,Decimation:ro,Filler:So,Legend:Co,SubTitle:Lo,Title:Ao,Tooltip:Yo});function Xo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class qo extends Bs{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if($(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:jt(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:Xo(i,t,K(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function Ko(t,e,{horizontal:i,minRotation:s}){const n=It(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}qo.id="category",qo.defaults={ticks:{callback:qo.prototype.getLabelForValue}};class Go extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return $(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=Ct(s),e=Ct(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const s=function(t,e){const i=[],{bounds:s,step:n,min:o,max:a,precision:r,count:l,maxTicks:h,maxDigits:c,includeBounds:d}=t,u=n||1,f=h-1,{min:g,max:p}=e,m=!$(o),x=!$(a),b=!$(l),_=(p-g)/(c+1);let y,v,w,M,k=Ot((p-g)/f/u)*u;if(k<1e-14&&!m&&!x)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Ot(M*k/f/u)*u),$(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===s?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&x&&n&&Rt((a-o)/n,k/1e3)?(M=Math.round(Math.min((a-o)/k,h)),k=(a-o)/M,v=o,w=a):b?(v=m?o:v,w=x?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=Lt(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(Ft(k),Ft(v));y=Math.pow(10,$(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==o?(i.push({value:o}),v<o&&P++,Lt(Math.round((v+P*k)*y)/y,o,Ko(o,_,t))&&P++):v<o&&P++);P<M;++P)i.push({value:Math.round((v+P*k)*y)/y});return x&&d&&w!==a?i.length&&Lt(i[i.length-1].value,a,Ko(a,_,t))?i[i.length-1].value=a:i.push({value:a}):x&&w!==a||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&Et(s,this,"value"),t.reverse?(s.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),s}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return Ri(t,this.chart.options.locale,this.options.ticks.format)}}class Zo extends Go{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?t:0,this.max=X(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=It(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function Jo(t){return 1===t/Math.pow(10,Math.floor(Dt(t)))}Zo.id="linear",Zo.defaults={ticks:{callback:Os.formatters.numeric}};class Qo extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=Go.prototype.parse.apply(this,[t,e]);if(0!==i)return X(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?Math.max(0,t):null,this.max=X(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(Dt(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(Dt(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=q(t.min,Math.pow(10,Math.floor(Dt(e.min)))),a=Math.floor(Dt(o)),r=Math.floor(o/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{n.push({value:o,major:Jo(o)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),o=Math.round(r*Math.pow(10,a)*l)/l}while(a<i||a===i&&r<s);const h=q(t.max,o);return n.push({value:h,major:Jo(o)}),n}({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&Et(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":Ri(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=Dt(t),this._valueRange=Dt(this.max)-Dt(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(Dt(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function ta(t){const e=t.ticks;if(e.display&&t.display){const t=Ne(e.backdropPadding);return K(e.font&&e.font.size,bt.font.size)+t.height}return 0}function ea(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function ia(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],n=[],o=t._pointLabels.length,a=t.options.pointLabels,r=a.centerPointLabels?_t/o:0;for(let d=0;d<o;d++){const o=a.setContext(t.getPointLabelContext(d));n[d]=o.padding;const u=t.getPointPosition(d,t.drawingArea+n[d],r),f=He(o.font),g=(l=t.ctx,h=f,c=Y(c=t._pointLabels[d])?c:[c],{w:qt(l,h.string,c),h:c.length*h.lineHeight});s[d]=g;const p=Nt(t.getIndexAngle(d)+r),m=Math.round(zt(p));sa(i,e,p,ea(m,u.x,g.w,0,180),ea(m,u.y,g.h,90,270))}var l,h,c;t.setCenterPoint(e.l-i.l,i.r-e.r,e.t-i.t,i.b-e.b),t._pointLabelItems=function(t,e,i){const s=[],n=t._pointLabels.length,o=t.options,a=ta(o)/2,r=t.drawingArea,l=o.pointLabels.centerPointLabels?_t/n:0;for(let o=0;o<n;o++){const n=t.getPointPosition(o,r+a+i[o],l),h=Math.round(zt(Nt(n.angle+kt))),c=e[o],d=aa(n.y,c.h,h),u=na(h),f=oa(n.x,c.w,u);s.push({x:n.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,s,n)}function sa(t,e,i,s,n){const o=Math.abs(Math.sin(i)),a=Math.abs(Math.cos(i));let r=0,l=0;s.start<e.l?(r=(e.l-s.start)/o,t.l=Math.min(t.l,e.l-r)):s.end>e.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.start<e.t?(l=(e.t-n.start)/a,t.t=Math.min(t.t,e.t-l)):n.end>e.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function na(t){return 0===t||180===t?"center":t<180?"left":"right"}function oa(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function aa(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function ra(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,yt);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}Qo.id="logarithmic",Qo.defaults={ticks:{callback:Os.formatters.logarithmic,major:{enabled:!0}}};class la extends Go{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=Ne(ta(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=X(t)&&!isNaN(t)?t:0,this.max=X(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/ta(this.options))}generateTickLabels(t){Go.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=J(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?ia(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return Nt(t*(yt/(this._pointLabels.length||1))+It(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if($(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if($(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return Ye(t,{label:i,index:e,type:"pointLabel"})}(this.getContext(),t,i)}}getPointPosition(t,e,i=0){const s=this.getIndexAngle(t)-kt+i;return{x:Math.cos(s)*e+this.xCenter,y:Math.sin(s)*e+this.yCenter,angle:s}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),ra(this,this.getDistanceFromCenterForValue(this._endValue),e,this._pointLabels.length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:i,grid:s}=e,n=this._pointLabels.length;let o,a,r;if(e.pointLabels.display&&function(t,e){const{ctx:i,options:{pointLabels:s}}=t;for(let n=e-1;n>=0;n--){const e=s.setContext(t.getPointLabelContext(n)),o=He(e.font),{x:a,y:r,textAlign:l,left:h,top:c,right:d,bottom:u}=t._pointLabelItems[n],{backdropColor:f}=e;if(!$(f)){const t=Ne(e.backdropPadding);i.fillStyle=f,i.fillRect(h-t.left,c-t.top,d-h+t.width,u-c+t.height)}se(i,t._pointLabels[n],a,r+o.lineHeight/2,o,{color:e.color,textAlign:l,textBaseline:"middle"})}}(this,n),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e){a=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),ra(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,s.setContext(this.getContext(e-1)),a,n)}})),i.display){for(t.save(),o=n-1;o>=0;o--){const s=i.setContext(this.getPointLabelContext(o)),{color:n,lineWidth:l}=s;l&&n&&(t.lineWidth=l,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,a=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),r=this.getPointPosition(o,a),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(r.x,r.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=He(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=Ne(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}se(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}la.id="radialLinear",la.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Os.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},la.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},la.descriptors={angleLines:{_fallback:"grid"}};const ha={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}},ca=Object.keys(ha);function da(t,e){return t-e}function ua(t,e){if($(e))return null;const i=t._adapter,{parser:s,round:n,isoWeekday:o}=t._parseOpts;let a=e;return"function"==typeof s&&(a=s(a)),X(a)||(a="string"==typeof s?i.parse(a,s):i.parse(a)),null===a?null:(n&&(a="week"!==n||!Tt(o)&&!0!==o?i.startOf(a,n):i.startOf(a,"isoWeek",o)),+a)}function fa(t,e,i,s){const n=ca.length;for(let o=ca.indexOf(t);o<n-1;++o){const t=ha[ca[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return ca[o]}return ca[n-1]}function ga(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=ae(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function pa(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class ma extends Bs{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new mn._date(t.adapters.date);ot(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:ua(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:a}=this.getUserBounds();function r(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),a||isNaN(t.max)||(n=Math.max(n,t.max))}o&&a||(r(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||r(this.getMinMax(!1))),s=X(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=X(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=he(s,n,this.max);return this._unit=e.unit||(i.autoSkip?fa(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ca.length-1;o>=ca.indexOf(i);o--){const i=ca[o];if(ha[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ca[i?ca.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=ca.indexOf(t)+1,i=ca.length;e<i;++e)if(ha[ca[e]].common)return ca[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),pa(this,o,this._majorUnit)}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=jt(s,0,o),n=jt(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||fa(n.minUnit,e,i,this._getLabelCapacity(e)),a=K(n.stepSize,1),r="week"===o&&n.isoWeekday,l=Tt(r)||!0===r,h={};let c,d,u=e;if(l&&(u=+t.startOf(u,"isoWeek",r)),u=+t.startOf(u,l?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const f="data"===s.ticks.source&&this.getDataTimestamps();for(c=u,d=0;c<i;c=+t.add(c,a,o),d++)ga(h,c,f);return c!==i&&"ticks"!==s.bounds&&1!==d||ga(h,c,f),Object.keys(h).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],c=i[e],d=r&&h&&c&&c.major,u=this._adapter.format(t,s||(d?h:l)),f=n.ticks.callback;return f?J(f,[u,e,i],this):u}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=It(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,pa(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(ua(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return fe(t.sort(da))}}function xa(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=re(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=re(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}ma.id="time",ma.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ba extends ma{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=xa(e,this.min),this._tableRange=xa(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(xa(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return xa(this._table,i*this._tableRange+this._minPos,!0)}}ba.id="timeseries",ba.defaults=ma.defaults;var _a=Object.freeze({__proto__:null,CategoryScale:qo,LinearScale:Zo,LogarithmicScale:Qo,RadialLinearScale:la,TimeScale:ma,TimeSeriesScale:ba});return dn.register(Rn,_a,no,Uo),dn.helpers={...Yi},dn._adapters=mn,dn.Animation=us,dn.Animations=gs,dn.animator=a,dn.controllers=Ws.controllers.items,dn.DatasetController=Ps,dn.Element=Ds,dn.elements=no,dn.Interaction=Ee,dn.layouts=ni,dn.platforms=hs,dn.Scale=Bs,dn.Ticks=Os,Object.assign(dn,Rn,_a,no,Uo,hs),dn.Chart=dn,"undefined"!=typeof window&&(window.Chart=dn),dn}));
static/ninjafirewall.js CHANGED
@@ -462,6 +462,20 @@ function nfwjs_referrer_onoff() {
462
  }
463
  }
464
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  // =====================================================================
466
  // File Check.
467
 
462
  }
463
  }
464
 
465
+ function nfwjs_test_headers( homepage ) {
466
+ // Bypass caching
467
+ homepage = homepage +'?'+ Date.now();
468
+
469
+ jQuery('#progress-gif').show();
470
+ jQuery.ajax( {
471
+ url: homepage,
472
+ method: 'HEAD'
473
+ } ).then( function( data, status, xhr ) {
474
+ jQuery('#progress-gif').hide();
475
+ alert( xhr.getAllResponseHeaders() );
476
+ });
477
+ }
478
+
479
  // =====================================================================
480
  // File Check.
481