Version Description
- New dashboard with simple stats.
Download this release
Release Info
Developer | wpchefgadget |
Plugin | Limit Login Attempts Reloaded |
Version | 2.20.0 |
Comparing to | |
See all releases |
Code changes from version 2.19.2 to 2.20.0
- assets/css/limit-login-attempts.css +1 -1
- assets/img/flags/AD.png +0 -0
- assets/img/flags/AE.png +0 -0
- assets/img/flags/AF.png +0 -0
- assets/img/flags/AG.png +0 -0
- assets/img/flags/AI.png +0 -0
- assets/img/flags/AL.png +0 -0
- assets/img/flags/AM.png +0 -0
- assets/img/flags/AN.png +0 -0
- assets/img/flags/AO.png +0 -0
- assets/img/flags/AQ.png +0 -0
- assets/img/flags/AR.png +0 -0
- assets/img/flags/AS.png +0 -0
- assets/img/flags/AT.png +0 -0
- assets/img/flags/AU.png +0 -0
- assets/img/flags/AW.png +0 -0
- assets/img/flags/AX.png +0 -0
- assets/img/flags/AZ.png +0 -0
- assets/img/flags/BA.png +0 -0
- assets/img/flags/BB.png +0 -0
- assets/img/flags/BD.png +0 -0
- assets/img/flags/BE.png +0 -0
- assets/img/flags/BF.png +0 -0
- assets/img/flags/BG.png +0 -0
- assets/img/flags/BH.png +0 -0
- assets/img/flags/BI.png +0 -0
- assets/img/flags/BJ.png +0 -0
- assets/img/flags/BL.png +0 -0
- assets/img/flags/BM.png +0 -0
- assets/img/flags/BN.png +0 -0
- assets/img/flags/BO.png +0 -0
- assets/img/flags/BR.png +0 -0
- assets/img/flags/BS.png +0 -0
- assets/img/flags/BT.png +0 -0
- assets/img/flags/BW.png +0 -0
- assets/img/flags/BY.png +0 -0
- assets/img/flags/BZ.png +0 -0
- assets/img/flags/CA.png +0 -0
- assets/img/flags/CC.png +0 -0
- assets/img/flags/CD.png +0 -0
- assets/img/flags/CF.png +0 -0
- assets/img/flags/CG.png +0 -0
- assets/img/flags/CH.png +0 -0
- assets/img/flags/CI.png +0 -0
- assets/img/flags/CK.png +0 -0
- assets/img/flags/CL.png +0 -0
- assets/img/flags/CM.png +0 -0
- assets/img/flags/CN.png +0 -0
- assets/img/flags/CO.png +0 -0
- assets/img/flags/CR.png +0 -0
- assets/img/flags/CU.png +0 -0
- assets/img/flags/CV.png +0 -0
- assets/img/flags/CW.png +0 -0
- assets/img/flags/CX.png +0 -0
- assets/img/flags/CY.png +0 -0
- assets/img/flags/CZ.png +0 -0
- assets/img/flags/DE.png +0 -0
- assets/img/flags/DJ.png +0 -0
- assets/img/flags/DK.png +0 -0
- assets/img/flags/DM.png +0 -0
- assets/img/flags/DO.png +0 -0
- assets/img/flags/DZ.png +0 -0
- assets/img/flags/EC.png +0 -0
- assets/img/flags/EE.png +0 -0
- assets/img/flags/EG.png +0 -0
- assets/img/flags/EH.png +0 -0
- assets/img/flags/ER.png +0 -0
- assets/img/flags/ES.png +0 -0
- assets/img/flags/ET.png +0 -0
- assets/img/flags/EU.png +0 -0
- assets/img/flags/FI.png +0 -0
- assets/img/flags/FJ.png +0 -0
- assets/img/flags/FK.png +0 -0
- assets/img/flags/FM.png +0 -0
- assets/img/flags/FO.png +0 -0
- assets/img/flags/FR.png +0 -0
- assets/img/flags/GA.png +0 -0
- assets/img/flags/GB.png +0 -0
- assets/img/flags/GD.png +0 -0
- assets/img/flags/GE.png +0 -0
- assets/img/flags/GG.png +0 -0
- assets/img/flags/GH.png +0 -0
- assets/img/flags/GI.png +0 -0
- assets/img/flags/GL.png +0 -0
- assets/img/flags/GM.png +0 -0
- assets/img/flags/GN.png +0 -0
- assets/img/flags/GQ.png +0 -0
- assets/img/flags/GR.png +0 -0
- assets/img/flags/GS.png +0 -0
- assets/img/flags/GT.png +0 -0
- assets/img/flags/GU.png +0 -0
- assets/img/flags/GW.png +0 -0
- assets/img/flags/GY.png +0 -0
- assets/img/flags/HK.png +0 -0
- assets/img/flags/HN.png +0 -0
- assets/img/flags/HR.png +0 -0
- assets/img/flags/HT.png +0 -0
- assets/img/flags/HU.png +0 -0
- assets/img/flags/IC.png +0 -0
- assets/img/flags/ID.png +0 -0
- assets/img/flags/IE.png +0 -0
- assets/img/flags/IL.png +0 -0
- assets/img/flags/IM.png +0 -0
- assets/img/flags/IN.png +0 -0
- assets/img/flags/IQ.png +0 -0
- assets/img/flags/IR.png +0 -0
- assets/img/flags/IS.png +0 -0
- assets/img/flags/IT.png +0 -0
- assets/img/flags/JE.png +0 -0
- assets/img/flags/JM.png +0 -0
- assets/img/flags/JO.png +0 -0
- assets/img/flags/JP.png +0 -0
- assets/img/flags/KE.png +0 -0
- assets/img/flags/KG.png +0 -0
- assets/img/flags/KH.png +0 -0
- assets/img/flags/KI.png +0 -0
- assets/img/flags/KM.png +0 -0
- assets/img/flags/KN.png +0 -0
- assets/img/flags/KP.png +0 -0
- assets/img/flags/KR.png +0 -0
- assets/img/flags/KW.png +0 -0
- assets/img/flags/KY.png +0 -0
- assets/img/flags/KZ.png +0 -0
- assets/img/flags/LA.png +0 -0
- assets/img/flags/LB.png +0 -0
- assets/img/flags/LC.png +0 -0
- assets/img/flags/LI.png +0 -0
- assets/img/flags/LK.png +0 -0
- assets/img/flags/LR.png +0 -0
- assets/img/flags/LS.png +0 -0
- assets/img/flags/LT.png +0 -0
- assets/img/flags/LU.png +0 -0
- assets/img/flags/LV.png +0 -0
- assets/img/flags/LY.png +0 -0
- assets/img/flags/MA.png +0 -0
- assets/img/flags/MC.png +0 -0
- assets/img/flags/MD.png +0 -0
- assets/img/flags/ME.png +0 -0
- assets/img/flags/MF.png +0 -0
- assets/img/flags/MG.png +0 -0
- assets/img/flags/MH.png +0 -0
- assets/img/flags/MK.png +0 -0
- assets/img/flags/ML.png +0 -0
- assets/img/flags/MM.png +0 -0
- assets/img/flags/MN.png +0 -0
- assets/img/flags/MO.png +0 -0
- assets/img/flags/MP.png +0 -0
- assets/img/flags/MQ.png +0 -0
- assets/img/flags/MR.png +0 -0
- assets/img/flags/MS.png +0 -0
- assets/img/flags/MT.png +0 -0
- assets/img/flags/MU.png +0 -0
- assets/img/flags/MV.png +0 -0
- assets/img/flags/MW.png +0 -0
- assets/img/flags/MX.png +0 -0
- assets/img/flags/MY.png +0 -0
- assets/img/flags/MZ.png +0 -0
- assets/img/flags/NA.png +0 -0
- assets/img/flags/NC.png +0 -0
- assets/img/flags/NE.png +0 -0
- assets/img/flags/NF.png +0 -0
- assets/img/flags/NG.png +0 -0
- assets/img/flags/NI.png +0 -0
- assets/img/flags/NL.png +0 -0
- assets/img/flags/NO.png +0 -0
- assets/img/flags/NP.png +0 -0
- assets/img/flags/NR.png +0 -0
- assets/img/flags/NU.png +0 -0
- assets/img/flags/NZ.png +0 -0
- assets/img/flags/OM.png +0 -0
- assets/img/flags/PA.png +0 -0
- assets/img/flags/PE.png +0 -0
- assets/img/flags/PF.png +0 -0
- assets/img/flags/PG.png +0 -0
- assets/img/flags/PH.png +0 -0
- assets/img/flags/PK.png +0 -0
- assets/img/flags/PL.png +0 -0
- assets/img/flags/PN.png +0 -0
- assets/img/flags/PR.png +0 -0
- assets/img/flags/PS.png +0 -0
- assets/img/flags/PT.png +0 -0
- assets/img/flags/PW.png +0 -0
- assets/img/flags/PY.png +0 -0
- assets/img/flags/QA.png +0 -0
- assets/img/flags/RO.png +0 -0
- assets/img/flags/RS.png +0 -0
- assets/img/flags/RU.png +0 -0
- assets/img/flags/RW.png +0 -0
- assets/img/flags/SA.png +0 -0
- assets/img/flags/SB.png +0 -0
- assets/img/flags/SC.png +0 -0
- assets/img/flags/SD.png +0 -0
- assets/img/flags/SE.png +0 -0
- assets/img/flags/SG.png +0 -0
- assets/img/flags/SH.png +0 -0
- assets/img/flags/SI.png +0 -0
- assets/img/flags/SK.png +0 -0
- assets/img/flags/SL.png +0 -0
- assets/img/flags/SM.png +0 -0
- assets/img/flags/SN.png +0 -0
- assets/img/flags/SO.png +0 -0
- assets/img/flags/SR.png +0 -0
- assets/img/flags/SS.png +0 -0
- assets/img/flags/ST.png +0 -0
- assets/img/flags/SV.png +0 -0
- assets/img/flags/SY.png +0 -0
- assets/img/flags/SZ.png +0 -0
- assets/img/flags/TC.png +0 -0
- assets/img/flags/TD.png +0 -0
- assets/img/flags/TF.png +0 -0
- assets/img/flags/TG.png +0 -0
- assets/img/flags/TH.png +0 -0
- assets/img/flags/TJ.png +0 -0
- assets/img/flags/TK.png +0 -0
- assets/img/flags/TL.png +0 -0
- assets/img/flags/TM.png +0 -0
- assets/img/flags/TN.png +0 -0
- assets/img/flags/TO.png +0 -0
- assets/img/flags/TR.png +0 -0
- assets/img/flags/TT.png +0 -0
- assets/img/flags/TV.png +0 -0
- assets/img/flags/TW.png +0 -0
- assets/img/flags/TZ.png +0 -0
- assets/img/flags/UA.png +0 -0
- assets/img/flags/UG.png +0 -0
- assets/img/flags/US.png +0 -0
- assets/img/flags/UY.png +0 -0
- assets/img/flags/UZ.png +0 -0
- assets/img/flags/VA.png +0 -0
- assets/img/flags/VC.png +0 -0
- assets/img/flags/VE.png +0 -0
- assets/img/flags/VG.png +0 -0
- assets/img/flags/VI.png +0 -0
- assets/img/flags/VN.png +0 -0
- assets/img/flags/VU.png +0 -0
- assets/img/flags/WF.png +0 -0
- assets/img/flags/WS.png +0 -0
- assets/img/flags/YE.png +0 -0
- assets/img/flags/YT.png +0 -0
- assets/img/flags/ZA.png +0 -0
- assets/img/flags/ZM.png +0 -0
- assets/img/flags/ZW.png +0 -0
- assets/img/flags/_abkhazia.png +0 -0
- assets/img/flags/_basque-country.png +0 -0
- assets/img/flags/_british-antarctic-territory.png +0 -0
- assets/img/flags/_commonwealth.png +0 -0
- assets/img/flags/_england.png +0 -0
- assets/img/flags/_gosquared.png +0 -0
- assets/img/flags/_kosovo.png +0 -0
- assets/img/flags/_mars.png +0 -0
- assets/img/flags/_nagorno-karabakh.png +0 -0
- assets/img/flags/_nato.png +0 -0
- assets/img/flags/_northern-cyprus.png +0 -0
- assets/img/flags/_olympics.png +0 -0
- assets/img/flags/_red-cross.png +0 -0
- assets/img/flags/_scotland.png +0 -0
- assets/img/flags/_somaliland.png +0 -0
- assets/img/flags/_south-ossetia.png +0 -0
- assets/img/flags/_united-nations.png +0 -0
- assets/img/flags/_unknown.png +0 -0
- assets/img/flags/_wales.png +0 -0
- assets/js/chartjs-gauge.js +357 -0
- assets/sass/_dashboard-page.scss +355 -0
- assets/sass/limit-login-attempts.scss +36 -9
- core/App.php +16 -0
- core/LimitLoginAttempts.php +38 -8
- limit-login-attempts-reloaded.php +2 -2
- readme.txt +4 -1
- resources/countries.php +254 -0
- views/options-page.php +2 -1
- views/tab-dashboard.php +447 -0
- views/tab-logs-custom.php +0 -70
- views/tab-logs-local.php +1 -0
assets/css/limit-login-attempts.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.limit-login-page-settings .field-col{display:inline-block;margin-right:20px}.limit-login-page-settings .limit-login-log table{background-color:#fff}.limit-login-page-settings .limit-login-log table th,.limit-login-page-settings .limit-login-log table td{padding:10px}.limit-login-page-settings .limit-login-log table tr:nth-child(even){background-color:rgba(0,0,0,0.09)}.limit-login-page-settings #limit-login-app-setup-code{width:85%}.limit-login-page-settings .nav-tab-wrapper{position:relative}.limit-login-page-settings .nav-tab-wrapper .llar-failover-link{font-size:14px;float:right;line-height:2}.limit-login-page-settings .limit-login-app-dashboard .llar-table-scroll-wrap{max-height:400px;overflow-y:auto}.limit-login-page-settings .limit-login-app-dashboard .form-table{background-color:#fff;border:1px solid #f4f4f4;border-top:3px solid #3c8dbc;position:relative}.limit-login-page-settings .limit-login-app-dashboard .form-table.llar-preloader:before{content:"";display:block;width:100%;height:100%;background-color:rgba(255,255,255,0.7);z-index:999;position:absolute;top:0;left:0}.limit-login-page-settings .limit-login-app-dashboard .form-table th{font-weight:bold;border-bottom:1px solid #dbdbdb !important}.limit-login-page-settings .limit-login-app-dashboard .form-table th,.limit-login-page-settings .limit-login-app-dashboard .form-table td{padding:10px;border:1px solid #b9b9b9}.limit-login-page-settings .limit-login-app-dashboard .form-table th.llar-col-nowrap,.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-col-nowrap{white-space:nowrap}.limit-login-page-settings .limit-login-app-dashboard .form-table td button{line-height:1;margin-right:5px}.limit-login-page-settings .limit-login-app-dashboard .form-table td button:last-child{margin-right:0}.limit-login-page-settings .limit-login-app-dashboard .form-table td button .dashicons{vertical-align:middle}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions{text-align:center}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn{display:inline-block;line-height:20px;cursor:pointer}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn i{vertical-align:middle}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn:hover i{color:#3c8dbc}.limit-login-page-settings .limit-login-app-dashboard .form-table tr:nth-child(even){background-color:#f9f9f9}.limit-login-page-settings .limit-login-app-dashboard .llar-app-log-pagination>a{font-size:16px;line-height:1.625}.limit-login-page-settings .limit-login-app-dashboard .llar-app-log-pagination .spinner{float:none}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col{-webkit-box-flex:0;-ms-flex:0 0 49%;flex:0 0 49%}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table select{width:100%}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-acl-action-col{text-align:center}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-pass{background-color:#cffbe8}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-allow{background-color:#abdfff}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-deny{background-color:#fd2c2c3d}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-acl-remove{color:crimson;border-color:crimson}.limit-login-page-settings .llar-app-notice{background-color:#fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:15px;border-radius:3px;margin-top:20px;margin-bottom:20px;font-size:14px;border-left:5px solid #ffba00}.limit-login-page-settings .llar-app-notice.success{border-color:#46b450}.limit-login-page-settings .llar-app-notice p{font-size:inherit;margin:0 0 20px}.limit-login-page-settings .llar-app-notice p:last-child{margin-bottom:0}.limit-login-page-settings input[name="admin_notify_email"]{min-width:243px}.limit-login-page-settings .llar-protect-notice{font-size:15px;color:#848484;margin-left:10px}.limit-login-page-settings .llar-protect-notice a{color:#222222;text-decoration:none;border-bottom:1px dashed}.limit-login-page-settings .llar-show-app-fields{position:absolute;right:15px;top:15px;color:#bdbdbd}.limit-login-page-settings .llar-show-app-fields:hover{color:#222}.limit-login-page-settings .llar-app-field{display:none}.limit-login-page-settings .llar-app-field.active{display:table-row}.llar-notice-review,.llar-notice-notify{display:-webkit-box;display:-ms-flexbox;display:flex;padding:15px 20px 0 !important;border-left:4px solid #333 !important}.llar-notice-review .llar-review-image img,.llar-notice-notify .llar-review-image img{margin-top:10px;margin-bottom:20px}.llar-notice-review .llar-review-image span,.llar-notice-notify .llar-review-image span{font-size:80px;color:orange;width:80px;height:auto;margin-bottom:20px}.llar-notice-review .llar-review-info,.llar-notice-notify .llar-review-info{-webkit-box-flex:1;-ms-flex:1;flex:1;margin-left:30px}.llar-notice-review .llar-review-info .llar-buttons,.llar-notice-notify .llar-review-info .llar-buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.llar-notice-review .llar-review-info .llar-buttons li,.llar-notice-notify .llar-review-info .llar-buttons li{margin-right:10px}.llar-notice-review .llar-review-info .llar-buttons li .dashicons,.llar-notice-notify .llar-review-info .llar-buttons li .dashicons{margin-right:5px}.llar-accordion .ui-accordion-header{font-weight:bold;background:#778899;color:#fff}.llar-accordion .ui-accordion-header.ui-accordion-header-active{background:#87CEFA}.custom-app-tab{position:relative}.custom-app-tab .spinner{float:none}.custom-app-tab .llar-app-ajax-msg{font-size:13px;margin-top:5px;display:block}.custom-app-tab .llar-app-ajax-msg.error{color:red}.custom-app-tab .llar-app-ajax-msg.success{color:green}.custom-app-tab .llar-delete-app{color:#dc3232;position:absolute;bottom:15px;right:15px}.custom-app-tab .llar-delete-app:hover{opacity:0.8}.custom-app-tab .llar-why-use-premium-text{margin-top:20px}.custom-app-tab .llar-why-use-premium-text .title{font-weight:bold;font-size:16px;color:#4d4d4d}.custom-app-tab .llar-why-use-premium-text ul li .dashicons{color:#3ab54a;font-size:25px;width:25px;top:-2px;position:relative}#llar-progress-bar{position:fixed;top:0;height:6px;left:0;width:100%;z-index:999999;background-color:#eee}#llar-progress-bar span{height:100%;position:absolute;display:block;width:0;background-color:#00b357;-webkit-transition:width 0.4s;transition:width 0.4s}#llar-header-upgrade-message{text-align:center;background-color:#f5f0c0;color:#222;padding:10px;margin-left:-20px;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.2);box-shadow:0 0 3px rgba(0,0,0,0.2)}#llar-header-upgrade-message p{margin:0}#llar-header-upgrade-message p .dashicons{color:#f2a64c;margin-right:5px}.settings_page_limit-login-attempts .update-nag{display:none}.llar-chart-wrap{width:100%;max-width:900px;margin:0 auto;clear:both}#llar-welcome-page{padding:50px 0}#llar-welcome-page img{max-width:100%;height:auto}#llar-welcome-page .llar-welcome-page-container{width:100%;max-width:760px;margin:0 auto 30px;background-color:#fff;border-radius:4px;-webkit-box-shadow:0 0 4px rgba(0,0,0,0.1);box-shadow:0 0 4px rgba(0,0,0,0.1)}#llar-welcome-page .llar-welcome-page-container.llar-premium{border-top:5px solid #50c1cd}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section{padding:20px;text-align:center}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section .llar-logo{text-align:center;margin-top:20px;margin-bottom:30px}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section h2{font-size:2.4em;line-height:1.4}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section h3{font-size:1.5em;line-height:1.4}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section p{font-size:17px;color:#444}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-video-wrap img{width:100%;height:auto;cursor:pointer}#llar-welcome-page .llar-welcome-page-features{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0 15px;counter-reset:cnt1}#llar-welcome-page .llar-welcome-page-features .llar-feature-item{-webkit-box-flex:0;-ms-flex:0 0 24%;flex:0 0 24%;text-align:center;margin-bottom:40px;position:relative;padding-bottom:60px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:before{content:counter(cnt1);counter-increment:cnt1;position:absolute;left:50%;-webkit-transform:translatex(-50%);transform:translatex(-50%);bottom:0;font-size:1em;font-weight:600;width:40px;height:40px;line-height:40px;text-align:center;border-radius:50%;background-color:#ecedef;color:#979aaa}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:after{position:absolute;content:'';left:-39%;width:69%;height:1px;bottom:1.4em;background-color:#ecedef}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:nth-child(4n+1):after{display:none}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-image{margin-bottom:15px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-info .llar-feature-title{font-weight:bold;margin-bottom:15px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-info .llar-feature-desc{color:#979aaa}@media (max-width: 768px){#llar-welcome-page .llar-welcome-page-features{display:block}}#llar-welcome-page .llar-why-recommend{text-align:left;font-size:17px}#llar-welcome-page .llar-why-recommend ul li span{margin-right:5px;width:auto;height:auto;font-size:25px;vertical-align:middle;color:green}#llar-welcome-page .llar-welcome-list{font-size:17px;text-align:left;line-height:1.4;list-style:none}#llar-welcome-page .llar-welcome-list li span{margin-right:10px;width:auto;height:auto;font-size:22px;vertical-align:top;color:orange}#llar-welcome-page .llar-upgrade-btn-wrap{padding:20px}#llar-welcome-page .llar-upgrade-btn-wrap a{display:inline-block;background-color:#e27800;color:#fff;font-size:22px;padding:20px;text-decoration:none;font-weight:600}#llar-welcome-page .llar-upgrade-btn-wrap a:hover{background-color:#af5d00}#llar-welcome-page .llar-upgrade-questions{font-size:17px}.dashboard_page_llar-welcome .update-nag,.dashboard_page_llar-welcome .notice{display:none}.dashboard_page_llar-welcome .video-container{position:relative;padding-bottom:56.1%;height:0;overflow:hidden}.dashboard_page_llar-welcome .video-container iframe{position:absolute;top:0;left:0;width:100%;height:100%}.jconfirm .jconfirm-box div.jconfirm-closeIcon{top:-2px !important;right:-2px !important}
|
1 |
+
.limit-login-page-settings .field-col{display:inline-block;margin-right:20px}.limit-login-page-settings .limit-login-log table{background-color:#fff}.limit-login-page-settings .limit-login-log table th,.limit-login-page-settings .limit-login-log table td{padding:10px}.limit-login-page-settings .limit-login-log table tr:nth-child(even){background-color:rgba(0,0,0,0.09)}.limit-login-page-settings #limit-login-app-setup-code{width:85%}.limit-login-page-settings .nav-tab-wrapper{position:relative}.limit-login-page-settings .nav-tab-wrapper .llar-failover-link{font-size:14px;float:right;line-height:2}.limit-login-page-settings .limit-login-app-dashboard .llar-table-scroll-wrap{max-height:400px;overflow-y:auto}.limit-login-page-settings .limit-login-app-dashboard .form-table{background-color:#fff;border:1px solid #f4f4f4;border-top:3px solid #3c8dbc;position:relative}.limit-login-page-settings .limit-login-app-dashboard .form-table.llar-preloader:before{content:"";display:block;width:100%;height:100%;background-color:rgba(255,255,255,0.7);z-index:999;position:absolute;top:0;left:0}.limit-login-page-settings .limit-login-app-dashboard .form-table th{font-weight:bold;border-bottom:1px solid #dbdbdb !important}.limit-login-page-settings .limit-login-app-dashboard .form-table th,.limit-login-page-settings .limit-login-app-dashboard .form-table td{padding:10px;border:1px solid #b9b9b9}.limit-login-page-settings .limit-login-app-dashboard .form-table th.llar-col-nowrap,.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-col-nowrap{white-space:nowrap}.limit-login-page-settings .limit-login-app-dashboard .form-table td button{line-height:1;margin-right:5px}.limit-login-page-settings .limit-login-app-dashboard .form-table td button:last-child{margin-right:0}.limit-login-page-settings .limit-login-app-dashboard .form-table td button .dashicons{vertical-align:middle}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions{text-align:center}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn{display:inline-block;line-height:20px;cursor:pointer}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn i{vertical-align:middle}.limit-login-page-settings .limit-login-app-dashboard .form-table td.llar-app-log-actions .llar-app-log-action-btn:hover i{color:#3c8dbc}.limit-login-page-settings .limit-login-app-dashboard .form-table tr:nth-child(even){background-color:#f9f9f9}.limit-login-page-settings .limit-login-app-dashboard .llar-app-log-pagination>a{font-size:16px;line-height:1.625}.limit-login-page-settings .limit-login-app-dashboard .llar-app-log-pagination .spinner{float:none}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col{-webkit-box-flex:0;-ms-flex:0 0 49%;flex:0 0 49%}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table select{width:100%}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-acl-action-col{text-align:center}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-pass{background-color:#cffbe8}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-allow{background-color:#abdfff}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-rule-deny{background-color:#fd2c2c3d}.limit-login-page-settings .limit-login-app-dashboard .llar-app-acl-rules .app-rules-col .form-table .llar-app-acl-remove{color:crimson;border-color:crimson}.limit-login-page-settings .llar-app-notice{background-color:#fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:15px;border-radius:3px;margin-top:20px;margin-bottom:20px;font-size:14px;border-left:5px solid #ffba00}.limit-login-page-settings .llar-app-notice.success{border-color:#46b450}.limit-login-page-settings .llar-app-notice p{font-size:inherit;margin:0 0 20px}.limit-login-page-settings .llar-app-notice p:last-child{margin-bottom:0}.limit-login-page-settings input[name="admin_notify_email"]{min-width:243px}.limit-login-page-settings .llar-protect-notice{font-size:15px;color:#848484;margin-left:10px}.limit-login-page-settings .llar-protect-notice a{color:#222222;text-decoration:none;border-bottom:1px dashed}.limit-login-page-settings .llar-show-app-fields{position:absolute;right:15px;top:15px;color:#bdbdbd}.limit-login-page-settings .llar-show-app-fields:hover{color:#222}.limit-login-page-settings .llar-app-field{display:none}.limit-login-page-settings .llar-app-field.active{display:table-row}.llar-notice-review,.llar-notice-notify{display:-webkit-box;display:-ms-flexbox;display:flex;padding:15px 20px 0 !important;border-left:4px solid #333 !important}.llar-notice-review .llar-review-image img,.llar-notice-notify .llar-review-image img{margin-top:10px;margin-bottom:20px}.llar-notice-review .llar-review-image span,.llar-notice-notify .llar-review-image span{font-size:80px;color:orange;width:80px;height:auto;margin-bottom:20px}.llar-notice-review .llar-review-info,.llar-notice-notify .llar-review-info{-webkit-box-flex:1;-ms-flex:1;flex:1;margin-left:30px}.llar-notice-review .llar-review-info .llar-buttons,.llar-notice-notify .llar-review-info .llar-buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.llar-notice-review .llar-review-info .llar-buttons li,.llar-notice-notify .llar-review-info .llar-buttons li{margin-right:10px}.llar-notice-review .llar-review-info .llar-buttons li .dashicons,.llar-notice-notify .llar-review-info .llar-buttons li .dashicons{margin-right:5px}.llar-accordion .ui-accordion-header{font-weight:bold;background:#778899;color:#fff}.llar-accordion .ui-accordion-header.ui-accordion-header-active{background:#87CEFA}.custom-app-tab{position:relative}.custom-app-tab .spinner{float:none}.custom-app-tab .llar-app-ajax-msg{font-size:13px;margin-top:5px;display:block}.custom-app-tab .llar-app-ajax-msg.error{color:red}.custom-app-tab .llar-app-ajax-msg.success{color:green}.custom-app-tab .llar-delete-app{color:#dc3232;position:absolute;bottom:15px;right:15px}.custom-app-tab .llar-delete-app:hover{opacity:0.8}.custom-app-tab .llar-why-use-premium-text{margin-top:20px}.custom-app-tab .llar-why-use-premium-text .title{font-weight:bold;font-size:16px;color:#4d4d4d}.custom-app-tab .llar-why-use-premium-text ul li .dashicons{color:#3ab54a;font-size:25px;width:25px;top:-2px;position:relative}#llar-progress-bar{position:fixed;top:0;height:6px;left:0;width:100%;z-index:999999;background-color:#eee}#llar-progress-bar span{height:100%;position:absolute;display:block;width:0;background-color:#00b357;-webkit-transition:width 0.4s;transition:width 0.4s}#llar-header-upgrade-message{text-align:center;background-color:#f5f0c0;color:#222;padding:10px;margin-left:-20px;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.2);box-shadow:0 0 3px rgba(0,0,0,0.2)}#llar-header-upgrade-message p{margin:0}#llar-header-upgrade-message p .dashicons{color:#f2a64c;margin-right:5px}.settings_page_limit-login-attempts .update-nag{display:none}#llar-welcome-page{padding:50px 0}#llar-welcome-page img{max-width:100%;height:auto}#llar-welcome-page .llar-welcome-page-container{width:100%;max-width:760px;margin:0 auto 30px;background-color:#fff;border-radius:4px;-webkit-box-shadow:0 0 4px rgba(0,0,0,0.1);box-shadow:0 0 4px rgba(0,0,0,0.1)}#llar-welcome-page .llar-welcome-page-container.llar-premium{border-top:5px solid #50c1cd}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section{padding:20px;text-align:center}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section .llar-logo{text-align:center;margin-top:20px;margin-bottom:30px}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section h2{font-size:2.4em;line-height:1.4}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section h3{font-size:1.5em;line-height:1.4}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-section p{font-size:17px;color:#444}#llar-welcome-page .llar-welcome-page-container .llar-welcome-page-video-wrap img{width:100%;height:auto;cursor:pointer}#llar-welcome-page .llar-welcome-page-features{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0 15px;counter-reset:cnt1}#llar-welcome-page .llar-welcome-page-features .llar-feature-item{-webkit-box-flex:0;-ms-flex:0 0 24%;flex:0 0 24%;text-align:center;margin-bottom:40px;position:relative;padding-bottom:60px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:before{content:counter(cnt1);counter-increment:cnt1;position:absolute;left:50%;-webkit-transform:translatex(-50%);transform:translatex(-50%);bottom:0;font-size:1em;font-weight:600;width:40px;height:40px;line-height:40px;text-align:center;border-radius:50%;background-color:#ecedef;color:#979aaa}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:after{position:absolute;content:'';left:-39%;width:69%;height:1px;bottom:1.4em;background-color:#ecedef}#llar-welcome-page .llar-welcome-page-features .llar-feature-item:nth-child(4n+1):after{display:none}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-image{margin-bottom:15px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-info .llar-feature-title{font-weight:bold;margin-bottom:15px}#llar-welcome-page .llar-welcome-page-features .llar-feature-item .llar-feature-info .llar-feature-desc{color:#979aaa}@media (max-width: 768px){#llar-welcome-page .llar-welcome-page-features{display:block}}#llar-welcome-page .llar-why-recommend{text-align:left;font-size:17px}#llar-welcome-page .llar-why-recommend ul li span{margin-right:5px;width:auto;height:auto;font-size:25px;vertical-align:middle;color:green}#llar-welcome-page .llar-welcome-list{font-size:17px;text-align:left;line-height:1.4;list-style:none}#llar-welcome-page .llar-welcome-list li span{margin-right:10px;width:auto;height:auto;font-size:22px;vertical-align:top;color:orange}#llar-welcome-page .llar-upgrade-btn-wrap{padding:20px}#llar-welcome-page .llar-upgrade-btn-wrap a{display:inline-block;background-color:#e27800;color:#fff;font-size:22px;padding:20px;text-decoration:none;font-weight:600}#llar-welcome-page .llar-upgrade-btn-wrap a:hover{background-color:#af5d00}#llar-welcome-page .llar-upgrade-questions{font-size:17px}.dashboard_page_llar-welcome .update-nag,.dashboard_page_llar-welcome .notice,.toplevel_page_limit-login-attempts .update-nag,.toplevel_page_limit-login-attempts .notice{display:none}.dashboard_page_llar-welcome .video-container,.toplevel_page_limit-login-attempts .video-container{position:relative;padding-bottom:56.1%;height:0;overflow:hidden}.dashboard_page_llar-welcome .video-container iframe,.toplevel_page_limit-login-attempts .video-container iframe{position:absolute;top:0;left:0;width:100%;height:100%}.jconfirm .jconfirm-box div.jconfirm-closeIcon{top:-2px !important;right:-2px !important}.llar-tooltip{text-decoration:underline;-webkit-text-decoration-style:dotted;text-decoration-style:dotted;cursor:pointer;position:relative}.llar-tooltip:before{content:attr(data-text);position:absolute;width:200px;padding:5px;background-color:rgba(0,0,0,0.8);color:#fff;font-size:13px;top:100%;z-index:999;visibility:hidden;opacity:0;-webkit-transition:all .2s;transition:all .2s;font-weight:300;cursor:auto}.llar-tooltip:hover:before{visibility:visible;opacity:1}#llar-dashboard-page{padding-top:10px}#llar-dashboard-page *{-webkit-box-sizing:border-box;box-sizing:border-box}#llar-dashboard-page .dashboard-header{background-color:#0071a0;color:#fff;text-align:center;padding:15px}#llar-dashboard-page .dashboard-header h1{color:#fff}#llar-dashboard-page .section-title{font-weight:bold;padding:15px;border-bottom:1px solid #e4e4e4;font-size:14px;text-align:left}#llar-dashboard-page .section-content{padding:15px}#llar-dashboard-page .dashboard-section-1{margin-bottom:20px;background-color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}#llar-dashboard-page .dashboard-section-1>[class^="info-box-"]{text-align:center;-webkit-box-flex:0;-ms-flex:0 0 33.333%;flex:0 0 33.333%;max-width:33.333%;border-right:1px solid #e4e4e4}#llar-dashboard-page .dashboard-section-1>[class^="info-box-"]:last-child{border:0}#llar-dashboard-page .dashboard-section-1>[class^="info-box-"] .title{font-weight:600;font-size:16px;line-height:1.5;margin-bottom:10px}#llar-dashboard-page .dashboard-section-1 .info-box-1 .chart{max-width:300px;position:relative;margin-bottom:15px;margin-left:auto;margin-right:auto}#llar-dashboard-page .dashboard-section-1 .info-box-1 .chart .llar-retries-count{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);font-size:28px;font-weight:bold}#llar-dashboard-page .dashboard-section-1 .info-box-1 .desc{font-size:15px}#llar-dashboard-page .dashboard-section-1 .info-box-1 .actions{margin-top:5px}#llar-dashboard-page .dashboard-section-1 .info-box-2 .llar-chart-wrap{width:100%;max-width:80%;margin:0 auto;clear:both}#llar-dashboard-page .dashboard-section-1 .info-box-2 .llar-chart-wrap canvas{height:300px}#llar-dashboard-page .dashboard-section-1 .info-box-2 .chart-stats-legend{text-align:center;margin-top:10px}#llar-dashboard-page .dashboard-section-1 .info-box-3{text-align:left}#llar-dashboard-page .dashboard-section-1 .info-box-3 .desc{margin-bottom:20px}#llar-dashboard-page .dashboard-section-1 .info-box-3 .actions{text-align:center;padding-top:20px}#llar-dashboard-page .dashboard-section-1 .info-box-3 .actions a{text-transform:uppercase;font-size:16px;margin-bottom:5px}#llar-dashboard-page .dashboard-section-1.custom .info-box-2{-webkit-box-flex:0;-ms-flex:0 0 66.666%;flex:0 0 66.666%;max-width:66.666%}#llar-dashboard-page .dashboard-section-2{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin-bottom:20px}#llar-dashboard-page .dashboard-section-2>[class^="info-box-"]{-webkit-box-flex:0;-ms-flex:0 0 calc(50% - 10px);flex:0 0 calc(50% - 10px);min-height:100px;background-color:#fff;border:1px solid #e4e4e4;padding:15px}#llar-dashboard-page .dashboard-section-2>[class^="info-box-"]:last-child{margin-right:0}#llar-dashboard-page .dashboard-section-2 .info-box-1{padding:0}#llar-dashboard-page .dashboard-section-2 .info-box-1 .notifications-list{padding:0;margin:0}#llar-dashboard-page .dashboard-section-2 .info-box-1 .notifications-list li{margin:0;border-bottom:1px solid #e4e4e4}#llar-dashboard-page .dashboard-section-2 .info-box-1 .notifications-list li:last-child{border:0}#llar-dashboard-page .dashboard-section-2 .info-box-1 .notifications-list li a{text-decoration:none;padding:15px;font-size:15px;display:block}#llar-dashboard-page .dashboard-section-2 .info-box-1 .notifications-list li a:hover{background-color:#f9f9f9}#llar-dashboard-page .dashboard-section-2 .info-box-2{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-icon{-webkit-box-flex:0;-ms-flex:0 0 100px;flex:0 0 100px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-right:15px}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-icon .dashicons{color:#0073a0;font-size:50px;width:auto;height:auto}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-content{-webkit-box-flex:1;-ms-flex:1;flex:1}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-content .title{font-size:20px;font-weight:bold;margin-bottom:10px;line-height:1.5}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-content .desc{font-size:15px;margin-bottom:15px}#llar-dashboard-page .dashboard-section-2 .info-box-2 .info-box-content .actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#llar-dashboard-page .dashboard-section-3{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;background-color:#fff;margin-bottom:20px}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"]{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:30px 15px 30px 0;-webkit-box-flex:1;-ms-flex:1;flex:1;border-right:1px solid #e4e4e4}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-icon{-webkit-box-flex:0;-ms-flex:0 0 100px;flex:0 0 100px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-icon .dashicons{color:#a1a2a2;font-size:60px;width:auto;height:auto}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-content{-webkit-box-flex:1;-ms-flex:1;flex:1}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-content .title{font-size:20px;font-weight:bold;margin-bottom:10px;line-height:1.3}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-content .title a{text-decoration:none}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-content .desc{font-size:15px;margin-bottom:15px}#llar-dashboard-page .dashboard-section-3>[class^="info-box-"] .info-box-content .actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#llar-dashboard-page .dashboard-section-4{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin-bottom:20px}#llar-dashboard-page .dashboard-section-4>[class^="info-box-"]{-webkit-box-flex:0;-ms-flex:0 0 calc(50% - 10px);flex:0 0 calc(50% - 10px);min-height:100px;background-color:#fff;border:1px solid #e4e4e4;padding:15px}#llar-dashboard-page .dashboard-section-4>[class^="info-box-"]:last-child{margin-right:0}#llar-dashboard-page .dashboard-section-4 .info-box-1{padding:0}#llar-dashboard-page .dashboard-section-4 .info-box-1 .section-title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#llar-dashboard-page .dashboard-section-4 .info-box-1 .section-title .section-title-info{color:#a7a7a7;font-weight:400}#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table{width:100%;border-collapse:collapse}#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table tr th,#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table tr td{padding:10px;border:1px solid #cecece}#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table tr th{background-color:#000;color:#fff;text-align:left}#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table tr:nth-child(odd) td{background-color:#eff0ef}#llar-dashboard-page .dashboard-section-4 .info-box-1 .lockouts-by-country-table tr td .flag-icon{width:24px;vertical-align:middle;margin-right:10px}#llar-dashboard-page .dashboard-section-4 .info-box-1 .countries-table-info{color:#a7a7a7;font-weight:400;margin-top:5px;margin-bottom:0}#llar-dashboard-page .dashboard-section-4 .info-box-2{padding:0}#llar-dashboard-page .dashboard-section-4 .info-box-2 .section-title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#llar-dashboard-page .dashboard-section-4 .info-box-2 .section-title .section-title-info{color:#a7a7a7;font-weight:400}#llar-dashboard-page .dashboard-section-4 .info-box-2 .llar-chart-wrap{width:100%;max-width:80%;margin:0 auto;clear:both}#llar-dashboard-page .dashboard-section-4 .info-box-2 .llar-chart-wrap canvas{height:300px}
|
assets/img/flags/AD.png
ADDED
Binary file
|
assets/img/flags/AE.png
ADDED
Binary file
|
assets/img/flags/AF.png
ADDED
Binary file
|
assets/img/flags/AG.png
ADDED
Binary file
|
assets/img/flags/AI.png
ADDED
Binary file
|
assets/img/flags/AL.png
ADDED
Binary file
|
assets/img/flags/AM.png
ADDED
Binary file
|
assets/img/flags/AN.png
ADDED
Binary file
|
assets/img/flags/AO.png
ADDED
Binary file
|
assets/img/flags/AQ.png
ADDED
Binary file
|
assets/img/flags/AR.png
ADDED
Binary file
|
assets/img/flags/AS.png
ADDED
Binary file
|
assets/img/flags/AT.png
ADDED
Binary file
|
assets/img/flags/AU.png
ADDED
Binary file
|
assets/img/flags/AW.png
ADDED
Binary file
|
assets/img/flags/AX.png
ADDED
Binary file
|
assets/img/flags/AZ.png
ADDED
Binary file
|
assets/img/flags/BA.png
ADDED
Binary file
|
assets/img/flags/BB.png
ADDED
Binary file
|
assets/img/flags/BD.png
ADDED
Binary file
|
assets/img/flags/BE.png
ADDED
Binary file
|
assets/img/flags/BF.png
ADDED
Binary file
|
assets/img/flags/BG.png
ADDED
Binary file
|
assets/img/flags/BH.png
ADDED
Binary file
|
assets/img/flags/BI.png
ADDED
Binary file
|
assets/img/flags/BJ.png
ADDED
Binary file
|
assets/img/flags/BL.png
ADDED
Binary file
|
assets/img/flags/BM.png
ADDED
Binary file
|
assets/img/flags/BN.png
ADDED
Binary file
|
assets/img/flags/BO.png
ADDED
Binary file
|
assets/img/flags/BR.png
ADDED
Binary file
|
assets/img/flags/BS.png
ADDED
Binary file
|
assets/img/flags/BT.png
ADDED
Binary file
|
assets/img/flags/BW.png
ADDED
Binary file
|
assets/img/flags/BY.png
ADDED
Binary file
|
assets/img/flags/BZ.png
ADDED
Binary file
|
assets/img/flags/CA.png
ADDED
Binary file
|
assets/img/flags/CC.png
ADDED
Binary file
|
assets/img/flags/CD.png
ADDED
Binary file
|
assets/img/flags/CF.png
ADDED
Binary file
|
assets/img/flags/CG.png
ADDED
Binary file
|
assets/img/flags/CH.png
ADDED
Binary file
|
assets/img/flags/CI.png
ADDED
Binary file
|
assets/img/flags/CK.png
ADDED
Binary file
|
assets/img/flags/CL.png
ADDED
Binary file
|
assets/img/flags/CM.png
ADDED
Binary file
|
assets/img/flags/CN.png
ADDED
Binary file
|
assets/img/flags/CO.png
ADDED
Binary file
|
assets/img/flags/CR.png
ADDED
Binary file
|
assets/img/flags/CU.png
ADDED
Binary file
|
assets/img/flags/CV.png
ADDED
Binary file
|
assets/img/flags/CW.png
ADDED
Binary file
|
assets/img/flags/CX.png
ADDED
Binary file
|
assets/img/flags/CY.png
ADDED
Binary file
|
assets/img/flags/CZ.png
ADDED
Binary file
|
assets/img/flags/DE.png
ADDED
Binary file
|
assets/img/flags/DJ.png
ADDED
Binary file
|
assets/img/flags/DK.png
ADDED
Binary file
|
assets/img/flags/DM.png
ADDED
Binary file
|
assets/img/flags/DO.png
ADDED
Binary file
|
assets/img/flags/DZ.png
ADDED
Binary file
|
assets/img/flags/EC.png
ADDED
Binary file
|
assets/img/flags/EE.png
ADDED
Binary file
|
assets/img/flags/EG.png
ADDED
Binary file
|
assets/img/flags/EH.png
ADDED
Binary file
|
assets/img/flags/ER.png
ADDED
Binary file
|
assets/img/flags/ES.png
ADDED
Binary file
|
assets/img/flags/ET.png
ADDED
Binary file
|
assets/img/flags/EU.png
ADDED
Binary file
|
assets/img/flags/FI.png
ADDED
Binary file
|
assets/img/flags/FJ.png
ADDED
Binary file
|
assets/img/flags/FK.png
ADDED
Binary file
|
assets/img/flags/FM.png
ADDED
Binary file
|
assets/img/flags/FO.png
ADDED
Binary file
|
assets/img/flags/FR.png
ADDED
Binary file
|
assets/img/flags/GA.png
ADDED
Binary file
|
assets/img/flags/GB.png
ADDED
Binary file
|
assets/img/flags/GD.png
ADDED
Binary file
|
assets/img/flags/GE.png
ADDED
Binary file
|
assets/img/flags/GG.png
ADDED
Binary file
|
assets/img/flags/GH.png
ADDED
Binary file
|
assets/img/flags/GI.png
ADDED
Binary file
|
assets/img/flags/GL.png
ADDED
Binary file
|
assets/img/flags/GM.png
ADDED
Binary file
|
assets/img/flags/GN.png
ADDED
Binary file
|
assets/img/flags/GQ.png
ADDED
Binary file
|
assets/img/flags/GR.png
ADDED
Binary file
|
assets/img/flags/GS.png
ADDED
Binary file
|
assets/img/flags/GT.png
ADDED
Binary file
|
assets/img/flags/GU.png
ADDED
Binary file
|
assets/img/flags/GW.png
ADDED
Binary file
|
assets/img/flags/GY.png
ADDED
Binary file
|
assets/img/flags/HK.png
ADDED
Binary file
|
assets/img/flags/HN.png
ADDED
Binary file
|
assets/img/flags/HR.png
ADDED
Binary file
|
assets/img/flags/HT.png
ADDED
Binary file
|
assets/img/flags/HU.png
ADDED
Binary file
|
assets/img/flags/IC.png
ADDED
Binary file
|
assets/img/flags/ID.png
ADDED
Binary file
|
assets/img/flags/IE.png
ADDED
Binary file
|
assets/img/flags/IL.png
ADDED
Binary file
|
assets/img/flags/IM.png
ADDED
Binary file
|
assets/img/flags/IN.png
ADDED
Binary file
|
assets/img/flags/IQ.png
ADDED
Binary file
|
assets/img/flags/IR.png
ADDED
Binary file
|
assets/img/flags/IS.png
ADDED
Binary file
|
assets/img/flags/IT.png
ADDED
Binary file
|
assets/img/flags/JE.png
ADDED
Binary file
|
assets/img/flags/JM.png
ADDED
Binary file
|
assets/img/flags/JO.png
ADDED
Binary file
|
assets/img/flags/JP.png
ADDED
Binary file
|
assets/img/flags/KE.png
ADDED
Binary file
|
assets/img/flags/KG.png
ADDED
Binary file
|
assets/img/flags/KH.png
ADDED
Binary file
|
assets/img/flags/KI.png
ADDED
Binary file
|
assets/img/flags/KM.png
ADDED
Binary file
|
assets/img/flags/KN.png
ADDED
Binary file
|
assets/img/flags/KP.png
ADDED
Binary file
|
assets/img/flags/KR.png
ADDED
Binary file
|
assets/img/flags/KW.png
ADDED
Binary file
|
assets/img/flags/KY.png
ADDED
Binary file
|
assets/img/flags/KZ.png
ADDED
Binary file
|
assets/img/flags/LA.png
ADDED
Binary file
|
assets/img/flags/LB.png
ADDED
Binary file
|
assets/img/flags/LC.png
ADDED
Binary file
|
assets/img/flags/LI.png
ADDED
Binary file
|
assets/img/flags/LK.png
ADDED
Binary file
|
assets/img/flags/LR.png
ADDED
Binary file
|
assets/img/flags/LS.png
ADDED
Binary file
|
assets/img/flags/LT.png
ADDED
Binary file
|
assets/img/flags/LU.png
ADDED
Binary file
|
assets/img/flags/LV.png
ADDED
Binary file
|
assets/img/flags/LY.png
ADDED
Binary file
|
assets/img/flags/MA.png
ADDED
Binary file
|
assets/img/flags/MC.png
ADDED
Binary file
|
assets/img/flags/MD.png
ADDED
Binary file
|
assets/img/flags/ME.png
ADDED
Binary file
|
assets/img/flags/MF.png
ADDED
Binary file
|
assets/img/flags/MG.png
ADDED
Binary file
|
assets/img/flags/MH.png
ADDED
Binary file
|
assets/img/flags/MK.png
ADDED
Binary file
|
assets/img/flags/ML.png
ADDED
Binary file
|
assets/img/flags/MM.png
ADDED
Binary file
|
assets/img/flags/MN.png
ADDED
Binary file
|
assets/img/flags/MO.png
ADDED
Binary file
|
assets/img/flags/MP.png
ADDED
Binary file
|
assets/img/flags/MQ.png
ADDED
Binary file
|
assets/img/flags/MR.png
ADDED
Binary file
|
assets/img/flags/MS.png
ADDED
Binary file
|
assets/img/flags/MT.png
ADDED
Binary file
|
assets/img/flags/MU.png
ADDED
Binary file
|
assets/img/flags/MV.png
ADDED
Binary file
|
assets/img/flags/MW.png
ADDED
Binary file
|
assets/img/flags/MX.png
ADDED
Binary file
|
assets/img/flags/MY.png
ADDED
Binary file
|
assets/img/flags/MZ.png
ADDED
Binary file
|
assets/img/flags/NA.png
ADDED
Binary file
|
assets/img/flags/NC.png
ADDED
Binary file
|
assets/img/flags/NE.png
ADDED
Binary file
|
assets/img/flags/NF.png
ADDED
Binary file
|
assets/img/flags/NG.png
ADDED
Binary file
|
assets/img/flags/NI.png
ADDED
Binary file
|
assets/img/flags/NL.png
ADDED
Binary file
|
assets/img/flags/NO.png
ADDED
Binary file
|
assets/img/flags/NP.png
ADDED
Binary file
|
assets/img/flags/NR.png
ADDED
Binary file
|
assets/img/flags/NU.png
ADDED
Binary file
|
assets/img/flags/NZ.png
ADDED
Binary file
|
assets/img/flags/OM.png
ADDED
Binary file
|
assets/img/flags/PA.png
ADDED
Binary file
|
assets/img/flags/PE.png
ADDED
Binary file
|
assets/img/flags/PF.png
ADDED
Binary file
|
assets/img/flags/PG.png
ADDED
Binary file
|
assets/img/flags/PH.png
ADDED
Binary file
|
assets/img/flags/PK.png
ADDED
Binary file
|
assets/img/flags/PL.png
ADDED
Binary file
|
assets/img/flags/PN.png
ADDED
Binary file
|
assets/img/flags/PR.png
ADDED
Binary file
|
assets/img/flags/PS.png
ADDED
Binary file
|
assets/img/flags/PT.png
ADDED
Binary file
|
assets/img/flags/PW.png
ADDED
Binary file
|
assets/img/flags/PY.png
ADDED
Binary file
|
assets/img/flags/QA.png
ADDED
Binary file
|
assets/img/flags/RO.png
ADDED
Binary file
|
assets/img/flags/RS.png
ADDED
Binary file
|
assets/img/flags/RU.png
ADDED
Binary file
|
assets/img/flags/RW.png
ADDED
Binary file
|
assets/img/flags/SA.png
ADDED
Binary file
|
assets/img/flags/SB.png
ADDED
Binary file
|
assets/img/flags/SC.png
ADDED
Binary file
|
assets/img/flags/SD.png
ADDED
Binary file
|
assets/img/flags/SE.png
ADDED
Binary file
|
assets/img/flags/SG.png
ADDED
Binary file
|
assets/img/flags/SH.png
ADDED
Binary file
|
assets/img/flags/SI.png
ADDED
Binary file
|
assets/img/flags/SK.png
ADDED
Binary file
|
assets/img/flags/SL.png
ADDED
Binary file
|
assets/img/flags/SM.png
ADDED
Binary file
|
assets/img/flags/SN.png
ADDED
Binary file
|
assets/img/flags/SO.png
ADDED
Binary file
|
assets/img/flags/SR.png
ADDED
Binary file
|
assets/img/flags/SS.png
ADDED
Binary file
|
assets/img/flags/ST.png
ADDED
Binary file
|
assets/img/flags/SV.png
ADDED
Binary file
|
assets/img/flags/SY.png
ADDED
Binary file
|
assets/img/flags/SZ.png
ADDED
Binary file
|
assets/img/flags/TC.png
ADDED
Binary file
|
assets/img/flags/TD.png
ADDED
Binary file
|
assets/img/flags/TF.png
ADDED
Binary file
|
assets/img/flags/TG.png
ADDED
Binary file
|
assets/img/flags/TH.png
ADDED
Binary file
|
assets/img/flags/TJ.png
ADDED
Binary file
|
assets/img/flags/TK.png
ADDED
Binary file
|
assets/img/flags/TL.png
ADDED
Binary file
|
assets/img/flags/TM.png
ADDED
Binary file
|
assets/img/flags/TN.png
ADDED
Binary file
|
assets/img/flags/TO.png
ADDED
Binary file
|
assets/img/flags/TR.png
ADDED
Binary file
|
assets/img/flags/TT.png
ADDED
Binary file
|
assets/img/flags/TV.png
ADDED
Binary file
|
assets/img/flags/TW.png
ADDED
Binary file
|
assets/img/flags/TZ.png
ADDED
Binary file
|
assets/img/flags/UA.png
ADDED
Binary file
|
assets/img/flags/UG.png
ADDED
Binary file
|
assets/img/flags/US.png
ADDED
Binary file
|
assets/img/flags/UY.png
ADDED
Binary file
|
assets/img/flags/UZ.png
ADDED
Binary file
|
assets/img/flags/VA.png
ADDED
Binary file
|
assets/img/flags/VC.png
ADDED
Binary file
|
assets/img/flags/VE.png
ADDED
Binary file
|
assets/img/flags/VG.png
ADDED
Binary file
|
assets/img/flags/VI.png
ADDED
Binary file
|
assets/img/flags/VN.png
ADDED
Binary file
|
assets/img/flags/VU.png
ADDED
Binary file
|
assets/img/flags/WF.png
ADDED
Binary file
|
assets/img/flags/WS.png
ADDED
Binary file
|
assets/img/flags/YE.png
ADDED
Binary file
|
assets/img/flags/YT.png
ADDED
Binary file
|
assets/img/flags/ZA.png
ADDED
Binary file
|
assets/img/flags/ZM.png
ADDED
Binary file
|
assets/img/flags/ZW.png
ADDED
Binary file
|
assets/img/flags/_abkhazia.png
ADDED
Binary file
|
assets/img/flags/_basque-country.png
ADDED
Binary file
|
assets/img/flags/_british-antarctic-territory.png
ADDED
Binary file
|
assets/img/flags/_commonwealth.png
ADDED
Binary file
|
assets/img/flags/_england.png
ADDED
Binary file
|
assets/img/flags/_gosquared.png
ADDED
Binary file
|
assets/img/flags/_kosovo.png
ADDED
Binary file
|
assets/img/flags/_mars.png
ADDED
Binary file
|
assets/img/flags/_nagorno-karabakh.png
ADDED
Binary file
|
assets/img/flags/_nato.png
ADDED
Binary file
|
assets/img/flags/_northern-cyprus.png
ADDED
Binary file
|
assets/img/flags/_olympics.png
ADDED
Binary file
|
assets/img/flags/_red-cross.png
ADDED
Binary file
|
assets/img/flags/_scotland.png
ADDED
Binary file
|
assets/img/flags/_somaliland.png
ADDED
Binary file
|
assets/img/flags/_south-ossetia.png
ADDED
Binary file
|
assets/img/flags/_united-nations.png
ADDED
Binary file
|
assets/img/flags/_unknown.png
ADDED
Binary file
|
assets/img/flags/_wales.png
ADDED
Binary file
|
assets/js/chartjs-gauge.js
ADDED
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* chartjs-gauge.js v0.2.0
|
3 |
+
* https://github.com/haiiaaa/chartjs-gauge/
|
4 |
+
* (c) 2020 chartjs-gauge.js Contributors
|
5 |
+
* Released under the MIT License
|
6 |
+
*/
|
7 |
+
(function (global, factory) {
|
8 |
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('chart.js')) :
|
9 |
+
typeof define === 'function' && define.amd ? define(['chart.js'], factory) :
|
10 |
+
(global = global || self, global.Gauge = factory(global.Chart));
|
11 |
+
}(this, (function (Chart) { 'use strict';
|
12 |
+
|
13 |
+
Chart = Chart && Object.prototype.hasOwnProperty.call(Chart, 'default') ? Chart['default'] : Chart;
|
14 |
+
|
15 |
+
function _defineProperty(obj, key, value) {
|
16 |
+
if (key in obj) {
|
17 |
+
Object.defineProperty(obj, key, {
|
18 |
+
value: value,
|
19 |
+
enumerable: true,
|
20 |
+
configurable: true,
|
21 |
+
writable: true
|
22 |
+
});
|
23 |
+
} else {
|
24 |
+
obj[key] = value;
|
25 |
+
}
|
26 |
+
|
27 |
+
return obj;
|
28 |
+
}
|
29 |
+
|
30 |
+
function ownKeys(object, enumerableOnly) {
|
31 |
+
var keys = Object.keys(object);
|
32 |
+
|
33 |
+
if (Object.getOwnPropertySymbols) {
|
34 |
+
var symbols = Object.getOwnPropertySymbols(object);
|
35 |
+
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
36 |
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
37 |
+
});
|
38 |
+
keys.push.apply(keys, symbols);
|
39 |
+
}
|
40 |
+
|
41 |
+
return keys;
|
42 |
+
}
|
43 |
+
|
44 |
+
function _objectSpread2(target) {
|
45 |
+
for (var i = 1; i < arguments.length; i++) {
|
46 |
+
var source = arguments[i] != null ? arguments[i] : {};
|
47 |
+
|
48 |
+
if (i % 2) {
|
49 |
+
ownKeys(Object(source), true).forEach(function (key) {
|
50 |
+
_defineProperty(target, key, source[key]);
|
51 |
+
});
|
52 |
+
} else if (Object.getOwnPropertyDescriptors) {
|
53 |
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
54 |
+
} else {
|
55 |
+
ownKeys(Object(source)).forEach(function (key) {
|
56 |
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
57 |
+
});
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
return target;
|
62 |
+
}
|
63 |
+
|
64 |
+
Chart.defaults._set('gauge', {
|
65 |
+
needle: {
|
66 |
+
// Needle circle radius as the percentage of the chart area width
|
67 |
+
radiusPercentage: 2,
|
68 |
+
// Needle width as the percentage of the chart area width
|
69 |
+
widthPercentage: 3.2,
|
70 |
+
// Needle length as the percentage of the interval between inner radius (0%) and outer radius (100%) of the arc
|
71 |
+
lengthPercentage: 80,
|
72 |
+
// The color of the needle
|
73 |
+
color: 'rgba(0, 0, 0, 1)'
|
74 |
+
},
|
75 |
+
valueLabel: {
|
76 |
+
// fontSize: undefined
|
77 |
+
display: true,
|
78 |
+
formatter: null,
|
79 |
+
color: 'rgba(255, 255, 255, 1)',
|
80 |
+
backgroundColor: 'rgba(0, 0, 0, 1)',
|
81 |
+
borderRadius: 5,
|
82 |
+
padding: {
|
83 |
+
top: 5,
|
84 |
+
right: 5,
|
85 |
+
bottom: 5,
|
86 |
+
left: 5
|
87 |
+
},
|
88 |
+
bottomMarginPercentage: 5
|
89 |
+
},
|
90 |
+
animation: {
|
91 |
+
duration: 1000,
|
92 |
+
animateRotate: true,
|
93 |
+
animateScale: false
|
94 |
+
},
|
95 |
+
// The percentage of the chart that we cut out of the middle.
|
96 |
+
cutoutPercentage: 50,
|
97 |
+
// The rotation of the chart, where the first data arc begins.
|
98 |
+
rotation: -Math.PI,
|
99 |
+
// The total circumference of the chart.
|
100 |
+
circumference: Math.PI,
|
101 |
+
legend: {
|
102 |
+
display: false
|
103 |
+
},
|
104 |
+
tooltips: {
|
105 |
+
enabled: false
|
106 |
+
}
|
107 |
+
});
|
108 |
+
|
109 |
+
var GaugeController = Chart.controllers.doughnut.extend({
|
110 |
+
getMaxValue: function getMaxValue(data) {
|
111 |
+
// assuming array is sorted
|
112 |
+
return data[data.length - 1] || 1;
|
113 |
+
},
|
114 |
+
getWidth: function getWidth(chart) {
|
115 |
+
return chart.chartArea.right - chart.chartArea.left;
|
116 |
+
},
|
117 |
+
getTranslation: function getTranslation(chart) {
|
118 |
+
var chartArea = chart.chartArea,
|
119 |
+
offsetX = chart.offsetX,
|
120 |
+
offsetY = chart.offsetY;
|
121 |
+
var centerX = (chartArea.left + chartArea.right) / 2;
|
122 |
+
var centerY = (chartArea.top + chartArea.bottom) / 2;
|
123 |
+
var dx = centerX + offsetX;
|
124 |
+
var dy = centerY + offsetY;
|
125 |
+
return {
|
126 |
+
dx: dx,
|
127 |
+
dy: dy
|
128 |
+
};
|
129 |
+
},
|
130 |
+
getAngle: function getAngle(_ref) {
|
131 |
+
var chart = _ref.chart,
|
132 |
+
value = _ref.value,
|
133 |
+
maxValue = _ref.maxValue;
|
134 |
+
var _chart$options = chart.options,
|
135 |
+
rotation = _chart$options.rotation,
|
136 |
+
circumference = _chart$options.circumference;
|
137 |
+
return rotation + circumference * (value / maxValue);
|
138 |
+
},
|
139 |
+
|
140 |
+
/* TODO set min padding, not applied until chart.update() (also chartArea must have been set)
|
141 |
+
setBottomPadding(chart) {
|
142 |
+
const needleRadius = this.getNeedleRadius(chart);
|
143 |
+
const padding = this.chart.config.options.layout.padding;
|
144 |
+
if (needleRadius > padding.bottom) {
|
145 |
+
padding.bottom = needleRadius;
|
146 |
+
return true;
|
147 |
+
}
|
148 |
+
return false;
|
149 |
+
},
|
150 |
+
*/
|
151 |
+
drawNeedle: function drawNeedle(ease) {
|
152 |
+
if (!this.chart.animating) {
|
153 |
+
// triggered when hovering
|
154 |
+
ease = 1;
|
155 |
+
}
|
156 |
+
|
157 |
+
var _this$chart = this.chart,
|
158 |
+
ctx = _this$chart.ctx,
|
159 |
+
config = _this$chart.config,
|
160 |
+
innerRadius = _this$chart.innerRadius,
|
161 |
+
outerRadius = _this$chart.outerRadius;
|
162 |
+
var dataset = config.data.datasets[this.index];
|
163 |
+
|
164 |
+
var _this$getMeta = this.getMeta(),
|
165 |
+
previous = _this$getMeta.previous;
|
166 |
+
|
167 |
+
var _config$options$needl = config.options.needle,
|
168 |
+
radiusPercentage = _config$options$needl.radiusPercentage,
|
169 |
+
widthPercentage = _config$options$needl.widthPercentage,
|
170 |
+
lengthPercentage = _config$options$needl.lengthPercentage,
|
171 |
+
color = _config$options$needl.color;
|
172 |
+
var width = this.getWidth(this.chart);
|
173 |
+
var needleRadius = radiusPercentage / 100 * width;
|
174 |
+
var needleWidth = widthPercentage / 100 * width;
|
175 |
+
var needleLength = lengthPercentage / 100 * (outerRadius - innerRadius) + innerRadius; // center
|
176 |
+
|
177 |
+
var _this$getTranslation = this.getTranslation(this.chart),
|
178 |
+
dx = _this$getTranslation.dx,
|
179 |
+
dy = _this$getTranslation.dy; // interpolate
|
180 |
+
|
181 |
+
|
182 |
+
var origin = this.getAngle({
|
183 |
+
chart: this.chart,
|
184 |
+
value: previous.value,
|
185 |
+
maxValue: previous.maxValue
|
186 |
+
}); // TODO maxValue is in current.maxValue also
|
187 |
+
|
188 |
+
var target = this.getAngle({
|
189 |
+
chart: this.chart,
|
190 |
+
value: dataset.value,
|
191 |
+
maxValue: this.getMaxValue(dataset.data)
|
192 |
+
});
|
193 |
+
var angle = origin + (target - origin) * ease; // draw
|
194 |
+
|
195 |
+
ctx.save();
|
196 |
+
ctx.translate(dx, dy);
|
197 |
+
ctx.rotate(angle);
|
198 |
+
ctx.fillStyle = color; // draw circle
|
199 |
+
|
200 |
+
ctx.beginPath();
|
201 |
+
ctx.ellipse(0, 0, needleRadius, needleRadius, 0, 0, 2 * Math.PI);
|
202 |
+
ctx.fill(); // draw needle
|
203 |
+
|
204 |
+
ctx.beginPath();
|
205 |
+
ctx.moveTo(0, needleWidth / 2);
|
206 |
+
ctx.lineTo(needleLength, 0);
|
207 |
+
ctx.lineTo(0, -needleWidth / 2);
|
208 |
+
ctx.fill();
|
209 |
+
ctx.restore();
|
210 |
+
},
|
211 |
+
drawValueLabel: function drawValueLabel(ease) {
|
212 |
+
// eslint-disable-line no-unused-vars
|
213 |
+
if (!this.chart.config.options.valueLabel.display) {
|
214 |
+
return;
|
215 |
+
}
|
216 |
+
|
217 |
+
var _this$chart2 = this.chart,
|
218 |
+
ctx = _this$chart2.ctx,
|
219 |
+
config = _this$chart2.config;
|
220 |
+
var defaultFontFamily = config.options.defaultFontFamily;
|
221 |
+
var dataset = config.data.datasets[this.index];
|
222 |
+
var _config$options$value = config.options.valueLabel,
|
223 |
+
formatter = _config$options$value.formatter,
|
224 |
+
fontSize = _config$options$value.fontSize,
|
225 |
+
color = _config$options$value.color,
|
226 |
+
backgroundColor = _config$options$value.backgroundColor,
|
227 |
+
borderRadius = _config$options$value.borderRadius,
|
228 |
+
padding = _config$options$value.padding,
|
229 |
+
bottomMarginPercentage = _config$options$value.bottomMarginPercentage;
|
230 |
+
var width = this.getWidth(this.chart);
|
231 |
+
var bottomMargin = bottomMarginPercentage / 100 * width;
|
232 |
+
|
233 |
+
var fmt = formatter || function (value) {
|
234 |
+
return value;
|
235 |
+
};
|
236 |
+
|
237 |
+
var valueText = fmt(dataset.value).toString();
|
238 |
+
ctx.textBaseline = 'middle';
|
239 |
+
ctx.textAlign = 'center';
|
240 |
+
|
241 |
+
if (fontSize) {
|
242 |
+
ctx.font = "".concat(fontSize, "px ").concat(defaultFontFamily);
|
243 |
+
} // const { width: textWidth, actualBoundingBoxAscent, actualBoundingBoxDescent } = ctx.measureText(valueText);
|
244 |
+
// const textHeight = actualBoundingBoxAscent + actualBoundingBoxDescent;
|
245 |
+
|
246 |
+
|
247 |
+
var _ctx$measureText = ctx.measureText(valueText),
|
248 |
+
textWidth = _ctx$measureText.width; // approximate height until browsers support advanced TextMetrics
|
249 |
+
|
250 |
+
|
251 |
+
var textHeight = Math.max(ctx.measureText('m').width, ctx.measureText("\uFF37").width);
|
252 |
+
var x = -(padding.left + textWidth / 2);
|
253 |
+
var y = -(padding.top + textHeight / 2);
|
254 |
+
var w = padding.left + textWidth + padding.right;
|
255 |
+
var h = padding.top + textHeight + padding.bottom; // center
|
256 |
+
|
257 |
+
var _this$getTranslation2 = this.getTranslation(this.chart),
|
258 |
+
dx = _this$getTranslation2.dx,
|
259 |
+
dy = _this$getTranslation2.dy; // add rotation
|
260 |
+
|
261 |
+
|
262 |
+
var rotation = this.chart.options.rotation % (Math.PI * 2.0);
|
263 |
+
dx += bottomMargin * Math.cos(rotation + Math.PI / 2);
|
264 |
+
dy += bottomMargin * Math.sin(rotation + Math.PI / 2); // draw
|
265 |
+
|
266 |
+
ctx.save();
|
267 |
+
ctx.translate(dx, dy); // draw background
|
268 |
+
|
269 |
+
ctx.beginPath();
|
270 |
+
Chart.helpers.canvas.roundedRect(ctx, x, y, w, h, borderRadius);
|
271 |
+
ctx.fillStyle = backgroundColor;
|
272 |
+
ctx.fill(); // draw value text
|
273 |
+
|
274 |
+
ctx.fillStyle = color || config.options.defaultFontColor;
|
275 |
+
var magicNumber = 0.075; // manual testing
|
276 |
+
|
277 |
+
ctx.fillText(valueText, 0, textHeight * magicNumber);
|
278 |
+
ctx.restore();
|
279 |
+
},
|
280 |
+
// overrides
|
281 |
+
update: function update(reset) {
|
282 |
+
var dataset = this.chart.config.data.datasets[this.index];
|
283 |
+
var meta = this.getMeta();
|
284 |
+
var initialValue = {
|
285 |
+
value: 0,
|
286 |
+
maxValue: 1
|
287 |
+
}; // animations on will call update(reset) before update()
|
288 |
+
|
289 |
+
if (reset) {
|
290 |
+
meta.previous = null;
|
291 |
+
meta.current = initialValue;
|
292 |
+
} else {
|
293 |
+
dataset.data.sort(function (a, b) {
|
294 |
+
return a - b;
|
295 |
+
});
|
296 |
+
meta.previous = meta.current || initialValue;
|
297 |
+
meta.current = {
|
298 |
+
value: dataset.value,
|
299 |
+
maxValue: this.getMaxValue(dataset.data)
|
300 |
+
};
|
301 |
+
}
|
302 |
+
|
303 |
+
Chart.controllers.doughnut.prototype.update.call(this, reset);
|
304 |
+
},
|
305 |
+
updateElement: function updateElement(arc, index, reset) {
|
306 |
+
// TODO handle reset and options.animation
|
307 |
+
Chart.controllers.doughnut.prototype.updateElement.call(this, arc, index, reset);
|
308 |
+
var dataset = this.getDataset();
|
309 |
+
var data = dataset.data;
|
310 |
+
var options = this.chart.config.options; // scale data
|
311 |
+
|
312 |
+
var maxValue = this.getMaxValue(data);
|
313 |
+
var previousValue = data[index - 1] || 0;
|
314 |
+
var value = data[index];
|
315 |
+
var startAngle = options.rotation + options.circumference * (previousValue / maxValue);
|
316 |
+
var endAngle = startAngle + options.circumference * ((value - previousValue) / maxValue);
|
317 |
+
var circumference = endAngle - startAngle;
|
318 |
+
arc._model = _objectSpread2({}, arc._model, {
|
319 |
+
startAngle: startAngle,
|
320 |
+
endAngle: endAngle,
|
321 |
+
circumference: circumference
|
322 |
+
});
|
323 |
+
},
|
324 |
+
draw: function draw(ease) {
|
325 |
+
Chart.controllers.doughnut.prototype.draw.call(this, ease);
|
326 |
+
this.drawNeedle(ease);
|
327 |
+
this.drawValueLabel(ease);
|
328 |
+
}
|
329 |
+
});
|
330 |
+
|
331 |
+
/* eslint-disable max-len, func-names */
|
332 |
+
var polyfill = function polyfill() {
|
333 |
+
if (CanvasRenderingContext2D.prototype.ellipse === undefined) {
|
334 |
+
CanvasRenderingContext2D.prototype.ellipse = function (x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise) {
|
335 |
+
this.save();
|
336 |
+
this.translate(x, y);
|
337 |
+
this.rotate(rotation);
|
338 |
+
this.scale(radiusX, radiusY);
|
339 |
+
this.arc(0, 0, 1, startAngle, endAngle, antiClockwise);
|
340 |
+
this.restore();
|
341 |
+
};
|
342 |
+
}
|
343 |
+
};
|
344 |
+
|
345 |
+
polyfill();
|
346 |
+
Chart.controllers.gauge = GaugeController;
|
347 |
+
|
348 |
+
Chart.Gauge = function (context, config) {
|
349 |
+
config.type = 'gauge';
|
350 |
+
return new Chart(context, config);
|
351 |
+
};
|
352 |
+
|
353 |
+
var index = Chart.Gauge;
|
354 |
+
|
355 |
+
return index;
|
356 |
+
|
357 |
+
})));
|
assets/sass/_dashboard-page.scss
ADDED
@@ -0,0 +1,355 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#llar-dashboard-page {
|
2 |
+
padding-top: 10px;
|
3 |
+
|
4 |
+
* {
|
5 |
+
box-sizing: border-box;
|
6 |
+
}
|
7 |
+
|
8 |
+
.dashboard-header {
|
9 |
+
background-color: #0071a0;
|
10 |
+
color: #fff;
|
11 |
+
text-align: center;
|
12 |
+
padding: 15px;
|
13 |
+
|
14 |
+
h1 {
|
15 |
+
color: #fff
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
.section-title {
|
20 |
+
font-weight: bold;
|
21 |
+
padding: 15px;
|
22 |
+
border-bottom: 1px solid #e4e4e4;
|
23 |
+
font-size: 14px;
|
24 |
+
text-align: left;
|
25 |
+
}
|
26 |
+
.section-content {
|
27 |
+
padding: 15px;
|
28 |
+
}
|
29 |
+
|
30 |
+
.dashboard-section-1 {
|
31 |
+
margin-bottom: 20px;
|
32 |
+
background-color: #fff;
|
33 |
+
display: flex;
|
34 |
+
flex-wrap: wrap;
|
35 |
+
|
36 |
+
|
37 |
+
> [class^="info-box-"] {
|
38 |
+
//padding: 15px;
|
39 |
+
text-align: center;
|
40 |
+
flex: 0 0 33.333%;
|
41 |
+
max-width: 33.333%;
|
42 |
+
border-right: 1px solid #e4e4e4;
|
43 |
+
|
44 |
+
&:last-child {
|
45 |
+
border: 0;
|
46 |
+
}
|
47 |
+
|
48 |
+
.title {
|
49 |
+
font-weight: 600;
|
50 |
+
font-size: 16px;
|
51 |
+
line-height: 1.5;
|
52 |
+
margin-bottom: 10px;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
.info-box-1 {
|
56 |
+
.chart {
|
57 |
+
//margin-bottom: 10px;
|
58 |
+
max-width: 300px;
|
59 |
+
//display: inline-block;
|
60 |
+
position: relative;
|
61 |
+
margin-bottom: 15px;
|
62 |
+
margin-left: auto;
|
63 |
+
margin-right: auto;
|
64 |
+
|
65 |
+
.llar-retries-count {
|
66 |
+
position: absolute;
|
67 |
+
top: 50%;
|
68 |
+
left: 50%;
|
69 |
+
transform: translate(-50%, -50%);
|
70 |
+
font-size: 28px;
|
71 |
+
font-weight: bold;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
.desc {
|
75 |
+
font-size: 15px;
|
76 |
+
}
|
77 |
+
.actions {
|
78 |
+
margin-top: 5px;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
.info-box-2 {
|
82 |
+
|
83 |
+
.llar-chart-wrap {
|
84 |
+
width: 100%;
|
85 |
+
max-width: 80%;
|
86 |
+
margin: 0 auto;
|
87 |
+
clear: both;
|
88 |
+
|
89 |
+
canvas {
|
90 |
+
height: 300px;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
.chart-stats-legend {
|
94 |
+
text-align: center;
|
95 |
+
margin-top: 10px;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
.info-box-3 {
|
99 |
+
text-align: left;
|
100 |
+
|
101 |
+
.desc {
|
102 |
+
margin-bottom: 20px;
|
103 |
+
}
|
104 |
+
.actions {
|
105 |
+
text-align: center;
|
106 |
+
padding-top: 20px;
|
107 |
+
|
108 |
+
a {
|
109 |
+
text-transform: uppercase;
|
110 |
+
font-size: 16px;
|
111 |
+
margin-bottom: 5px;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
&.custom {
|
117 |
+
.info-box-2 {
|
118 |
+
flex: 0 0 66.666%;
|
119 |
+
max-width: 66.666%;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
.dashboard-section-2 {
|
125 |
+
display: flex;
|
126 |
+
flex-wrap: wrap;
|
127 |
+
justify-content: space-between;
|
128 |
+
margin-bottom: 20px;
|
129 |
+
|
130 |
+
> [class^="info-box-"] {
|
131 |
+
flex: 0 0 calc(50% - 10px);
|
132 |
+
//margin-right: 20px;
|
133 |
+
min-height: 100px;
|
134 |
+
background-color: #fff;
|
135 |
+
border: 1px solid #e4e4e4;
|
136 |
+
padding: 15px;
|
137 |
+
|
138 |
+
&:last-child {
|
139 |
+
margin-right: 0;
|
140 |
+
}
|
141 |
+
}
|
142 |
+
.info-box-1 {
|
143 |
+
padding: 0;
|
144 |
+
|
145 |
+
.notifications-list {
|
146 |
+
padding: 0;
|
147 |
+
margin: 0;
|
148 |
+
|
149 |
+
li {
|
150 |
+
margin: 0;
|
151 |
+
border-bottom: 1px solid #e4e4e4;
|
152 |
+
|
153 |
+
&:last-child {
|
154 |
+
border: 0;
|
155 |
+
}
|
156 |
+
|
157 |
+
a {
|
158 |
+
text-decoration: none;
|
159 |
+
padding: 15px;
|
160 |
+
font-size: 15px;
|
161 |
+
display: block;
|
162 |
+
|
163 |
+
&:hover {
|
164 |
+
background-color: #f9f9f9;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
}
|
170 |
+
.info-box-2 {
|
171 |
+
display: flex;
|
172 |
+
flex-wrap: wrap;
|
173 |
+
|
174 |
+
.info-box-icon {
|
175 |
+
flex: 0 0 100px;
|
176 |
+
display: flex;
|
177 |
+
justify-content: center;
|
178 |
+
align-items: center;
|
179 |
+
margin-right: 15px;
|
180 |
+
|
181 |
+
.dashicons {
|
182 |
+
color: #0073a0;
|
183 |
+
font-size: 50px;
|
184 |
+
width: auto;
|
185 |
+
height: auto;
|
186 |
+
}
|
187 |
+
|
188 |
+
}
|
189 |
+
.info-box-content {
|
190 |
+
flex: 1;
|
191 |
+
|
192 |
+
.title {
|
193 |
+
font-size: 20px;
|
194 |
+
font-weight: bold;
|
195 |
+
margin-bottom: 10px;
|
196 |
+
line-height: 1.5;
|
197 |
+
}
|
198 |
+
.desc {
|
199 |
+
font-size: 15px;
|
200 |
+
margin-bottom: 15px;
|
201 |
+
}
|
202 |
+
.actions {
|
203 |
+
display: flex;
|
204 |
+
justify-content: space-between;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
.dashboard-section-3 {
|
211 |
+
display: flex;
|
212 |
+
flex-wrap: wrap;
|
213 |
+
background-color: #fff;
|
214 |
+
margin-bottom: 20px;
|
215 |
+
|
216 |
+
> [class^="info-box-"] {
|
217 |
+
display: flex;
|
218 |
+
flex-wrap: wrap;
|
219 |
+
padding: 30px 15px 30px 0;
|
220 |
+
flex: 1;
|
221 |
+
border-right: 1px solid #e4e4e4;
|
222 |
+
|
223 |
+
.info-box-icon {
|
224 |
+
flex: 0 0 100px;
|
225 |
+
display: flex;
|
226 |
+
justify-content: center;
|
227 |
+
align-items: center;
|
228 |
+
|
229 |
+
.dashicons {
|
230 |
+
color: #a1a2a2;
|
231 |
+
font-size: 60px;
|
232 |
+
width: auto;
|
233 |
+
height: auto;
|
234 |
+
}
|
235 |
+
|
236 |
+
}
|
237 |
+
.info-box-content {
|
238 |
+
flex: 1;
|
239 |
+
|
240 |
+
.title {
|
241 |
+
font-size: 20px;
|
242 |
+
font-weight: bold;
|
243 |
+
margin-bottom: 10px;
|
244 |
+
line-height: 1.3;
|
245 |
+
|
246 |
+
a {
|
247 |
+
text-decoration: none;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
.desc {
|
251 |
+
font-size: 15px;
|
252 |
+
margin-bottom: 15px;
|
253 |
+
}
|
254 |
+
.actions {
|
255 |
+
display: flex;
|
256 |
+
justify-content: space-between;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
.dashboard-section-4 {
|
263 |
+
display: flex;
|
264 |
+
flex-wrap: wrap;
|
265 |
+
justify-content: space-between;
|
266 |
+
margin-bottom: 20px;
|
267 |
+
|
268 |
+
> [class^="info-box-"] {
|
269 |
+
flex: 0 0 calc(50% - 10px);
|
270 |
+
//margin-right: 20px;
|
271 |
+
min-height: 100px;
|
272 |
+
background-color: #fff;
|
273 |
+
border: 1px solid #e4e4e4;
|
274 |
+
padding: 15px;
|
275 |
+
|
276 |
+
&:last-child {
|
277 |
+
margin-right: 0;
|
278 |
+
}
|
279 |
+
}
|
280 |
+
.info-box-1 {
|
281 |
+
padding: 0;
|
282 |
+
|
283 |
+
.section-title {
|
284 |
+
display: flex;
|
285 |
+
justify-content: space-between;
|
286 |
+
|
287 |
+
.section-title-info {
|
288 |
+
color: #a7a7a7;
|
289 |
+
font-weight: 400;
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
.lockouts-by-country-table {
|
294 |
+
width: 100%;
|
295 |
+
border-collapse: collapse;
|
296 |
+
|
297 |
+
tr {
|
298 |
+
th, td {
|
299 |
+
padding: 10px;
|
300 |
+
border: 1px solid #cecece;
|
301 |
+
}
|
302 |
+
th {
|
303 |
+
background-color: #000;
|
304 |
+
color: #fff;
|
305 |
+
text-align: left;
|
306 |
+
}
|
307 |
+
&:nth-child(odd){
|
308 |
+
td {
|
309 |
+
background-color: #eff0ef;
|
310 |
+
}
|
311 |
+
}
|
312 |
+
td {
|
313 |
+
.flag-icon {
|
314 |
+
width: 24px;
|
315 |
+
vertical-align: middle;
|
316 |
+
margin-right: 10px;
|
317 |
+
}
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
.countries-table-info {
|
323 |
+
color: #a7a7a7;
|
324 |
+
font-weight: 400;
|
325 |
+
margin-top: 5px;
|
326 |
+
margin-bottom: 0;
|
327 |
+
}
|
328 |
+
}
|
329 |
+
.info-box-2 {
|
330 |
+
padding: 0;
|
331 |
+
|
332 |
+
.section-title {
|
333 |
+
display: flex;
|
334 |
+
justify-content: space-between;
|
335 |
+
|
336 |
+
.section-title-info {
|
337 |
+
color: #a7a7a7;
|
338 |
+
font-weight: 400;
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
.llar-chart-wrap {
|
343 |
+
width: 100%;
|
344 |
+
max-width: 80%;
|
345 |
+
margin: 0 auto;
|
346 |
+
clear: both;
|
347 |
+
|
348 |
+
canvas {
|
349 |
+
height: 300px;
|
350 |
+
}
|
351 |
+
}
|
352 |
+
}
|
353 |
+
}
|
354 |
+
|
355 |
+
}
|
assets/sass/limit-login-attempts.scss
CHANGED
@@ -356,13 +356,6 @@
|
|
356 |
}
|
357 |
}
|
358 |
|
359 |
-
.llar-chart-wrap {
|
360 |
-
width: 100%;
|
361 |
-
max-width: 900px;
|
362 |
-
margin: 0 auto;
|
363 |
-
clear: both;
|
364 |
-
}
|
365 |
-
|
366 |
#llar-welcome-page {
|
367 |
padding: 50px 0;
|
368 |
|
@@ -537,7 +530,8 @@
|
|
537 |
}
|
538 |
}
|
539 |
|
540 |
-
.dashboard_page_llar-welcome
|
|
|
541 |
.update-nag,
|
542 |
.notice {
|
543 |
display: none;
|
@@ -561,4 +555,37 @@
|
|
561 |
.jconfirm .jconfirm-box div.jconfirm-closeIcon {
|
562 |
top: -2px !important;
|
563 |
right: -2px !important;
|
564 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
}
|
357 |
}
|
358 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
#llar-welcome-page {
|
360 |
padding: 50px 0;
|
361 |
|
530 |
}
|
531 |
}
|
532 |
|
533 |
+
.dashboard_page_llar-welcome,
|
534 |
+
.toplevel_page_limit-login-attempts {
|
535 |
.update-nag,
|
536 |
.notice {
|
537 |
display: none;
|
555 |
.jconfirm .jconfirm-box div.jconfirm-closeIcon {
|
556 |
top: -2px !important;
|
557 |
right: -2px !important;
|
558 |
+
}
|
559 |
+
|
560 |
+
.llar-tooltip {
|
561 |
+
text-decoration: underline;
|
562 |
+
text-decoration-style: dotted;
|
563 |
+
cursor: pointer;
|
564 |
+
position: relative;
|
565 |
+
|
566 |
+
&:before {
|
567 |
+
content: attr(data-text);
|
568 |
+
position: absolute;
|
569 |
+
width: 200px;
|
570 |
+
padding: 5px;
|
571 |
+
background-color: rgba(#000, 0.8);
|
572 |
+
color: #fff;
|
573 |
+
font-size: 13px;
|
574 |
+
top: 100%;
|
575 |
+
z-index: 999;
|
576 |
+
visibility: hidden;
|
577 |
+
opacity: 0;
|
578 |
+
transition: all .2s;
|
579 |
+
font-weight: 300;
|
580 |
+
cursor: auto;
|
581 |
+
}
|
582 |
+
|
583 |
+
&:hover {
|
584 |
+
&:before {
|
585 |
+
visibility: visible;
|
586 |
+
opacity: 1;
|
587 |
+
}
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
@import "dashboard-page";
|
core/App.php
CHANGED
@@ -128,6 +128,22 @@ class LLAR_App {
|
|
128 |
return $this->request( 'stats', 'get' );
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
/**
|
132 |
* @param $data
|
133 |
* @return bool|mixed
|
128 |
return $this->request( 'stats', 'get' );
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* @return bool|mixed
|
133 |
+
*/
|
134 |
+
public static function stats_global() {
|
135 |
+
|
136 |
+
$response = wp_remote_get('https://api.limitloginattempts.com/v1/global-stats');
|
137 |
+
|
138 |
+
if( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
139 |
+
|
140 |
+
return false;
|
141 |
+
} else {
|
142 |
+
|
143 |
+
return json_decode( sanitize_textarea_field( stripslashes( wp_remote_retrieve_body( $response ) ) ), true );
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
/**
|
148 |
* @param $data
|
149 |
* @return bool|mixed
|
core/LimitLoginAttempts.php
CHANGED
@@ -24,7 +24,7 @@ class Limit_Login_Attempts {
|
|
24 |
'long_duration' => 86400, // 24 hours,
|
25 |
|
26 |
/* Reset failed attempts after this many seconds */
|
27 |
-
'valid_duration' =>
|
28 |
|
29 |
/* Also limit malformed/forged cookies? */
|
30 |
'cookies' => true,
|
@@ -258,6 +258,7 @@ class Limit_Login_Attempts {
|
|
258 |
|
259 |
wp_enqueue_style( 'llar-charts', LLA_PLUGIN_URL.'assets/css/Chart.min.css' );
|
260 |
wp_enqueue_script( 'llar-charts', LLA_PLUGIN_URL . 'assets/js/Chart.bundle.min.js' );
|
|
|
261 |
}
|
262 |
|
263 |
public function check_whitelist_ips( $allow, $ip ) {
|
@@ -752,6 +753,7 @@ class Limit_Login_Attempts {
|
|
752 |
/* Get the arrays with retries and retries-valid information */
|
753 |
$retries = $this->get_option( 'retries' );
|
754 |
$valid = $this->get_option( 'retries_valid' );
|
|
|
755 |
|
756 |
if ( ! is_array( $retries ) ) {
|
757 |
$retries = array();
|
@@ -763,6 +765,21 @@ class Limit_Login_Attempts {
|
|
763 |
$this->add_option( 'retries_valid', $valid );
|
764 |
}
|
765 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
766 |
$gdpr = $this->get_option('gdpr');
|
767 |
$ip = ($gdpr ? $ipHash : $ip);
|
768 |
/* Check validity and add one to retries */
|
@@ -921,10 +938,7 @@ class Limit_Login_Attempts {
|
|
921 |
$admin_name = ' ' . $res[0];
|
922 |
}
|
923 |
|
924 |
-
|
925 |
-
$blogname = htmlspecialchars_decode( $blogname, ENT_QUOTES );
|
926 |
-
|
927 |
-
$subject = sprintf( __( "[%s] Failed login attempts", 'limit-login-attempts-reloaded' ) , $blogname );
|
928 |
|
929 |
$message = __( '<p>Hello%1$s,</p>' .
|
930 |
'<p>%2$d failed login attempts (%3$d lockout(s)) from IP <b>%4$s</b><br>' .
|
@@ -932,9 +946,10 @@ class Limit_Login_Attempts {
|
|
932 |
'IP was blocked for %6$s</p>'.
|
933 |
'<p>This notification was sent automatically via Limit Login Attempts Reloaded Plugin. ' .
|
934 |
'<b>This is installed on your WordPress site.</b></p>'.
|
935 |
-
'<p
|
936 |
-
'
|
937 |
-
'<
|
|
|
938 |
|
939 |
$plugin_data = get_plugin_data( LLA_PLUGIN_DIR . '/limit-login-attempts-reloaded.php' );
|
940 |
|
@@ -946,6 +961,7 @@ class Limit_Login_Attempts {
|
|
946 |
$ip,
|
947 |
$user,
|
948 |
$when,
|
|
|
949 |
'https://www.limitloginattempts.com/info.php?from=plugin-lockout-email&v='.$plugin_data['Version'],
|
950 |
'https://www.limitloginattempts.com/resources/?from=plugin-lockout-email',
|
951 |
admin_url( 'options-general.php?page=limit-login-attempts&tab=settings' )
|
@@ -1435,6 +1451,20 @@ class Limit_Login_Attempts {
|
|
1435 |
}
|
1436 |
}
|
1437 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1438 |
$this->update_option( 'retries', $retries );
|
1439 |
$this->update_option( 'retries_valid', $valid );
|
1440 |
}
|
24 |
'long_duration' => 86400, // 24 hours,
|
25 |
|
26 |
/* Reset failed attempts after this many seconds */
|
27 |
+
'valid_duration' => 86400, // 12 hours
|
28 |
|
29 |
/* Also limit malformed/forged cookies? */
|
30 |
'cookies' => true,
|
258 |
|
259 |
wp_enqueue_style( 'llar-charts', LLA_PLUGIN_URL.'assets/css/Chart.min.css' );
|
260 |
wp_enqueue_script( 'llar-charts', LLA_PLUGIN_URL . 'assets/js/Chart.bundle.min.js' );
|
261 |
+
wp_enqueue_script( 'llar-charts-gauge', LLA_PLUGIN_URL . 'assets/js/chartjs-gauge.js' );
|
262 |
}
|
263 |
|
264 |
public function check_whitelist_ips( $allow, $ip ) {
|
753 |
/* Get the arrays with retries and retries-valid information */
|
754 |
$retries = $this->get_option( 'retries' );
|
755 |
$valid = $this->get_option( 'retries_valid' );
|
756 |
+
$retries_stats = $this->get_option( 'retries_stats' );
|
757 |
|
758 |
if ( ! is_array( $retries ) ) {
|
759 |
$retries = array();
|
765 |
$this->add_option( 'retries_valid', $valid );
|
766 |
}
|
767 |
|
768 |
+
if ( ! is_array( $retries_stats ) ) {
|
769 |
+
$retries_stats = array();
|
770 |
+
$this->add_option( 'retries_stats', $retries_stats );
|
771 |
+
}
|
772 |
+
|
773 |
+
$date_key = date_i18n( 'Y-m-d' );
|
774 |
+
if(!empty($retries_stats[$date_key])) {
|
775 |
+
|
776 |
+
$retries_stats[$date_key]++;
|
777 |
+
} else {
|
778 |
+
|
779 |
+
$retries_stats[$date_key] = 1;
|
780 |
+
}
|
781 |
+
$this->update_option( 'retries_stats', $retries_stats );
|
782 |
+
|
783 |
$gdpr = $this->get_option('gdpr');
|
784 |
$ip = ($gdpr ? $ipHash : $ip);
|
785 |
/* Check validity and add one to retries */
|
938 |
$admin_name = ' ' . $res[0];
|
939 |
}
|
940 |
|
941 |
+
$subject = sprintf( __( "Failed login attempt alert for %s", 'limit-login-attempts-reloaded' ) , str_replace( array( 'http://', 'https://' ), '', home_url() ) );
|
|
|
|
|
|
|
942 |
|
943 |
$message = __( '<p>Hello%1$s,</p>' .
|
944 |
'<p>%2$d failed login attempts (%3$d lockout(s)) from IP <b>%4$s</b><br>' .
|
946 |
'IP was blocked for %6$s</p>'.
|
947 |
'<p>This notification was sent automatically via Limit Login Attempts Reloaded Plugin. ' .
|
948 |
'<b>This is installed on your WordPress site.</b></p>'.
|
949 |
+
'<p><b><a href="%7$s">Visit your WordPress Dashboard</a> for complete stats and logs.</b></p>'.
|
950 |
+
'<p>Under Attack? Try our <a href="%8$s" target="_blank">advanced protection</a>. ' .
|
951 |
+
'Have Questions? Visit our <a href="%9$s" target="_blank">help section</a>.</p>' .
|
952 |
+
'<hr><a href="%10$s">Unsubscribe</a> from these notifications.', 'limit-login-attempts-reloaded' );
|
953 |
|
954 |
$plugin_data = get_plugin_data( LLA_PLUGIN_DIR . '/limit-login-attempts-reloaded.php' );
|
955 |
|
961 |
$ip,
|
962 |
$user,
|
963 |
$when,
|
964 |
+
admin_url( 'options-general.php?page=limit-login-attempts&tab=dashboard' ),
|
965 |
'https://www.limitloginattempts.com/info.php?from=plugin-lockout-email&v='.$plugin_data['Version'],
|
966 |
'https://www.limitloginattempts.com/resources/?from=plugin-lockout-email',
|
967 |
admin_url( 'options-general.php?page=limit-login-attempts&tab=settings' )
|
1451 |
}
|
1452 |
}
|
1453 |
|
1454 |
+
$retries_stats = $this->get_option( 'retries_stats' );
|
1455 |
+
|
1456 |
+
if($retries_stats) {
|
1457 |
+
|
1458 |
+
foreach( $retries_stats as $date => $count ) {
|
1459 |
+
|
1460 |
+
if( strtotime( $date ) < strtotime( '-7 day' ) ) {
|
1461 |
+
unset($retries_stats[$date]);
|
1462 |
+
}
|
1463 |
+
}
|
1464 |
+
|
1465 |
+
$this->update_option( 'retries_stats', $retries_stats );
|
1466 |
+
}
|
1467 |
+
|
1468 |
$this->update_option( 'retries', $retries );
|
1469 |
$this->update_option( 'retries_valid', $valid );
|
1470 |
}
|
limit-login-attempts-reloaded.php
CHANGED
@@ -3,9 +3,9 @@
|
|
3 |
Plugin Name: Limit Login Attempts Reloaded
|
4 |
Description: Limit the rate of login attempts for each IP address.
|
5 |
Author: Limit Login Attempts Reloaded
|
6 |
-
Author URI: https://limitloginattempts.com/
|
7 |
Text Domain: limit-login-attempts-reloaded
|
8 |
-
Version: 2.
|
9 |
|
10 |
Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2021 Limit Login Attempts Reloaded
|
11 |
*/
|
3 |
Plugin Name: Limit Login Attempts Reloaded
|
4 |
Description: Limit the rate of login attempts for each IP address.
|
5 |
Author: Limit Login Attempts Reloaded
|
6 |
+
Author URI: https://www.limitloginattempts.com/
|
7 |
Text Domain: limit-login-attempts-reloaded
|
8 |
+
Version: 2.20.0
|
9 |
|
10 |
Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2021 Limit Login Attempts Reloaded
|
11 |
*/
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/donate?hosted_button_id=FKD4MYFCMNVQQ
|
|
4 |
Tags: brute force, login, security, firewall, protection
|
5 |
Requires at least: 3.0
|
6 |
Tested up to: 5.6
|
7 |
-
Stable tag: 2.
|
8 |
|
9 |
Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
|
10 |
|
@@ -97,6 +97,9 @@ Please follow this link: <a href="https://www.limitloginattempts.com/resources/"
|
|
97 |
|
98 |
== Changelog ==
|
99 |
|
|
|
|
|
|
|
100 |
= 2.19.2 =
|
101 |
* Texts and links updated.
|
102 |
|
4 |
Tags: brute force, login, security, firewall, protection
|
5 |
Requires at least: 3.0
|
6 |
Tested up to: 5.6
|
7 |
+
Stable tag: 2.20.0
|
8 |
|
9 |
Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
|
10 |
|
97 |
|
98 |
== Changelog ==
|
99 |
|
100 |
+
= 2.20.0 =
|
101 |
+
* New dashboard with simple stats.
|
102 |
+
|
103 |
= 2.19.2 =
|
104 |
* Texts and links updated.
|
105 |
|
resources/countries.php
ADDED
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
return array (
|
3 |
+
'ZZ' => 'Unknown',
|
4 |
+
'RW' => 'Rwanda',
|
5 |
+
'SO' => 'Somalia',
|
6 |
+
'YE' => 'Yemen',
|
7 |
+
'IQ' => 'Iraq',
|
8 |
+
'SA' => 'Saudi Arabia',
|
9 |
+
'IR' => 'Iran',
|
10 |
+
'CY' => 'Cyprus',
|
11 |
+
'TZ' => 'Tanzania',
|
12 |
+
'SY' => 'Syria',
|
13 |
+
'AM' => 'Armenia',
|
14 |
+
'KE' => 'Kenya',
|
15 |
+
'CD' => 'DR Congo',
|
16 |
+
'DJ' => 'Djibouti',
|
17 |
+
'UG' => 'Uganda',
|
18 |
+
'CF' => 'Central African Republic',
|
19 |
+
'SC' => 'Seychelles',
|
20 |
+
'JO' => 'Jordan',
|
21 |
+
'LB' => 'Lebanon',
|
22 |
+
'KW' => 'Kuwait',
|
23 |
+
'OM' => 'Oman',
|
24 |
+
'QA' => 'Qatar',
|
25 |
+
'BH' => 'Bahrain',
|
26 |
+
'AE' => 'United Arab Emirates',
|
27 |
+
'IL' => 'Israel',
|
28 |
+
'TR' => 'Turkey',
|
29 |
+
'ET' => 'Ethiopia',
|
30 |
+
'ER' => 'Eritrea',
|
31 |
+
'EG' => 'Egypt',
|
32 |
+
'SD' => 'Sudan',
|
33 |
+
'GR' => 'Greece',
|
34 |
+
'BI' => 'Burundi',
|
35 |
+
'EE' => 'Estonia',
|
36 |
+
'LV' => 'Latvia',
|
37 |
+
'AZ' => 'Azerbaijan',
|
38 |
+
'LT' => 'Lithuania',
|
39 |
+
'SJ' => 'Svalbard and Jan Mayen',
|
40 |
+
'GE' => 'Georgia',
|
41 |
+
'MD' => 'Moldova',
|
42 |
+
'BY' => 'Belarus',
|
43 |
+
'FI' => 'Finland',
|
44 |
+
'AX' => 'Åland',
|
45 |
+
'UA' => 'Ukraine',
|
46 |
+
'MK' => 'North Macedonia',
|
47 |
+
'HU' => 'Hungary',
|
48 |
+
'BG' => 'Bulgaria',
|
49 |
+
'AL' => 'Albania',
|
50 |
+
'PL' => 'Poland',
|
51 |
+
'RO' => 'Romania',
|
52 |
+
'XK' => 'Kosovo',
|
53 |
+
'ZW' => 'Zimbabwe',
|
54 |
+
'ZM' => 'Zambia',
|
55 |
+
'KM' => 'Comoros',
|
56 |
+
'MW' => 'Malawi',
|
57 |
+
'LS' => 'Lesotho',
|
58 |
+
'BW' => 'Botswana',
|
59 |
+
'MU' => 'Mauritius',
|
60 |
+
'SZ' => 'Eswatini',
|
61 |
+
'RE' => 'Réunion',
|
62 |
+
'ZA' => 'South Africa',
|
63 |
+
'YT' => 'Mayotte',
|
64 |
+
'MZ' => 'Mozambique',
|
65 |
+
'MG' => 'Madagascar',
|
66 |
+
'AF' => 'Afghanistan',
|
67 |
+
'PK' => 'Pakistan',
|
68 |
+
'BD' => 'Bangladesh',
|
69 |
+
'TM' => 'Turkmenistan',
|
70 |
+
'TJ' => 'Tajikistan',
|
71 |
+
'LK' => 'Sri Lanka',
|
72 |
+
'BT' => 'Bhutan',
|
73 |
+
'IN' => 'India',
|
74 |
+
'MV' => 'Maldives',
|
75 |
+
'IO' => 'British Indian Ocean Territory',
|
76 |
+
'NP' => 'Nepal',
|
77 |
+
'MM' => 'Myanmar',
|
78 |
+
'UZ' => 'Uzbekistan',
|
79 |
+
'KZ' => 'Kazakhstan',
|
80 |
+
'KG' => 'Kyrgyzstan',
|
81 |
+
'TF' => 'French Southern Territories',
|
82 |
+
'HM' => 'Heard Island and McDonald Islands',
|
83 |
+
'CC' => 'Cocos [Keeling] Islands',
|
84 |
+
'PW' => 'Palau',
|
85 |
+
'VN' => 'Vietnam',
|
86 |
+
'TH' => 'Thailand',
|
87 |
+
'ID' => 'Indonesia',
|
88 |
+
'LA' => 'Laos',
|
89 |
+
'TW' => 'Taiwan',
|
90 |
+
'PH' => 'Philippines',
|
91 |
+
'MY' => 'Malaysia',
|
92 |
+
'CN' => 'China',
|
93 |
+
'HK' => 'Hong Kong',
|
94 |
+
'BN' => 'Brunei',
|
95 |
+
'MO' => 'Macao',
|
96 |
+
'KH' => 'Cambodia',
|
97 |
+
'KR' => 'South Korea',
|
98 |
+
'JP' => 'Japan',
|
99 |
+
'KP' => 'North Korea',
|
100 |
+
'SG' => 'Singapore',
|
101 |
+
'CK' => 'Cook Islands',
|
102 |
+
'TL' => 'East Timor',
|
103 |
+
'RU' => 'Russia',
|
104 |
+
'MN' => 'Mongolia',
|
105 |
+
'AU' => 'Australia',
|
106 |
+
'CX' => 'Christmas Island',
|
107 |
+
'MH' => 'Marshall Islands',
|
108 |
+
'FM' => 'Federated States of Micronesia',
|
109 |
+
'PG' => 'Papua New Guinea',
|
110 |
+
'SB' => 'Solomon Islands',
|
111 |
+
'TV' => 'Tuvalu',
|
112 |
+
'NR' => 'Nauru',
|
113 |
+
'VU' => 'Vanuatu',
|
114 |
+
'NC' => 'New Caledonia',
|
115 |
+
'NF' => 'Norfolk Island',
|
116 |
+
'NZ' => 'New Zealand',
|
117 |
+
'FJ' => 'Fiji',
|
118 |
+
'LY' => 'Libya',
|
119 |
+
'CM' => 'Cameroon',
|
120 |
+
'SN' => 'Senegal',
|
121 |
+
'CG' => 'Congo Republic',
|
122 |
+
'PT' => 'Portugal',
|
123 |
+
'LR' => 'Liberia',
|
124 |
+
'CI' => 'Ivory Coast',
|
125 |
+
'GH' => 'Ghana',
|
126 |
+
'GQ' => 'Equatorial Guinea',
|
127 |
+
'NG' => 'Nigeria',
|
128 |
+
'BF' => 'Burkina Faso',
|
129 |
+
'TG' => 'Togo',
|
130 |
+
'GW' => 'Guinea-Bissau',
|
131 |
+
'MR' => 'Mauritania',
|
132 |
+
'BJ' => 'Benin',
|
133 |
+
'GA' => 'Gabon',
|
134 |
+
'SL' => 'Sierra Leone',
|
135 |
+
'ST' => 'São Tomé and Príncipe',
|
136 |
+
'GI' => 'Gibraltar',
|
137 |
+
'GM' => 'Gambia',
|
138 |
+
'GN' => 'Guinea',
|
139 |
+
'TD' => 'Chad',
|
140 |
+
'NE' => 'Niger',
|
141 |
+
'ML' => 'Mali',
|
142 |
+
'EH' => 'Western Sahara',
|
143 |
+
'TN' => 'Tunisia',
|
144 |
+
'ES' => 'Spain',
|
145 |
+
'MA' => 'Morocco',
|
146 |
+
'MT' => 'Malta',
|
147 |
+
'DZ' => 'Algeria',
|
148 |
+
'FO' => 'Faroe Islands',
|
149 |
+
'DK' => 'Denmark',
|
150 |
+
'IS' => 'Iceland',
|
151 |
+
'GB' => 'United Kingdom',
|
152 |
+
'CH' => 'Switzerland',
|
153 |
+
'SE' => 'Sweden',
|
154 |
+
'NL' => 'Netherlands',
|
155 |
+
'AT' => 'Austria',
|
156 |
+
'BE' => 'Belgium',
|
157 |
+
'DE' => 'Germany',
|
158 |
+
'LU' => 'Luxembourg',
|
159 |
+
'IE' => 'Ireland',
|
160 |
+
'MC' => 'Monaco',
|
161 |
+
'FR' => 'France',
|
162 |
+
'AD' => 'Andorra',
|
163 |
+
'LI' => 'Liechtenstein',
|
164 |
+
'JE' => 'Jersey',
|
165 |
+
'IM' => 'Isle of Man',
|
166 |
+
'GG' => 'Guernsey',
|
167 |
+
'SK' => 'Slovakia',
|
168 |
+
'CZ' => 'Czechia',
|
169 |
+
'NO' => 'Norway',
|
170 |
+
'VA' => 'Vatican City',
|
171 |
+
'SM' => 'San Marino',
|
172 |
+
'IT' => 'Italy',
|
173 |
+
'SI' => 'Slovenia',
|
174 |
+
'ME' => 'Montenegro',
|
175 |
+
'HR' => 'Croatia',
|
176 |
+
'BA' => 'Bosnia and Herzegovina',
|
177 |
+
'AO' => 'Angola',
|
178 |
+
'NA' => 'Namibia',
|
179 |
+
'SH' => 'Saint Helena',
|
180 |
+
'BV' => 'Bouvet Island',
|
181 |
+
'BB' => 'Barbados',
|
182 |
+
'CV' => 'Cabo Verde',
|
183 |
+
'GY' => 'Guyana',
|
184 |
+
'GF' => 'French Guiana',
|
185 |
+
'SR' => 'Suriname',
|
186 |
+
'PM' => 'Saint Pierre and Miquelon',
|
187 |
+
'GL' => 'Greenland',
|
188 |
+
'PY' => 'Paraguay',
|
189 |
+
'UY' => 'Uruguay',
|
190 |
+
'BR' => 'Brazil',
|
191 |
+
'FK' => 'Falkland Islands',
|
192 |
+
'GS' => 'South Georgia and the South Sandwich Islands',
|
193 |
+
'JM' => 'Jamaica',
|
194 |
+
'DO' => 'Dominican Republic',
|
195 |
+
'CU' => 'Cuba',
|
196 |
+
'MQ' => 'Martinique',
|
197 |
+
'BS' => 'Bahamas',
|
198 |
+
'BM' => 'Bermuda',
|
199 |
+
'AI' => 'Anguilla',
|
200 |
+
'TT' => 'Trinidad and Tobago',
|
201 |
+
'KN' => 'St Kitts and Nevis',
|
202 |
+
'DM' => 'Dominica',
|
203 |
+
'AG' => 'Antigua and Barbuda',
|
204 |
+
'LC' => 'Saint Lucia',
|
205 |
+
'TC' => 'Turks and Caicos Islands',
|
206 |
+
'AW' => 'Aruba',
|
207 |
+
'VG' => 'British Virgin Islands',
|
208 |
+
'VC' => 'Saint Vincent and the Grenadines',
|
209 |
+
'MS' => 'Montserrat',
|
210 |
+
'MF' => 'Saint Martin',
|
211 |
+
'BL' => 'Saint Barthélemy',
|
212 |
+
'GP' => 'Guadeloupe',
|
213 |
+
'GD' => 'Grenada',
|
214 |
+
'KY' => 'Cayman Islands',
|
215 |
+
'BZ' => 'Belize',
|
216 |
+
'SV' => 'El Salvador',
|
217 |
+
'GT' => 'Guatemala',
|
218 |
+
'HN' => 'Honduras',
|
219 |
+
'NI' => 'Nicaragua',
|
220 |
+
'CR' => 'Costa Rica',
|
221 |
+
'VE' => 'Venezuela',
|
222 |
+
'EC' => 'Ecuador',
|
223 |
+
'CO' => 'Colombia',
|
224 |
+
'PA' => 'Panama',
|
225 |
+
'HT' => 'Haiti',
|
226 |
+
'AR' => 'Argentina',
|
227 |
+
'CL' => 'Chile',
|
228 |
+
'BO' => 'Bolivia',
|
229 |
+
'PE' => 'Peru',
|
230 |
+
'MX' => 'Mexico',
|
231 |
+
'PF' => 'French Polynesia',
|
232 |
+
'PN' => 'Pitcairn Islands',
|
233 |
+
'KI' => 'Kiribati',
|
234 |
+
'TK' => 'Tokelau',
|
235 |
+
'TO' => 'Tonga',
|
236 |
+
'WF' => 'Wallis and Futuna',
|
237 |
+
'WS' => 'Samoa',
|
238 |
+
'NU' => 'Niue',
|
239 |
+
'MP' => 'Northern Mariana Islands',
|
240 |
+
'GU' => 'Guam',
|
241 |
+
'PR' => 'Puerto Rico',
|
242 |
+
'VI' => 'U.S. Virgin Islands',
|
243 |
+
'UM' => 'U.S. Minor Outlying Islands',
|
244 |
+
'AS' => 'American Samoa',
|
245 |
+
'CA' => 'Canada',
|
246 |
+
'US' => 'United States',
|
247 |
+
'PS' => 'Palestine',
|
248 |
+
'RS' => 'Serbia',
|
249 |
+
'AQ' => 'Antarctica',
|
250 |
+
'SX' => 'Sint Maarten',
|
251 |
+
'CW' => 'Curaçao',
|
252 |
+
'BQ' => 'Bonaire, Sint Eustatius, and Saba',
|
253 |
+
'SS' => 'South Sudan',
|
254 |
+
);
|
views/options-page.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
if( !defined( 'ABSPATH' ) ) exit();
|
4 |
|
5 |
-
$active_tab = "
|
6 |
$active_app = $this->get_option( 'active_app' );
|
7 |
if( !empty($_GET["tab"]) && in_array( $_GET["tab"], array( 'logs-local', 'logs-custom', 'settings', 'debug' ) ) ) {
|
8 |
|
@@ -29,6 +29,7 @@ if( !empty($_GET["tab"]) && in_array( $_GET["tab"], array( 'logs-local', 'logs-c
|
|
29 |
<h2><?php echo __( 'Limit Login Attempts Reloaded', 'limit-login-attempts-reloaded' ); ?></h2>
|
30 |
|
31 |
<h2 class="nav-tab-wrapper">
|
|
|
32 |
<a href="<?php echo $this->get_options_page_uri('settings'); ?>" class="nav-tab <?php if($active_tab == 'settings'){echo 'nav-tab-active';} ?> "><?php _e('Settings', 'limit-login-attempts-reloaded'); ?></a>
|
33 |
<?php if( $active_app === 'custom' ) : ?>
|
34 |
<a href="<?php echo $this->get_options_page_uri('logs-custom'); ?>" class="nav-tab <?php if($active_tab == 'logs-custom'){echo 'nav-tab-active';} ?> "><?php _e('Logs', 'limit-login-attempts-reloaded'); ?></a>
|
2 |
|
3 |
if( !defined( 'ABSPATH' ) ) exit();
|
4 |
|
5 |
+
$active_tab = "dashboard";
|
6 |
$active_app = $this->get_option( 'active_app' );
|
7 |
if( !empty($_GET["tab"]) && in_array( $_GET["tab"], array( 'logs-local', 'logs-custom', 'settings', 'debug' ) ) ) {
|
8 |
|
29 |
<h2><?php echo __( 'Limit Login Attempts Reloaded', 'limit-login-attempts-reloaded' ); ?></h2>
|
30 |
|
31 |
<h2 class="nav-tab-wrapper">
|
32 |
+
<a href="<?php echo $this->get_options_page_uri('dashboard'); ?>" class="nav-tab <?php if($active_tab == 'dashboard'){echo 'nav-tab-active';} ?> "><?php _e('Dashboard', 'limit-login-attempts-reloaded'); ?></a>
|
33 |
<a href="<?php echo $this->get_options_page_uri('settings'); ?>" class="nav-tab <?php if($active_tab == 'settings'){echo 'nav-tab-active';} ?> "><?php _e('Settings', 'limit-login-attempts-reloaded'); ?></a>
|
34 |
<?php if( $active_app === 'custom' ) : ?>
|
35 |
<a href="<?php echo $this->get_options_page_uri('logs-custom'); ?>" class="nav-tab <?php if($active_tab == 'logs-custom'){echo 'nav-tab-active';} ?> "><?php _e('Logs', 'limit-login-attempts-reloaded'); ?></a>
|
views/tab-dashboard.php
ADDED
@@ -0,0 +1,447 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( !defined( 'ABSPATH' ) ) exit();
|
4 |
+
|
5 |
+
$active_app = $this->get_option( 'active_app' );
|
6 |
+
$retries = $this->get_option( 'retries' );
|
7 |
+
$valid_duration = $this->get_option( 'valid_duration' );
|
8 |
+
$valid_duration /= 3600;
|
9 |
+
|
10 |
+
$retries_count = 0;
|
11 |
+
if($retries) {
|
12 |
+
foreach ($retries as $ip => $retry) {
|
13 |
+
$retries_count += (int)$retry;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
$retries_chart_title = '';
|
18 |
+
$retries_chart_desc = '';
|
19 |
+
$retries_chart_color = '';
|
20 |
+
$retries_chart_show_actions = false;
|
21 |
+
|
22 |
+
$api_stats = false;
|
23 |
+
$app_attacks = 0;
|
24 |
+
if( $active_app === 'local' ) {
|
25 |
+
|
26 |
+
if( $retries_count === 0 ) {
|
27 |
+
|
28 |
+
$retries_chart_title = sprintf( __( 'Hooray! Zero suspicious login attempts in the last %d hr', 'limit-login-attempts-reloaded' ), $valid_duration );
|
29 |
+
$retries_chart_color = '#66CC66';
|
30 |
+
}
|
31 |
+
else if ( $retries_count < 100 ) {
|
32 |
+
|
33 |
+
$retries_chart_title = sprintf( _n( '%d suspicious login attempt ', '%d suspicious login attempts ', $retries_count, 'limit-login-attempts-reloaded' ), $retries_count );
|
34 |
+
$retries_chart_title .= sprintf( __( 'in the last %d hr', 'limit-login-attempts-reloaded' ), $valid_duration );
|
35 |
+
$retries_chart_desc = __( 'Your site might have been discovered by hackers.', 'limit-login-attempts-reloaded' );
|
36 |
+
$retries_chart_color = '#FFCC66';
|
37 |
+
} else {
|
38 |
+
|
39 |
+
$retries_chart_title = sprintf( __( 'Warning: More than 100 suspicious login attempts in the last %d hr', 'limit-login-attempts-reloaded' ), $valid_duration );
|
40 |
+
$retries_chart_desc = __( 'Your site is likely under a brute-force attack.', 'limit-login-attempts-reloaded' );
|
41 |
+
$retries_chart_color = '#FF6633';
|
42 |
+
$retries_chart_show_actions = true;
|
43 |
+
}
|
44 |
+
|
45 |
+
} else {
|
46 |
+
|
47 |
+
$api_stats = $this->app->stats();
|
48 |
+
|
49 |
+
if( $api_stats && !empty( $api_stats['attempts']['count'] )) {
|
50 |
+
|
51 |
+
$app_attacks = (int) end( $api_stats['attempts']['count'] );
|
52 |
+
}
|
53 |
+
|
54 |
+
$retries_count = 0;
|
55 |
+
|
56 |
+
$retries_chart_title = __( 'Zero local suspicious login attempts in the last 24 hr', 'limit-login-attempts-reloaded' );
|
57 |
+
$retries_chart_desc = ($app_attacks)
|
58 |
+
? sprintf( __( 'All %d excessive login attempts have been neutralized in the cloud', 'limit-login-attempts-reloaded' ), $app_attacks )
|
59 |
+
: '';
|
60 |
+
$retries_chart_color = '#66CC66';
|
61 |
+
}
|
62 |
+
|
63 |
+
?>
|
64 |
+
|
65 |
+
<div id="llar-dashboard-page">
|
66 |
+
<div class="dashboard-header">
|
67 |
+
<h1><?php _e( 'Limit Login Attempts Reloaded Dashboard', 'limit-login-attempts-reloaded' ); ?></h1>
|
68 |
+
</div>
|
69 |
+
<div class="dashboard-section-1 <?php echo esc_attr( $active_app ); ?>">
|
70 |
+
<div class="info-box-1">
|
71 |
+
<div class="section-title"><?php echo ($active_app === 'local')
|
72 |
+
? __( 'Suspicious Login Activity', 'limit-login-attempts-reloaded' ) .
|
73 |
+
' (<span class="llar-tooltip" data-text="' . esc_attr__( '"Local" means the server that hosts your website.', 'limit-login-attempts-reloaded' ) . '">' .
|
74 |
+
__( 'Local', 'limit-login-attempts-reloaded' ) . '</span>)'
|
75 |
+
: __( 'Suspicious Login Attempts Prevented', 'limit-login-attempts-reloaded' ); ?></div>
|
76 |
+
<div class="section-content">
|
77 |
+
<div class="chart">
|
78 |
+
<canvas id="llar-attack-velocity-chart"></canvas>
|
79 |
+
<span class="llar-retries-count"><?php echo esc_html( $retries_count ); ?></span>
|
80 |
+
</div>
|
81 |
+
<script type="text/javascript">
|
82 |
+
(function(){
|
83 |
+
|
84 |
+
var ctx = document.getElementById('llar-attack-velocity-chart').getContext('2d');
|
85 |
+
var llar_retries_chart = new Chart(ctx, {
|
86 |
+
type: 'doughnut',
|
87 |
+
data: {
|
88 |
+
// labels: ['Success', 'Warning', 'Warning', 'Fail'],
|
89 |
+
datasets: [{
|
90 |
+
data: [1],
|
91 |
+
value: <?php echo esc_js( $retries_count ); ?>,
|
92 |
+
backgroundColor: ['<?php echo esc_js( $retries_chart_color ); ?>'],
|
93 |
+
borderWidth: [0]
|
94 |
+
}]
|
95 |
+
},
|
96 |
+
options: {
|
97 |
+
responsive: true,
|
98 |
+
cutoutPercentage: 70,
|
99 |
+
title: {
|
100 |
+
display: false,
|
101 |
+
// text: 'Local Attack Velocity'
|
102 |
+
},
|
103 |
+
tooltips: {
|
104 |
+
enabled: false
|
105 |
+
},
|
106 |
+
layout: {
|
107 |
+
padding: {
|
108 |
+
// bottom: 40
|
109 |
+
}
|
110 |
+
},
|
111 |
+
// needle: {
|
112 |
+
// // Needle circle radius as the percentage of the chart area width
|
113 |
+
// radiusPercentage: 2,
|
114 |
+
// // Needle width as the percentage of the chart area width
|
115 |
+
// widthPercentage: 3.2,
|
116 |
+
// // Needle length as the percentage of the interval between inner radius (0%) and outer radius (100%) of the arc
|
117 |
+
// lengthPercentage: 40,
|
118 |
+
// // The color of the needle
|
119 |
+
// color: 'rgba(0, 0, 0, 1)'
|
120 |
+
// },
|
121 |
+
valueLabel: {
|
122 |
+
display: true,
|
123 |
+
fontSize: 25,
|
124 |
+
color: '#3e76c1',
|
125 |
+
backgroundColor: 'rgba(0,0,0,0)',
|
126 |
+
bottomMarginPercentage: -6
|
127 |
+
},
|
128 |
+
}
|
129 |
+
});
|
130 |
+
|
131 |
+
})();
|
132 |
+
</script>
|
133 |
+
<div class="title"><?php echo esc_html( $retries_chart_title ); ?></div>
|
134 |
+
<div class="desc"><?php echo $retries_chart_desc; ?></div>
|
135 |
+
<?php if( $retries_chart_show_actions ) : ?>
|
136 |
+
<div class="actions">
|
137 |
+
<ol>
|
138 |
+
<li><?php _e( 'Change your password to something more secure.', 'limit-login-attempts-reloaded' ); ?></li>
|
139 |
+
<li><?php _e( 'Make sure WordPress and all your plugins are updated.', 'limit-login-attempts-reloaded' ); ?></li>
|
140 |
+
<li><?php echo sprintf( __( '<a href="%s" target="_blank">Update to Premium</a> Limit Login Attempts Reloaded.', 'limit-login-attempts-reloaded' ), 'https://www.limitloginattempts.com/features/?from=plugin-dashboard-status' ); ?></li>
|
141 |
+
</ol>
|
142 |
+
</div>
|
143 |
+
<?php endif; ?>
|
144 |
+
</div>
|
145 |
+
</div>
|
146 |
+
<div class="info-box-2">
|
147 |
+
<div class="section-content">
|
148 |
+
<?php
|
149 |
+
$chart2_label = '';
|
150 |
+
$chart2_labels = array();
|
151 |
+
$chart2_datasets = array();
|
152 |
+
|
153 |
+
if( $active_app === 'custom' && $api_stats ) {
|
154 |
+
|
155 |
+
$stats_dates = array();
|
156 |
+
$stats_values = array();
|
157 |
+
$date_format = trim( get_option( 'date_format' ), ' yY,._:;-/\\' );
|
158 |
+
$date_format = str_replace( 'F', 'M', $date_format );
|
159 |
+
|
160 |
+
foreach ( $api_stats['attempts']['at'] as $timest ) {
|
161 |
+
|
162 |
+
$stats_dates[] = get_date_from_gmt( date( 'Y-m-d H:i:s', $timest ), $date_format );
|
163 |
+
}
|
164 |
+
|
165 |
+
$chart2_label = __( 'Requests', 'limit-login-attempts-reloaded' );
|
166 |
+
$chart2_labels = $stats_dates;
|
167 |
+
|
168 |
+
$chart2_datasets[] = array(
|
169 |
+
'label' => __( 'Suspicious Login Attempts', 'limit-login-attempts-reloaded' ),
|
170 |
+
'data' => $api_stats['attempts']['count'],
|
171 |
+
'backgroundColor' => 'rgb(54, 162, 235)',
|
172 |
+
'borderColor' => 'rgb(54, 162, 235)',
|
173 |
+
'fill' => false,
|
174 |
+
);
|
175 |
+
|
176 |
+
// $chart2_datasets[] = array(
|
177 |
+
// 'label' => __( 'API Requests', 'limit-login-attempts-reloaded' ),
|
178 |
+
// 'data' => $api_stats['requests']['count'],
|
179 |
+
// 'backgroundColor' => 'rgba(201, 203, 207, 0.4)',
|
180 |
+
// 'borderColor' => 'rgb(201, 203, 207)',
|
181 |
+
// 'fill' => '-1',
|
182 |
+
// );
|
183 |
+
|
184 |
+
} else {
|
185 |
+
|
186 |
+
$daterange = new DatePeriod(
|
187 |
+
(new DateTime())->modify('-6 day'),
|
188 |
+
new DateInterval('P1D'),
|
189 |
+
(new DateTime())->modify('+1 day')
|
190 |
+
);
|
191 |
+
|
192 |
+
$retries_stats = $this->get_option( 'retries_stats' );
|
193 |
+
|
194 |
+
$date_format = trim( get_option( 'date_format' ), ' yY,._:;-/\\' );
|
195 |
+
$date_format = str_replace( 'F', 'M', $date_format );
|
196 |
+
|
197 |
+
$chart2_data = array();
|
198 |
+
foreach ($daterange as $date) {
|
199 |
+
|
200 |
+
$chart2_labels[] = $date->format( $date_format );
|
201 |
+
$chart2_data[] = (!empty($retries_stats[$date->format("Y-m-d")])) ? $retries_stats[$date->format("Y-m-d")] : 0;
|
202 |
+
}
|
203 |
+
|
204 |
+
$chart2_datasets[] = array(
|
205 |
+
'label' => __( 'Suspicious Login Attempts By Day', 'limit-login-attempts-reloaded' ),
|
206 |
+
'data' => $chart2_data,
|
207 |
+
'backgroundColor' => 'rgb(54, 162, 235)',
|
208 |
+
'borderColor' => 'rgb(54, 162, 235)',
|
209 |
+
'fill' => false,
|
210 |
+
);
|
211 |
+
}
|
212 |
+
|
213 |
+
?>
|
214 |
+
|
215 |
+
<div class="llar-chart-wrap">
|
216 |
+
<canvas id="llar-api-requests-chart" style=""></canvas>
|
217 |
+
</div>
|
218 |
+
|
219 |
+
<script type="text/javascript">
|
220 |
+
(function(){
|
221 |
+
|
222 |
+
var ctx = document.getElementById('llar-api-requests-chart').getContext('2d');
|
223 |
+
var llar_stat_chart = new Chart(ctx, {
|
224 |
+
type: 'line',
|
225 |
+
data: {
|
226 |
+
labels: <?php echo json_encode( $chart2_labels ); ?>,
|
227 |
+
datasets: <?php echo json_encode( $chart2_datasets ); ?>
|
228 |
+
},
|
229 |
+
options: {
|
230 |
+
responsive: true,
|
231 |
+
maintainAspectRatio: false,
|
232 |
+
tooltips: {
|
233 |
+
mode: 'index',
|
234 |
+
intersect: false,
|
235 |
+
},
|
236 |
+
hover: {
|
237 |
+
mode: 'nearest',
|
238 |
+
intersect: true
|
239 |
+
},
|
240 |
+
scales: {
|
241 |
+
xAxes: [{
|
242 |
+
display: true,
|
243 |
+
scaleLabel: {
|
244 |
+
display: true,
|
245 |
+
labelString: '<?php echo esc_js( __( 'Date', 'limit-login-attempts-reloaded' ) ); ?>'
|
246 |
+
}
|
247 |
+
}],
|
248 |
+
yAxes: [{
|
249 |
+
display: true,
|
250 |
+
scaleLabel: {
|
251 |
+
display: false
|
252 |
+
},
|
253 |
+
ticks: {
|
254 |
+
beginAtZero: true,
|
255 |
+
userCallback: function(label, index, labels) {
|
256 |
+
if (Math.floor(label) === label) {
|
257 |
+
return label;
|
258 |
+
}
|
259 |
+
},
|
260 |
+
}
|
261 |
+
}]
|
262 |
+
}
|
263 |
+
}
|
264 |
+
});
|
265 |
+
|
266 |
+
})();
|
267 |
+
</script>
|
268 |
+
|
269 |
+
</div>
|
270 |
+
</div>
|
271 |
+
<?php if( $active_app === 'local' ) : ?>
|
272 |
+
<div class="info-box-3">
|
273 |
+
<div class="section-content">
|
274 |
+
<div class="title"><?php _e( 'Premium Protection Disabled', 'limit-login-attempts-reloaded' ); ?></div>
|
275 |
+
<div class="desc"><?php _e( 'As a free user, your local server is absorbing the traffic brought on by brute force attacks, potentially slowing down your website. Upgrade to Premium today to outsource these attacks through our cloud app, and slow down future attacks with advanced throttling.', 'limit-login-attempts-reloaded' ); ?></div>
|
276 |
+
<div class="actions">
|
277 |
+
<a href="https://www.limitloginattempts.com/features/?from=plugin-dashboard-cta" target="_blank" class="button button-primary"><?php _e( 'Upgrade to Premium', 'limit-login-attempts-reloaded' ); ?></a><br>
|
278 |
+
</div>
|
279 |
+
</div>
|
280 |
+
</div>
|
281 |
+
<?php endif; ?>
|
282 |
+
</div>
|
283 |
+
<div class="dashboard-section-2" style="display:none;">
|
284 |
+
<div class="info-box-1">
|
285 |
+
<div class="section-title"><?php _e( 'Notifications', 'limit-login-attempts-reloaded' ); ?></div>
|
286 |
+
<ul class="notifications-list">
|
287 |
+
<li><a href="#">12 issues found in most recent scan</a></li>
|
288 |
+
<li><a href="#">Updates are available for WordPress (v5.6) and 10 plugins</a></li>
|
289 |
+
</ul>
|
290 |
+
</div>
|
291 |
+
<div class="info-box-2">
|
292 |
+
<div class="info-box-icon">
|
293 |
+
<span class="dashicons dashicons-rest-api"></span>
|
294 |
+
</div>
|
295 |
+
<div class="info-box-content">
|
296 |
+
<div class="title"><?php _e( 'Multiply Your Protection By Adding More Domains', 'limit-login-attempts-reloaded' ); ?></div>
|
297 |
+
<div class="desc"><?php _e( 'When you upgrade to premium, you can synchronize your IP safelist and blacklist between multiple sites. This is a great way to improve your network performance and slow down future attacks.', 'limit-login-attempts-reloaded' ); ?></div>
|
298 |
+
<div class="actions">
|
299 |
+
<a href="#"><?php _e( 'Learn More', 'limit-login-attempts-reloaded' ); ?></a>
|
300 |
+
<a href="#"><?php _e( 'Connect This Site', 'limit-login-attempts-reloaded' ); ?></a>
|
301 |
+
</div>
|
302 |
+
</div>
|
303 |
+
</div>
|
304 |
+
</div>
|
305 |
+
<div class="dashboard-section-3">
|
306 |
+
<div class="info-box-1">
|
307 |
+
<div class="info-box-icon">
|
308 |
+
<span class="dashicons dashicons-admin-tools"></span>
|
309 |
+
</div>
|
310 |
+
<div class="info-box-content">
|
311 |
+
<div class="title"><a href="<?php echo $this->get_options_page_uri('logs-'.$active_app); ?>"><?php _e( 'Tools', 'limit-login-attempts-reloaded' ); ?></a></div>
|
312 |
+
<div class="desc"><?php _e( 'View lockouts logs, block or whitelist usernames or IPs, and more.', 'limit-login-attempts-reloaded' ); ?></div>
|
313 |
+
</div>
|
314 |
+
</div>
|
315 |
+
<div class="info-box-1">
|
316 |
+
<div class="info-box-icon">
|
317 |
+
<span class="dashicons dashicons-sos"></span>
|
318 |
+
</div>
|
319 |
+
<div class="info-box-content">
|
320 |
+
<div class="title"><a href="https://www.limitloginattempts.com/resources/?from=plugin-dashboard" target="_blank"><?php _e( 'Help', 'limit-login-attempts-reloaded' ); ?></a></div>
|
321 |
+
<div class="desc"><?php _e( 'Find the documentation and help you need.', 'limit-login-attempts-reloaded' ); ?></div>
|
322 |
+
</div>
|
323 |
+
</div>
|
324 |
+
<div class="info-box-1">
|
325 |
+
<div class="info-box-icon">
|
326 |
+
<span class="dashicons dashicons-admin-generic"></span>
|
327 |
+
</div>
|
328 |
+
<div class="info-box-content">
|
329 |
+
<div class="title"><a href="<?php echo $this->get_options_page_uri('settings'); ?>"><?php _e( 'Global Options', 'limit-login-attempts-reloaded' ); ?></a></div>
|
330 |
+
<div class="desc"><?php _e( 'Many options such as notifications, alerts, premium status, and more.', 'limit-login-attempts-reloaded' ); ?></div>
|
331 |
+
</div>
|
332 |
+
</div>
|
333 |
+
</div>
|
334 |
+
<?php if( $stats_global = LLAR_App::stats_global() ) : ?>
|
335 |
+
<div class="dashboard-section-4">
|
336 |
+
<?php
|
337 |
+
$stats_global_dates = array();
|
338 |
+
$date_format = trim( get_option( 'date_format' ), ' yY,._:;-/\\' );
|
339 |
+
$date_format = str_replace( 'F', 'M', $date_format );
|
340 |
+
|
341 |
+
foreach ( $stats_global['attempts']['day']['at'] as $timest ) {
|
342 |
+
|
343 |
+
$stats_global_dates[] = get_date_from_gmt( date( 'Y-m-d H:i:s', $timest ), $date_format );
|
344 |
+
}
|
345 |
+
|
346 |
+
$countries_list = require LLA_PLUGIN_DIR . '/resources/countries.php';
|
347 |
+
?>
|
348 |
+
<div class="info-box-1">
|
349 |
+
<div class="section-title">
|
350 |
+
<span><?php _e( 'Failed Login Attempts By Country', 'limit-login-attempts-reloaded' ); ?></span>
|
351 |
+
<span class="section-title-info"><?php _e( 'Global Network (Premium Users)', 'limit-login-attempts-reloaded' ); ?></span>
|
352 |
+
</div>
|
353 |
+
<div class="section-content">
|
354 |
+
<table class="lockouts-by-country-table">
|
355 |
+
<tr>
|
356 |
+
<th><?php _e( 'Country', 'limit-login-attempts-reloaded' ); ?></th>
|
357 |
+
<th><?php _e( 'Count', 'limit-login-attempts-reloaded' ); ?></th>
|
358 |
+
</tr>
|
359 |
+
<?php foreach( $stats_global['countries'] as $country_data ) :
|
360 |
+
|
361 |
+
$country_code = ( array_key_exists( $country_data['code'], $countries_list ) ) ? $country_data['code'] : 'ZZ';
|
362 |
+
$country_name = apply_filters( 'llar_country_name', $countries_list[$country_code], $country_code );
|
363 |
+
?>
|
364 |
+
<tr>
|
365 |
+
<td>
|
366 |
+
<?php if( $country_code !== 'ZZ' ) : ?>
|
367 |
+
<img class="flag-icon" src="<?php echo LLA_PLUGIN_URL; ?>/assets/img/flags/<?php echo esc_attr( $country_data['code'] ); ?>.png">
|
368 |
+
<?php endif; ?>
|
369 |
+
<?php echo esc_html( $country_name ); ?></td>
|
370 |
+
<td><?php echo esc_html( $country_data['attempts'] ); ?></td>
|
371 |
+
</tr>
|
372 |
+
<?php endforeach; ?>
|
373 |
+
</table>
|
374 |
+
<p class="countries-table-info"><?php _e( 'last 24 hr', 'limit-login-attempts-reloaded' ); ?></p>
|
375 |
+
</div>
|
376 |
+
</div>
|
377 |
+
|
378 |
+
<div class="info-box-2">
|
379 |
+
<div class="section-title">
|
380 |
+
<span><?php _e( 'Total Failed Login Attempts', 'limit-login-attempts-reloaded' ); ?></span>
|
381 |
+
<span class="section-title-info"><?php _e( 'Global Network (Premium Users)', 'limit-login-attempts-reloaded' ); ?></span>
|
382 |
+
</div>
|
383 |
+
<div class="section-content">
|
384 |
+
<div class="llar-chart-wrap">
|
385 |
+
<canvas id="llar-total-attacks-blocked-chart" style=""></canvas>
|
386 |
+
</div>
|
387 |
+
<script type="text/javascript">
|
388 |
+
(function(){
|
389 |
+
|
390 |
+
var ctx = document.getElementById('llar-total-attacks-blocked-chart').getContext('2d');
|
391 |
+
var llar_total_attacks_blocked_chart = new Chart(ctx, {
|
392 |
+
type: 'line',
|
393 |
+
data: {
|
394 |
+
labels: <?php echo json_encode( $stats_global_dates ); ?>,
|
395 |
+
datasets: [{
|
396 |
+
label: '<?php echo esc_js( __( 'Total Attempts', 'limit-login-attempts-reloaded' ) ); ?>',
|
397 |
+
data: <?php echo json_encode( $stats_global['attempts']['day']['count'] ); ?>,
|
398 |
+
backgroundColor: 'rgb(255, 159, 64)',
|
399 |
+
borderColor: 'rgb(255, 159, 64)',
|
400 |
+
fill: false
|
401 |
+
}]
|
402 |
+
},
|
403 |
+
options: {
|
404 |
+
responsive: true,
|
405 |
+
maintainAspectRatio: false,
|
406 |
+
tooltips: {
|
407 |
+
mode: 'index',
|
408 |
+
intersect: false,
|
409 |
+
},
|
410 |
+
hover: {
|
411 |
+
mode: 'nearest',
|
412 |
+
intersect: true
|
413 |
+
},
|
414 |
+
scales: {
|
415 |
+
xAxes: [{
|
416 |
+
display: true,
|
417 |
+
scaleLabel: {
|
418 |
+
display: true,
|
419 |
+
labelString: '<?php echo esc_js( __( 'Date', 'limit-login-attempts-reloaded' ) ); ?>'
|
420 |
+
}
|
421 |
+
}],
|
422 |
+
yAxes: [{
|
423 |
+
display: true,
|
424 |
+
scaleLabel: {
|
425 |
+
display: false,
|
426 |
+
// labelString: '<?php //echo esc_js( __( 'Date', 'limit-login-attempts-reloaded' ) ); ?>//'
|
427 |
+
},
|
428 |
+
ticks: {
|
429 |
+
beginAtZero: true,
|
430 |
+
userCallback: function(label, index, labels) {
|
431 |
+
if (Math.floor(label) === label) {
|
432 |
+
return label;
|
433 |
+
}
|
434 |
+
},
|
435 |
+
}
|
436 |
+
}]
|
437 |
+
}
|
438 |
+
}
|
439 |
+
});
|
440 |
+
|
441 |
+
})();
|
442 |
+
</script>
|
443 |
+
</div>
|
444 |
+
</div>
|
445 |
+
</div>
|
446 |
+
<?php endif; ?>
|
447 |
+
</div>
|
views/tab-logs-custom.php
CHANGED
@@ -9,76 +9,6 @@ if( !defined( 'ABSPATH' ) ) exit();
|
|
9 |
|
10 |
<div class="limit-login-app-dashboard">
|
11 |
|
12 |
-
<h3><?php _e( 'Statistics', 'limit-login-attempts-reloaded' ); ?></h3>
|
13 |
-
|
14 |
-
<?php
|
15 |
-
if( $api_stats = $this->app->stats() ) {
|
16 |
-
|
17 |
-
$stats_dates = array();
|
18 |
-
$stats_values = array();
|
19 |
-
$date_format = trim( get_option( 'date_format' ), ' yY,._:;-/\\' );
|
20 |
-
$date_format = str_replace( 'F', 'M', $date_format );
|
21 |
-
|
22 |
-
foreach ( $api_stats['requests']['at'] as $timest ) {
|
23 |
-
|
24 |
-
$stats_dates[] = get_date_from_gmt( date( 'Y-m-d H:i:s', $timest ), $date_format );
|
25 |
-
} ?>
|
26 |
-
|
27 |
-
<div class="llar-chart-wrap">
|
28 |
-
<canvas id="llar-api-requests-chart" style="width: 400px; height: auto;"></canvas>
|
29 |
-
</div>
|
30 |
-
<script type="text/javascript">
|
31 |
-
(function(){
|
32 |
-
|
33 |
-
var ctx = document.getElementById('llar-api-requests-chart').getContext('2d');
|
34 |
-
var llar_stat_chart = new Chart(ctx, {
|
35 |
-
type: 'line',
|
36 |
-
data: {
|
37 |
-
labels: <?php echo json_encode( $stats_dates ); ?>,
|
38 |
-
datasets: [{
|
39 |
-
label: '<?php echo esc_js( __( 'Requests', 'limit-login-attempts-reloaded' ) ); ?>',
|
40 |
-
data: <?php echo json_encode( $api_stats['requests']['count'] ); ?>,
|
41 |
-
backgroundColor: 'rgb(54, 162, 235)',
|
42 |
-
borderColor: 'rgb(54, 162, 235)',
|
43 |
-
fill: false
|
44 |
-
}]
|
45 |
-
},
|
46 |
-
options: {
|
47 |
-
responsive: true,
|
48 |
-
tooltips: {
|
49 |
-
mode: 'index',
|
50 |
-
intersect: false,
|
51 |
-
},
|
52 |
-
hover: {
|
53 |
-
mode: 'nearest',
|
54 |
-
intersect: true
|
55 |
-
},
|
56 |
-
scales: {
|
57 |
-
xAxes: [{
|
58 |
-
display: true,
|
59 |
-
scaleLabel: {
|
60 |
-
display: true,
|
61 |
-
labelString: '<?php echo esc_js( __( 'Date', 'limit-login-attempts-reloaded' ) ); ?>'
|
62 |
-
}
|
63 |
-
}],
|
64 |
-
yAxes: [{
|
65 |
-
display: true,
|
66 |
-
scaleLabel: {
|
67 |
-
display: true,
|
68 |
-
labelString: '<?php echo esc_js( __( 'API Requests', 'limit-login-attempts-reloaded' ) ); ?>'
|
69 |
-
},
|
70 |
-
ticks: {
|
71 |
-
beginAtZero: true
|
72 |
-
}
|
73 |
-
}]
|
74 |
-
}
|
75 |
-
}
|
76 |
-
});
|
77 |
-
|
78 |
-
})();
|
79 |
-
</script>
|
80 |
-
<?php } ?>
|
81 |
-
|
82 |
<h3><?php _e( 'Active Lockouts', 'limit-login-attempts-reloaded' ); ?></h3>
|
83 |
|
84 |
<div class="llar-app-lockouts-pagination">
|
9 |
|
10 |
<div class="limit-login-app-dashboard">
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
<h3><?php _e( 'Active Lockouts', 'limit-login-attempts-reloaded' ); ?></h3>
|
13 |
|
14 |
<div class="llar-app-lockouts-pagination">
|
views/tab-logs-local.php
CHANGED
@@ -94,6 +94,7 @@ $black_list_usernames = ( is_array( $black_list_usernames ) && !empty( $black_li
|
|
94 |
</form>
|
95 |
<?php
|
96 |
$log = $this->get_option( 'logged' );
|
|
|
97 |
$log = LLA_Helpers::sorted_log_by_date( $log );
|
98 |
|
99 |
$lockouts = (array)$this->get_option('lockouts');
|
94 |
</form>
|
95 |
<?php
|
96 |
$log = $this->get_option( 'logged' );
|
97 |
+
|
98 |
$log = LLA_Helpers::sorted_log_by_date( $log );
|
99 |
|
100 |
$lockouts = (array)$this->get_option('lockouts');
|